릴리스 랜딩 큐 — 최신 후보의 Merge Check와 순차 병합
2026-09-15 개정(오너 지시, #1661·#1659) — 작업 세션은 PR 전 precheck를 하지 않는다(폐기, QA1 퇴역으로 실행도 불가). 큐는 종전대로 Merge Check만 하며,
--dry-run도 같은 Merge Check를 하고 push만 하지 않는다(QA1ci:full-local을 부르던 dry-run 전체 검증은 폐기 — 큐 runner 코드 정리는 #1661 잔여 PR, main 도달 뒤 유효). 코드 검사는 승격 PR의 레인(release→staging precheck, staging→main QA2)이 한다. 아래의 "사전검증·full CI·재사용" 서술은 그 개정 전 기록이다.
2026-09-10 승인 정책 (#1491, v0.17.8 대상): 작업 세션은
ci:precheck-local, 작업→release 큐는 Merge Check만 수행한다. 최종 release→staging 후보에서 full CI를 실행하고, staging→main은 동일 tree의 유효한 full 성공 기록과 현재 staging 배포·smoke 증거를 확인해 재사용한다. 명시적merge:request --dry-run은 진단용 full 실행을 유지한다. 앱 main6afe58ec에 설치됐으며 정상 큐의 실제 실행 시간과 운영 배포 성공은 아직 확인 전이다. 상세 상태는 적용 기록에서 구분한다. 아래 과거 전환 기록보다 이 절차가 우선한다.
v0.17.7 표시 이름 — #1470: 큐 진행·검증 요약에서 번호 행동 검사는 유저 실사용 시뮬레이션(
browser,e2e-browser), 화면 크기·탭 구조 검사는 화면 정합성 검사(viewport,e2e-viewport)로 부른다. GitHub Full CI에서도 같은 이름을 사용하며 유저 실사용 시뮬레이션에(조각 n/4)를 붙인다. 잡 ID·명령·증거 JSON 키·아티팩트 이름·검사 내용은 유지한다.
v0.17.7 release 병합 완료: #1464 병렬 로컬 CI 운영에 기본 4개·사용 후 종료·유휴 회수와 최종 full CI 7분 32초 통과를 기록했다. Production 반영과 trusted main의 큐 전 prune 활성화는 별도로 확인한다.
#1463 저장소 분리 이후 적용: 아래 앱 release·DB·데이터 보호 규칙은 앱 저장소에 적용한다. 과거 docs/admin 결합 빌드·같은 SHA 배포·앱 main 문서 직행·문서 문자열 검사 설명은 이관 전 기록이다. 모든 문서와 작업 기록은 dekerd/Barbelic-docs에서 관리하며, 현행 저장소 경계와 문서·관리자 독립 운영이 그 부분을 대체한다. 세션 제목은 현재 Phase/전체 Phase 규칙을 따른다. 코드 준비·원격 활성화·실제 배포 성공은 독립 운영 문서의 기록으로 구분한다.
2026-09-09 개정 (이슈 #1456·#1457·#1458, 오너 결정) — 명령·워크플로 이름이 바뀌었다. 작업 PR 통합 요청
npm run merge:request(구 landing:request), PR 전 사전 검증npm run ci:precheck-local(최신 release 합치기 → verify → 서버 변경 시 DB 단계, 브라우저 없음), 전체 검증npm run ci:full-local(릴리스 큐 runner 안에서만; 세션은--only <단계>재현만). 워크플로 표시 이름:3-Release Merge Request(release-merge-request.yml) ·GitHub Full CI(policy-contract.yml) ·1-Production Deploy/2-Staging Deploy(production-deploy.yml·staging-deploy.yml, 단계 정의는 deploy-steps.yml) ·Production smoke (manual)·Social login daily check·Daily data backup.landing:lock·db:preflight스크립트는 폐기됐다(GitHub concurrency 가 잠금, DB 검사는 사전 검증과 큐가 한다). 아래 본문의 옛 이름은 그 개정 전 기록이다.
작업 PR을 release/vX.Y.Z에 넣을 때 최신 base 확인 → 통합 후보 생성 → Merge Check → 조건부 push·원격 병합 확인을 같은 GitHub Actions 슬롯에서 처리한다. 개별 작업의 사전검증은 요청 전에 수행하고 일반 큐 요청에서 full CI를 반복하지 않는다. GitHub가 대기열을 소유하며 병합 제어는 전용 Windows self-hosted runner에서 실행한다. 정본은 릴리스 프로세스다.
Actions 화면에서 실행되지만 계산은 로컬 PC가 담당하므로 이 release job은 GitHub-hosted runner 사용 시간을 소모하지 않는다. artifact·cache 저장 공간의 과금은 별도이며, 큐는 큰 검증 artifact를 업로드하지 않는다. 비용 기준은 GitHub Actions 과금 문서를 따른다.
일반 병합과 진단 실행
2026-09-10 #1491 승인 정책은 다음과 같다. main의 workflow·제어 코드 반영 이후 시작한 요청부터 적용하며, 실제 활성화 확인은 적용 기록을 따른다.
- 슬롯을 얻은 뒤 최신 release base와 요청된 PR head를 고정하고 두 부모 merge commit 후보를 만든다.
- 일반 요청은 고정 base의 기존 이력 불변성·migration 번호 순서·위험 기준을 확인한다. full CI를 실행하지 않고 full 성공 기록을 조회·재사용·발급하지 않는다. 사전검증은 작업 세션의 책임이며 추가 증명 장부나 승인 게이트를 만들지 않는다.
- 현재 PR/head/base·차단 라벨·clean 상태·후보 commit/tree를 다시 확인한다. 예상 base일 때만 같은 후보 commit을 반영하는 조건부 push를 유지한다. 원격 SHA와 PR merged 상태까지 확인한 뒤 슬롯을 반환한다.
- (2026-09-15 개정) 최종 release→staging 후보는 GitHub Full CI의 precheck 레인을, staging→main은 QA2 레인을 실행한다. 상세 기준은 릴리스 프로세스를 따른다.
--dry-run은 진단을 위한 명시적 예외로, 슬롯 안에서 같은 Merge Check를 하고 병합하지 않는다(2026-09-15 개정 — 그 전에는 full CI를 실행했다). --workflow-ref <branch>는 dry-run에만 허용하며 일반 요청은 main을 사용한다. 부분 재현과 수동 full은 유지한다. 실제 full을 실행한 성공과 일반 release 병합의 성공을 보고서에서 구분한다. 아래 초기 설치·실측 표는 당시 full 큐의 역사 기록이며 현재 매 요청 full을 요구하는 근거로 쓰지 않는다.
적용 상태
#1463 재개 확인: #1460을 포함한 앱 main df394f77ab0efe16ad018aecf2799a2306b10731에는 3-Release Merge Request와 merge:request가 설치되어 있다. docs 부재 후보를 처리할 별도 호환 변경은 아직 미활성이다. 현재 실행기는 docs/admin 설치·빌드 성공 증거를 여전히 요구하므로 main에 개명 코드가 도달했다는 이유만으로 분리 PR의 통합이 가능하다고 판단하지 않는다. HQ가 선행 적용 경로를 결정 중이며 전환 상태를 따른다. 아래 실제 실행 표는 초기 큐 설치 당시 이력이다.
2026-09-09(KST) 실제 CI·병합까지 검증한 원격 적용 상태다.
| 항목 | 확인 상태 |
|---|---|
| Windows runner 설치·GitHub 등록 | 완료. barbelic-local-windows, runner ID 21, 등록 직후 online·대기 확인 |
| 자동 시작 | 완료. USER 로그인 시 숨김 실행; Windows 서비스는 아님 |
| release 요청 CLI·workflow·검증/병합 코드 | 적용 완료. #1433을 실제 큐로 검증하고 release/v0.17.3에 병합 |
| main의 원격 workflow 활성화·실제 요청 실행 | #1431 설치·#1434 준비 단계 보완 완료. 실제 CI·병합 실행 success |
| release 업데이트 전용 권한 | release-landing environment(main만 허용)·전용 deploy key·secret 등록 완료 |
| 보호 규칙과 거부 동작 검증 | release-queue-only(22549203), release-history(22549205) 모두 active. 동일 업데이트 제한을 적용한 임시 ref에서 일반 사용자 토큰의 실제 fast-forward가 HTTP 422로 거부되고 ref가 유지됨을 확인 |
| Vercel·Supabase 배포 연결 및 두 승격의 hosted CI 전환 | 별도 전환 코드 준비 중. 실제 활성화·배포 검증은 릴리스 프로세스의 상태 표에서 확인 |
main 설치 커밋은 f3a624c0375345bd7b35104259d706060fc69c42, 준비 단계 보완 커밋은 f4b87b4ec4f464833cb595f7bcd51ebf96b8ce4e다. 설치 PR과 보완 PR의 GitHub full CI가 각각 통과했다. release 직접 업데이트는 보호 규칙으로 제한하며, 규칙을 우회하는 사용자·관리자 권한은 추가하지 않았다.
최초 실제 요청 A는 과거 태그가 없어 CASE-039/040 두 개가 건너뛰어지자 최종 evidence 검사에서 실패했다. release가 기존 base에 유지되어 실패 시 병합 차단을 확인했다. 같은 release의 요청 B는 A 실행 중 pending이었고 A 실패 후 취소했다. 이 실패·취소 실행을 통과 근거로 사용하지 않는다.
준비 단계를 보완한 성공 실행은 아래 두 부모로 후보를 만들고, full 로컬 CI·docs/admin 빌드 뒤 검증한 커밋 그대로 반영했다.
| 검증·병합 대상 | 고정 SHA |
|---|---|
| release base | 692181a0e557c11f5e3371f467af54dec43d01d2 |
| PR #1433 head | e3b48e6e6236327c8cee567cfeda5435fbdb1738 |
| 검증 후보 = 실제 release 병합 커밋 | 762bbaa752bc7c6a932c112f9eb6bff6a57d3c77 |
로컬 DB 2,199 assert, 브라우저 57/57(skip·flaky 0), viewport 22/22, full evidence, docs/admin 빌드를 통과했다. 별도 관련 회귀는 19/19, Node 22의 npm run check는 3,392 통과·DB 조건 27 skip·실패 0이었다. DB 조건 skip을 실제 DB 실행 결과와 혼동하지 않는다.
같은 PR·head의 중복 요청은 앞 실행 동안 pending으로 기다린 뒤 alreadyMerged: true로 성공 종료했다. full CI를 다시 시작하거나 새 병합 커밋을 만들지 않았고 release SHA도 그대로 유지됐다.
세션에서 하는 일
- 목적 release에서 작업 브랜치를 만들고 같은 release를 base로 PR을 연다. 구현과 관련 테스트는 여러 Codex·Claude 세션에서 병렬로 진행할 수 있다.
- Phase마다
npm run check(정적 검사)를 통과한 변경을 커밋·push한다(PR 전 precheck는 2026-09-15 폐기). PR head와 로컬 HEAD가 같은 clean worktree에서 요청한다. 번호·위험 헤더·관리자 호환 등 변경에 필요한 준비는 PR에 남긴다.
npm run merge:request -- --pr <N>
# Merge Check만 하고 병합하지 않는 진단 실행:
npm run merge:request -- --pr <N> --dry-run- 요청된
3-Release Merge Request실행을 GitHub Actions에서 확인한다. 같은 release의 다른 요청이 처리 중이면 GitHub에서 대기한다. 요청한 개발 세션은 종료해도 되며,landing:lock파일이나 heartbeat를 유지하지 않는다. - 성공 여부와 검증한 base/head·merge SHA를 확인한다. release에 합쳐졌다는 사실은 staging 배포나 출시 완료를 뜻하지 않는다.
큐에 들어간 뒤 PR head를 추가 push하면 요청된 SHA의 실행은 병합하지 않는다. 수정·push 후 새 head로 다시 요청한다. 앞 PR이 release에 들어가면 다음 요청은 그 결과가 포함된 최신 release로 후보를 만든다. 일반 요청에서는 이 후보의 Merge Check만 수행하며 full 실행·재사용은 하지 않는다.
--dry-run은 요청 계획만 출력하는 기능이 아니다. 같은 슬롯에서 통합 후보를 만들고 Merge Check를 한 뒤 원격 병합만 하지 않는 진단 실행이다(2026-09-15 개정 전에는 앱 full CI까지 수행했다). ci:local --plan의 계획 출력과 구별한다. --workflow-ref <branch>는 초기 workflow 검증을 위한 dry-run에서만 허용한다. 실제 병합 요청은 main의 workflow를 사용한다.
슬롯 안에서 보장하는 순서
2026-09-10 #1491: release별 슬롯은 최신 후보의 Merge Check부터 원격 병합 확인까지만 유지한다. 명시적 dry-run은 같은 슬롯에서 full을 실행하고 병합하지 않는다. release→staging은 최종 후보의 hosted full CI를 실행하고 staging→main은 유효한 동일 tree 기록과 현재 staging 배포·smoke를 확인한다. 별도 승격 큐·전역 락·배포까지 이어지는 락은 추가하지 않는다.
요청 A ─┐
요청 B ─┼─ GitHub의 목적 release별 대기열
요청 C ─┘ │
└─ 요청 하나가 슬롯 소유
1. PR 상태·고정 head·현재 release base 확인
2. 임시 clone에 두 부모 merge commit 생성
3. 고정 base 기준 이력·migration 순서/위험 검사
4. head/base·라벨·clean 상태·후보 tree 재확인
5. 예상 base일 때만 검증 커밋을 fast-forward push
6. GitHub PR merged 상태 확인 → 슬롯 종료.github/workflows/release-merge-request.yml의 release 작업은 목적 브랜치별 concurrency 그룹을 사용한다.queue: max,cancel-in-progress: false로 이전 요청을 취소하지 않고 한 건씩 처리한다. 서로 다른 release의 큐는 구분되지만 현재 runner 한 대는 job 하나씩 실행한다.- job timeout은 180분이다. PR head/base·candidate commit·tree·결과는 GitHub job summary와 실행 로그에 기록하며 큰 검증 artifact를 별도로 업로드하지 않는다.
- 후보의 첫 부모는 슬롯을 얻은 뒤 읽은 release base, 둘째 부모는 요청에서 고정한 PR head다. 개발자의 worktree를 checkout·reset하거나 원격 PR head를 자동으로 고치지 않는다. 충돌은 담당자가 자기 브랜치에서 해결한다.
- 일반 후보는 full·DB 스택·브라우저·docs/admin 빌드를 시작하지 않는다. 고정 base SHA를 기준으로 Merge Check를 수행한다.
--dry-run일 때만 같은 후보에서npm run ci:full-local -- --base <고정 base SHA>를 실행한다. - 진단용 full에는 정적·단위·앱 빌드·migration replay·schema snapshot·pgTAP·유저 실사용 시뮬레이션(
browser)·화면 정합성 검사(viewport)·완료 증거 검증이 포함된다. DB 검사는 CI용 격리 Supabase 스택을 사용하며 staging/Production DB를 초기화하지 않는다. - 진단용 full에서 구형 탭 공존 검사 CASE-039/040의 입력인
v0.17.1태그는 controller가 읽기 인증 구간에서 미리 가져온다. 후보 의존성 설치 뒤 인증정보가 없는 CI 환경으로 구형 번들을 준비하고, 준비 실패는 full CI 전에 차단한다. 이는 해당 과거 태그를 현재 도구로 다시 빌드한 검사 입력이며 현재 운영 배포 산출물이라고 간주하지 않는다. - 검사 뒤 PR head/base·차단 라벨·작업 트리와 후보 commit/tree가 그대로인지 다시 확인한다. 원격 쓰기도 예상 release SHA를 조건으로 하므로 최종 조회 직후 누군가 release를 바꿔도 해당 요청은 덮어쓰지 못한다.
- 별도 랜딩 승인 라벨은 추가하지 않는다. 기존 호환 판정의
admin-hold·admin-compat-confirmed와full-ci관련 조건을 유지한다. 일반 release 병합은 라벨 유무와 관계없이 Merge Check만 수행한다. - 성공하면 Merge Check를 마친 merge commit 자체를 release에 반영한다. 마지막에 squash나 새 merge commit을 만들어 검증하지 않은 SHA로 바꾸지 않는다.
release → staging,staging → main은 별도 승격 PR이다. - GitHub concurrency는 workflow가 종료될 때 슬롯을 반환한다. 실패·취소·timeout 후 파일 락을 회수하거나 takeover할 필요가 없다. runner가 offline이면 새 요청은 실행할 PC가 돌아올 때까지 대기한다.
실패와 중단
| 결과 | 다음 행동 |
|---|---|
| 같은 PR 중복 요청·이미 병합됨 | 새 병합을 만들지 않는다. 원래 실행과 PR 상태를 확인한다 |
| merge 충돌·migration 번호/계약 문제 | 작업 브랜치에서 최신 release를 반영하고 수정·push한 뒤 다시 요청한다 |
| Merge Check 실패 또는 dry-run full 실패 | 해당 로그를 보고 수정한다. 일반 병합 성공을 full 성공으로 제출하지 않으며 dry-run은 결과와 관계없이 병합하지 않는다 |
| 검증 중 PR head 또는 release base 변경 | 해당 실행은 병합하지 않는다. 최신 조합으로 새 요청을 보낸다 |
| draft·닫힌 PR·차단 라벨·호환 조건 미충족 | PR 상태나 필요한 증거를 갖춘 뒤 다시 요청한다 |
| push 이후 응답 유실·PR merged 확인 실패 | 원격 release와 PR에 후보 SHA가 반영됐는지 먼저 조회한다. CI 실패로 단정해 revert하거나 두 번째 병합을 만들지 않는다 |
| workflow 취소·runner 중단 | 종료 결과와 원격 SHA를 확인한다. 최종 확인을 마치기 전에는 병합하지 않으며, 재요청은 처음부터 현재 조합을 검증한다 |
원격 push의 성공과 GitHub의 PR 상태 갱신은 별도 확인이다. push 직후 중단되면 원격 반영은 이미 끝났을 수 있으므로 실행 로그·release SHA·PR 상태를 함께 확인한다.
runner를 강제 종료하면 정리 코드도 끝나지 않아 해당 실행의 임시 Docker 스택이 남을 수 있다. 로그에서 확인한 그 실행의 격리 샌드박스만 npm run ci:local -- --sandbox <해당 샌드박스> --stop으로 정리한다. 개발 중인 다른 스택이나 서비스 DB는 종료·초기화하지 않는다.
원격 권한과 보호 규칙
concurrency만으로 웹 병합이나 직접 push까지 막을 수는 없다. release에는 다음 보호 구성을 함께 적용한다.
- 일반
release/*통합은 큐의 DeployKey 경로를 사용한다. 2026-09-10 오너가release-queue-only에 관리자 역할(RepositoryRole 5,always) bypass를 직접 추가했고 #1491의 승인된 관리자 병합에 사용했다. 이 사용자 추가 권한은 보존하며, 이번 예외를 후속 일반 작업의 큐 밖 병합 승인으로 확대하지 않는다. staging/main 승격 보호 규칙은 별도이며 기존 main 랜딩은 사용하지 않는다. - fast-forward가 아닌 갱신과 브랜치 삭제는 별도 보호 규칙으로 금지한다. 업데이트용 bypass가 이 보호까지 우회하게 만들지 않는다.
- 기본 GitHub Actions bot은 이 update ruleset의 bypass actor로 지정할 수 없어 저장소 전용 write deploy key를 사용한다. private key는
release-landingGitHub Environment의RELEASE_LANDING_SSH_KEYsecret에 저장하고 그 environment는main에서 실행한 workflow만 사용하도록 제한한다. - 등록된 전용 deploy key는
barbelic-release-landing(ID162654957)이다. key 값은 문서에 기록하지 않는다. - CI 자식 프로세스의 환경에는 이 키를 넘기지 않는다. 검증·병합 제어 코드는 main의 workflow에서 실행하고, 후보 PR의 코드는 검증 대상이다. self-hosted runner는 신뢰하는 저장소 작업을 실행하는 머신이며 다른 사용자 코드와 비밀을 격리하는 보안 샌드박스는 아니다.
- GitHub의 DeployKey bypass는 키 ID 하나를 지정하는 규칙이 아니라 저장소 deploy key 종류를 허용한다. 향후 다른 write deploy key를 추가할 때 release 쓰기 권한도 함께 생기는지 검토한다.
secret 값·등록 토큰·개인 키를 로그·PR·문서·저장소 파일에 쓰지 않는다. 원격 규칙을 잠깐 끄거나 CI 성공 상태를 꾸며 병합하지 않는다. 순수 문서의 docs/* → main 예외는 기존 별도 기준을 유지하며 release 큐의 검증 축소에 사용하지 않는다.
설치된 Windows runner 운영
| 항목 | 값 |
|---|---|
| GitHub repository | dekerd/Barbelic |
| 이름 / ID | barbelic-local-windows / 21 |
| 라벨 | self-hosted, Windows, X64, barbelic-release |
| 설치 / 작업 경로 | D:\LiftGuild-2026\BarbelicRunner / 그 안의 _work |
| 설치 버전 | Actions runner 2.337.0 |
| 설치 ZIP SHA256 | 1150692afa94e71f872017e254ea55b6eece1eece3fe7e3a6d4c93d0a1b85cfc |
| 확인한 도구 | Node 24.16.0, npm 11.13.0, Supabase 2.113.0, Docker Desktop Linux engine 29.7.2 |
| runner 전용 Git | 공식 SHA256을 확인한 MinGit 2.55.0.5, D:\LiftGuild-2026\BarbelicRunner\tools\git |
| Git 경로 설정 | repository variable RELEASE_RUNNER_GIT가 위 경로를 지정. workflow가 cmd·usr/bin을 GITHUB_PATH에 추가 |
| 실행 계정·형태 | USER, 숨김 background 프로세스. 비관리자 셸에서 설치하여 Windows 서비스는 아님 |
| 시작 스크립트 | D:\LiftGuild-2026\BarbelicRunner\start-runner.ps1 |
| 로그인 자동 시작 | HKCU\Software\Microsoft\Windows\CurrentVersion\Run의 BarbelicReleaseRunner |
| 로그 | 설치 폴더의 launcher.log, _diag; CI 로그는 GitHub 실행에서 확인 |
PC가 켜져 있고 USER가 로그인한 상태여야 runner가 실행된다. Docker Desktop도 가동되어야 한다. 버전 값은 설치 시점의 실측이며 저장소의 .nvmrc·package.json Supabase 핀이 변경되면 runner 도구도 맞춘다. workflow의 Windows 명령은 shell: powershell을 명시한다. pwsh는 설치 당시 Codex 임시 PATH에만 있어 재로그인 후에는 보장되지 않는다.
전용 Git은 GIT_CONFIG_COUNT 인증 환경을 지원하는 Git 2.31 이상이 필요해 설치했다. 기존 시스템 Git 2.24와 시스템 PATH는 변경하지 않고 workflow에서만 전용 Git을 선택한다.
수동으로 숨김 실행하려면 다음 명령을 사용한다.
Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "D:\LiftGuild-2026\BarbelicRunner\start-runner.ps1"'시작 스크립트의 Windows named mutex는 같은 로그인 세션에서 listener를 두 번 띄우지 않기 위한 것이다. 파일 락이 아니며 release 병합 권한이나 CI 슬롯으로 사용하지 않는다. 이미 실행 중이면 추가 listener를 만들지 않는다. 재시작이 필요하면 먼저 GitHub에서 runner가 idle인지 확인하고 해당 설치 경로의 listener를 종료한 뒤 시작한다. 진행 중인 job을 종료하면 그 실행의 원격 반영 여부를 확인한다.
읽기 전용 상태 확인:
gh api repos/dekerd/Barbelic/actions/runners --jq '.runners[] | {name,status,busy,labels: [.labels[].name]}'설치 근거: GitHub runner 등록, Windows 서비스 구성, 공식 runner v2.337.0 배포.
기존 main 랜딩과의 차이
| PR base | merge:request 처리 | 완료 시점 |
|---|---|---|
release/vX.Y.Z | 목적 release별 큐 → 최신 후보의 Merge Check → 조건부 merge commit 반영 | release와 PR의 병합 확인. full·배포 없음 |
main (전환 전 기록) | 기존 main 큐 → 원격 검사 → squash merge → 기존 staging 배포 확인. DEPLOYMENT_BRANCH_CUTOVER=true 활성화 후 요청 차단 | 전환 후 새 작업에 사용하지 않음 |
release 큐는 Vercel·Supabase 배포를 수행하지 않는다. main=Production, staging=staging 매핑을 유지한다. release→staging 최종 후보의 hosted full CI와 staging→main의 유효한 기록·배포 증거 확인은 별도 승격 PR이 담당한다. 큐 슬롯을 승격·배포까지 연장하지 않는다. main 전용 과거 준비·복구 절차는 마이그레이션 랜딩의 역사 절에 한정한다.
완료 범위 — 2026-09-10 오너 정정
구현이 끝나면 최신 목적 release 반영·필수 precheck·자기 PR의 Merge Check·실제 release 병합까지 이어서 처리한다. Draft PR이나 선택 검증에서 멈추고 오너에게 다음 실행을 재요청하지 않는다. 이미 승인된 정책의 미반영은 자기 작업에 필요한 최소 변경으로 해결하며 다른 담당자의 브랜치·큐는 조작하지 않는다. 상세 승인 경계와 완료 기준은 공통 지침을 따른다.