트랙 BB1180분

기준선과 변경 통제

10월 30일 Launchpad의 Project에서 LP-03의 Estimate는 40시간이다. 실습 13에서 정한 값은 32시간이었다. 이 8시간은 언제, 누구의 결정으로 바뀌었는가. Project는 필드의 현재 값만 보여 주고, 값이 바뀐 이력과 그 변경을 승인한 사람은 남기지 않는다. 실습 14에서 “Estimate는 계획 회의에서 정하고 바꾸지 않는다. 바꿔야 하면 기준선 변경으로 기록한다”고 정했지만, 기록했는지 확인하는 방법은 정하지 않았다. 이 모듈은 기준선(baseline)을 저장소의 파일과 태그로 고정하고, 변경을 요청·결정·대장으로 남기고, 두 스냅숏의 차이를 대장과 대조해 승인 기록이 없는 변경을 찾는다.

진행
설명 50분 (1~3단계), 실습 110분 (4~7단계), 정리 20분 (8단계)
결과
변경 요청 양식, docs/baseline/의 기준선 파일과 변경 대장, CODEOWNERS, 기준선 태그, 기준선 차이 보고, 변경 통제 절차서
명령
gh label create, gh issue create, git tag, gh api .../codeowners/errors, baseline-diff.sh
cd ~/gh-pm-lab
source pm-lab/env.sh

1기준선 세 가지와 통합 변경 통제

기준선은 승인된 계획의 한 시점 사본이다. 진행 상황은 기준선과 비교해 판단하고, 기준선 자체는 정해진 절차로만 바꾼다. Launchpad의 기준선은 Level 1에서 이미 만들어져 있다.

기준선Launchpad에서GitHub의 원천Level 1
범위 기준선(scope baseline)M1 비공개 베타의 업무 6건(LP-01~LP-06)과 각 업무의 완료 조건마일스톤의 업무 이슈, 상위 이슈의 하위 이슈실습 5, 13
일정 기준선(schedule baseline)업무별 Start date·Target date, M1 마감 2026-11-06Project 날짜 필드, 마일스톤 마감일실습 13 (주경로 계산)
원가 기준선(cost baseline)업무별 Estimate, 합계(BAC) 112시간Project 숫자 필드실습 14 (획득가치)

통합 변경 통제(integrated change control)는 기준선에 영향을 주는 모든 변경 요청을 한 경로로 받아 영향을 분석하고 결정하는 절차다. PMBOK 가이드 6판(2017)은 이것을 프로세스 4.6 “통합 변경 통제 수행(Perform Integrated Change Control)”으로 두고, 결정 기구로 변경 통제 위원회(Change Control Board, CCB)를 둔다.

  1. 요청변경 요청 이슈
  2. 영향 분석범위, 일정, 공수, 위험
  3. 결정PM 또는 CCB, 결정 기록 댓글
  4. 기준선 갱신Project 값, 변경 대장 PR
  5. 통보주간 보고

Level 1에서 이 경로를 한 번 지났다. 실습 12의 LP-07 요청은 Sprint 1에 넣지 않고 M2에 배정했고, 운영 이슈에 범위 변경 기록을 남겼다. 10월 22일에는 M1 마감을 11월 13일로 1주 미루는 결정이 운영 이슈 #8의 결정 기록 댓글로 남았다. 빠진 것은 두 가지다. 결정 전의 영향 분석이 정해진 양식으로 남지 않았고, 기록이 실제 값의 변경과 하나하나 대응하는지 확인하지 않았다.

2형상 관리의 네 활동

기준선을 관리하는 일은 형상 관리(configuration management)의 한 경우다. ISO 10007:2017(형상 관리 지침)은 형상 관리 계획 아래 네 활동을 둔다. 형상 항목(configuration item)은 관리 대상으로 정한 산출물이다. 여기서는 기준선 파일, 변경 대장, 통제 설정 파일이 형상 항목이다.

활동뜻GitHub에서단계
형상 식별(configuration identification)무엇이 관리 대상이고 어느 판이 기준인지 정한다docs/baseline/2026-10-12.json 파일, 태그 baseline-2026-10-125
변경 통제(change control)변경을 요청, 평가, 승인, 반영하는 절차변경 요청 이슈 양식, 결정 기록 댓글, CODEOWNERS 승인이 필요한 PR4, 5
형상 상태 기록(configuration status accounting)무엇이 언제 왜 바뀌었는지 기록하고 보고한다변경 대장 docs/baseline/changes.tsv, 커밋 이력7
형상 감사(configuration audit)실제 상태가 기록과 맞는지 확인한다baseline-diff.sh --changes6, 7

3결정 권한: 누가 무엇을 정하는가

변경 요청이 오면 “누가 결정하는가”를 먼저 정해 두어야 한다. 정해 두지 않으면 PM이 모든 변경을 혼자 정하거나, 반대로 작은 변경마다 회의가 열린다. 역할을 나누는 모델은 여러 가지가 있다.

모델역할쓰임
RACI실행(Responsible), 최종 책임(Accountable), 의견(Consulted), 통보(Informed)업무 하나의 실행 책임을 나눌 때. 최종 책임자는 한 명이다
DACI추진(Driver), 승인(Approver), 기여(Contributors), 통보(Informed)결정 하나를 진행할 때. 추진자가 선택지를 모으고 승인자가 정한다
RAPID권고(Recommend), 동의(Agree), 실행(Perform), 의견(Input), 결정(Decide)로저스(P. Rogers)와 블렌코(M. Blenko)가 2006년 Harvard Business Review의 “Who Has the D?”에서 제안했다. 동의(A)는 거부권을 가진 역할이다

변경 통제에는 결정자 한 명과 임계치를 함께 적는 방식이 맞는다. 아래는 Launchpad의 결정 권한 표다. 10월 22일의 M1 마감 변경은 마일스톤 마감 변경이므로 CCB(PM gildong과 개발 리드)가 정했다.

변경임계치결정 (D)의견 (C)통보 (I)
업무 목표일5작업일 이하, 마일스톤 마감 영향 없음PM담당자팀
업무 목표일5작업일 초과, 또는 마일스톤 마감 영향CCB담당자, QA이해관계자
추정 공수업무당 10% 이하PM담당자팀
추정 공수업무당 10% 초과, 또는 총 공수 10% 초과CCB담당자이해관계자
범위 추가·제외, 마일스톤 마감모든 경우CCB요청자, 담당자이해관계자

임계치는 획득가치관리의 변동 임계치(variance threshold)와 같은 생각이다. ANSI/EIA-748의 획득가치관리 시스템(EVMS) 지침은 계획과 실적의 큰 차이를 찾아 원인을 설명하도록 하고(분석 지침), 승인된 변경만 기준선에 넣고 소급 변경을 통제하고 기준선 변경을 문서로 남기도록 한다(개정과 자료 유지 지침 28~32). 임계치를 넘은 차이는 변동 분석 보고(Variance Analysis Report, VAR)에 원인, 영향, 대응을 적는다.

결정 기록과 ADR

나이가드(M. Nygard)가 2011년 글 “Documenting Architecture Decisions”에서 제안한 아키텍처 결정 기록(Architecture Decision Record, ADR)은 결정 하나를 짧은 파일 하나로 남긴다. 항목은 제목, 상태(제안·채택·대체), 맥락, 결정, 결과다. Level 1의 결정 기록 댓글(일시, 결정, 이유, 결정자, 관련, 목표·일정 영향)과 항목이 거의 같다. 다른 점은 상태다. ADR은 나중 결정이 앞 결정을 대체하면 앞 기록의 상태를 “대체됨”으로 바꾸고 링크한다. 기준선을 다시 정할 때도 이전 기준선을 지우지 않고 대체 관계를 남긴다.

4변경 요청 양식 설치

변경 요청은 업무 이슈와 다른 양식으로 받는다. 영향(범위, 일정, 공수, 위험)과 결정자를 필수 칸으로 두어, 영향 분석 없이 결정이 나지 않게 한다.

# 저장소의 .github/ISSUE_TEMPLATE/change-request.yml 로 복사하면 웹의 New issue 화면에 "변경 요청" 양식이 나타난다 (트랙 B1).
# 범위·일정·원가 기준선을 바꾸는 요청을 받는다. 결정 전에는 Project의 기준선 값(Target date, Estimate, Iteration)을 바꾸지 않는다.
# 결정은 이 이슈의 결정 기록 댓글로 남기고, 승인된 변경은 변경 대장(docs/baseline/changes.tsv)에 한 줄씩 적는다.
name: 변경 요청
description: 범위, 일정, 공수(원가) 기준선을 바꾸는 요청
title: "[CR] "
labels: ["kind:change"]
body:
  - type: markdown
    attributes:
      value: |
        기준선을 바꾸는 요청이다. 업무 하나의 진행 상황 보고는 업무 이슈의 댓글로 남긴다.
        결정 권한 표(docs/baseline/README.md)의 임계치를 보고 결정자를 고른다.
  - type: dropdown
    id: kind
    attributes:
      label: 변경 종류
      multiple: true
      options:
        - 범위 추가
        - 범위 제외
        - 목표일 변경
        - 공수(Estimate) 변경
        - 반복(Iteration) 변경
        - 마일스톤 마감 변경
    validations:
      required: true
  - type: input
    id: items
    attributes:
      label: 영향받는 업무
      placeholder: "예: #3, #5 (LP-03, LP-05)"
    validations:
      required: true
  - type: textarea
    id: change
    attributes:
      label: 바꿀 값
      description: 기준선의 값과 요청하는 값을 업무마다 한 줄씩 적는다.
      value: |
        | 업무 | 항목 | 기준선 | 요청 |
        | - | - | - | - |
        |  |  |  |  |
    validations:
      required: true
  - type: textarea
    id: reason
    attributes:
      label: 이유
      description: 무엇이 바뀌었기에 기준선을 바꾸는가. 결정 기록, 토론, 리뷰 댓글이 있으면 링크한다.
    validations:
      required: true
  - type: input
    id: schedule-impact
    attributes:
      label: 일정 영향 (작업일)
      placeholder: "예: LP-05 목표일 +2작업일, M1 마감 영향 없음"
    validations:
      required: true
  - type: input
    id: cost-impact
    attributes:
      label: 공수 영향 (시간)
      placeholder: "예: +8h (총 공수 112h → 120h, +7.1%)"
    validations:
      required: true
  - type: textarea
    id: scope-impact
    attributes:
      label: 범위와 품질 영향
      description: 완료 조건, 테스트 항목, 다른 업무의 완료 조건이 어떻게 바뀌는지 적는다.
  - type: textarea
    id: risk
    attributes:
      label: 위험 영향
      description: 새로 생기거나 커지는 위험, 하지 않을 때의 위험을 적는다.
  - type: dropdown
    id: decider
    attributes:
      label: 결정자
      description: 결정 권한 표의 임계치를 기준으로 고른다.
      options:
        - PM (임계치 이내)
        - 변경 통제 위원회 (임계치 초과 또는 마일스톤 마감 변경)
    validations:
      required: true
  - type: dropdown
    id: urgency
    attributes:
      label: 결정 시한
      options:
        - 다음 주간 회의
        - 48시간 안 (긴급)
      default: 0
    validations:
      required: true
  - type: checkboxes
    id: checks
    attributes:
      label: 제출 전 확인
      options:
        - label: 영향받는 업무의 담당자와 영향을 확인했다
          required: true
        - label: 기준선 차이 보고(baseline-diff.sh)를 댓글로 붙였다

양식은 기본 브랜치에 있어야 New issue 화면에 나타난다. 실습 18처럼 브랜치와 PR로 올린다. 라벨은 양식보다 먼저 만든다.

gh label create kind:change -R "$PM_REPO" --color D93F0B --description "기준선 변경 요청"
cd "$PM_REPO_NAME"
git switch main && git pull -q
git switch -c ci/change-request-form
mkdir -p .github/ISSUE_TEMPLATE
cp ../github-pm-starter-kit/templates/ISSUE_TEMPLATE/change-request.yml .github/ISSUE_TEMPLATE/
git add .github/ISSUE_TEMPLATE/change-request.yml
git commit -m "chore: 변경 요청 이슈 양식 추가"
git push -u origin ci/change-request-form
gh pr create --fill
cd ..

병합 뒤 웹의 New issue 화면에 “변경 요청”이 보이면 설치가 끝난 것이다. 양식의 칸은 웹 화면에서만 채울 수 있다. 명령줄에서 만들 때는 같은 항목을 본문 파일로 적고 라벨을 붙인다.

cat > pm-lab/cr-lp05.md <<'EOF'
### 변경 종류
공수(Estimate) 변경

### 영향받는 업무
#5 (LP-05)

### 바꿀 값
| 업무 | 항목 | 기준선 | 요청 |
| - | - | - | - |
| LP-05 | Estimate | 16 | 20 |

### 이유
10월 26일 재신청 정책 변경(#3 결정 기록)으로 테스트 항목 1건이 늘었다.

### 일정 영향 (작업일)
LP-05 목표일 변경 없음. M1 마감 영향 없음

### 공수 영향 (시간)
+4h (총 공수 112h → 116h, +3.6%)

### 결정자
변경 통제 위원회 (임계치 초과 또는 마일스톤 마감 변경)
EOF
gh issue create -R "$PM_REPO" --title "[CR] LP-05 추정 공수 16h → 20h" \
  --label kind:change --body-file pm-lab/cr-lp05.md

LP-05의 공수 변경은 +25%여서 업무당 10% 임계치를 넘으므로 결정자는 CCB다. 결정은 이 이슈에 결정 기록 댓글로 남기고, 승인되면 Project의 Estimate를 바꾼다. 순서가 바뀌어 값을 먼저 바꾸면, 아래 6단계의 차이 보고에서 그 변경은 승인 기록이 없는 변경으로 나온다.

5기준선을 파일과 태그로 고정

기준선 시점의 Project 스냅숏은 실습 18의 pm-data 브랜치에 이미 있다. 그 파일을 기본 브랜치의 docs/baseline/에 PR로 올리면, 기준선을 정한 사람과 승인한 사람이 PR 리뷰로 남는다. 병합한 커밋에 태그를 붙이면 나중에 파일이 바뀌어도 기준선 시점의 내용을 태그 이름으로 다시 꺼낼 수 있다.

BASE_DATE=2026-10-12   # 기준선으로 정한 날. pm-data 브랜치에 그날 스냅숏이 있어야 한다
cd "$PM_REPO_NAME"
git switch main && git pull -q
git switch -c docs/baseline-$BASE_DATE
mkdir -p docs/baseline .github
cp ../pm-lab/pm-data/snapshots/$BASE_DATE.json docs/baseline/$BASE_DATE.json
cp ../github-pm-starter-kit/templates/change-control.md docs/baseline/README.md
printf '# date\tkey\tfield\tfrom\tto\tref\tdecider\n' > docs/baseline/changes.tsv
cp ../github-pm-starter-kit/templates/CODEOWNERS.example .github/CODEOWNERS
git add docs/baseline .github/CODEOWNERS
git commit -m "docs: 일정·원가 기준선 $BASE_DATE 고정"
git push -u origin docs/baseline-$BASE_DATE
gh pr create --fill
cd ..

.github/CODEOWNERS는 경로마다 승인할 사람을 정한다. 키트의 예시는 아래와 같다. 아이디를 실습 저장소의 협업자로 고친다.

# 기준선과 통제 설정 파일의 코드 소유자 (트랙 B1).
# 저장소의 .github/CODEOWNERS 로 복사하고 아이디를 팀에 맞게 고친다.
# 규칙:
#   - 아래에 있는 줄이 위의 줄보다 우선한다. 한 파일에는 마지막으로 맞은 줄 하나만 적용된다.
#   - 한 줄에 소유자를 여럿 적으면 그중 한 사람의 승인으로 충족된다.
#   - PR 작성자는 자기 PR을 승인할 수 없다. 소유자가 한 사람뿐이면 그 사람이 쓴 PR은 승인받을 수 없다.
#   - 소유자는 저장소에 쓰기 권한이 있어야 한다.
#   - 이 파일만으로는 리뷰 요청이 자동으로 갈 뿐이다. 승인을 필수로 만들려면 기본 브랜치의 보호 규칙이나
#     규칙 세트에서 코드 소유자 리뷰(Require review from Code Owners)를 켠다.

# 기준선 파일과 변경 대장: PM과 개발 리드 중 작성자가 아닌 사람이 승인한다
/docs/baseline/               @gildong @dev-kim

# 통제 설정 파일: 이 파일, 이슈 양식, 워크플로
/.github/CODEOWNERS           @gildong @dev-kim
/.github/ISSUE_TEMPLATE/      @gildong @dev-kim
/.github/workflows/           @dev-kim @dev-lee
규칙Launchpad에서 생기는 일
한 줄에 여러 소유자를 적으면 그중 한 사람의 승인으로 충족된다/docs/baseline/는 gildong이나 dev-kim 중 한 사람이 승인하면 된다. 두 사람 모두의 승인을 요구할 수는 없다
PR 작성자는 자기 PR을 승인할 수 없다gildong이 올린 기준선 PR은 dev-kim이 승인한다. 소유자를 gildong 한 명만 적으면 gildong의 PR은 코드 소유자 승인을 받을 수 없다
파일 하나에는 마지막으로 맞은 줄 하나만 적용된다아래에 * 줄을 두면 위의 경로 규칙이 모두 가려진다
파일만으로는 리뷰 요청이 자동으로 갈 뿐이다승인을 필수로 만들려면 기본 브랜치의 보호 규칙이나 규칙 세트에서 코드 소유자 리뷰(Require review from Code Owners)를 켠다

PR을 올린 뒤 CODEOWNERS 문법 오류가 없는지 확인한다. 이 API는 오류 목록을 돌려주며, 오류가 없으면 빈 배열이다.

gh api "repos/$PM_REPO/codeowners/errors?ref=docs/baseline-$BASE_DATE" --jq '.errors | length'

PR이 병합되면 병합 커밋에 주석 태그를 붙인다. 태그 메시지에 승인 PR 번호를 적어 두면 기준선과 승인 기록이 서로 가리킨다.

cd "$PM_REPO_NAME"
git switch main && git pull -q
git tag -a "baseline-$BASE_DATE" -m "일정·원가 기준선 $BASE_DATE. 승인: PR 번호를 적는다"
git push origin "baseline-$BASE_DATE"
git show "baseline-$BASE_DATE:docs/baseline/$BASE_DATE.json" | jq '.items | length'
cd ..

마지막 줄은 태그 시점의 기준선 파일에서 항목 수를 센다. 태그는 지우거나 다른 커밋으로 옮길 수 있으므로, 쓰기 권한이 있는 사람이 태그를 고치지 못하게 하는 설정(태그 대상 규칙)을 함께 두어야 기준선 식별이 유지된다.

6기준선 차이 보고

baseline-diff.sh는 기준선 스냅숏과 현재 스냅숏을 이슈 주소로 맞춰 비교한다. 비교 항목은 업무 추가·제외, Target date, Estimate, Iteration, 마일스톤 마감이다. Status와 담당자는 진행 상황이므로 비교하지 않는다. 목표일 차이는 lib/workdays.jq의 작업일 계산으로 센다. 실습 저장소의 스냅숏은 실습 기간이 짧아 차이가 거의 없으므로, Launchpad의 10월 12일 기준선과 10월 30일 스냅숏으로 실행한다. 두 파일은 pm-data 브랜치의 스냅숏과 같은 gh project item-list --format json 형식이다.

요약 줄에서 읽히는 것은 다음과 같다.

항목값읽는 법
업무 추가1LP-07(M2 공개 런칭). Estimate가 없어 총 공수에는 더해지지 않았다
총 공수112h → 124h+12h, +10.7%. LP-03(+8h)과 LP-05(+4h)의 합이다. 실습 14의 BAC가 바뀌었으므로 그 뒤의 EVM 지표는 10월 12일 이전 주와 같은 기준으로 비교할 수 없다
가장 늦은 목표일+5작업일11월 4일에서 11월 11일로. M1 마감도 같은 5작업일만큼 미뤄졌다
목표일 변경5LP-02~LP-06. LP-03의 +6작업일만 임계치(5작업일)를 넘었다
반복 변경2LP-02, LP-03이 Sprint 1에서 Sprint 2로 옮겨졌다 (실습 12의 이월)

LP-01은 10월 16일에 끝났지만 Target date는 10월 14일 그대로다. 끝난 업무의 목표일은 고치지 않는다. 기준선 차이는 계획이 바뀐 것을 보여 주고, 실제와 계획의 차이는 실습 14의 EVM과 실습 15의 예측이 보여 준다.

7변경 대장과 대조

차이 보고만으로는 그 변경이 승인되었는지 알 수 없다. 승인된 변경을 한 줄씩 적는 변경 대장을 두고, 차이마다 같은 업무·항목·바뀐 값의 줄이 있는지 대조한다. 대장은 CODEOWNERS가 보호하는 docs/baseline/changes.tsv에 두고, 줄을 더할 때마다 PR로 올린다. 아래는 10월 30일까지 Launchpad에서 승인된 변경을 적은 예시다.

# 기준선 변경 대장 (baseline-diff.sh --changes). 열 구분은 탭이다. 승인된 변경만 적는다.
# field: item(업무 추가·제외), target date, estimate, iteration, milestone(key 자리에 마일스톤 제목)
# to: item이면 추가 또는 제외, 나머지는 바뀐 뒤의 값
# date	key	field	from	to	ref	decider
2026-10-14	LP-07	item	-	추가	#8 범위 변경 기록	gildong
2026-10-22	M1 비공개 베타	milestone	2026-11-06	2026-11-13	#8 결정 기록	gildong, 개발 리드
2026-10-23	LP-02	iteration	Sprint 1	Sprint 2	#8 Sprint 1 종료 기록	gildong
2026-10-23	LP-03	iteration	Sprint 1	Sprint 2	#8 Sprint 1 종료 기록	gildong
2026-10-26	LP-02	target date	2026-10-21	2026-10-27	#16 Sprint 2 계획	gildong
2026-10-26	LP-03	target date	2026-10-22	2026-10-30	#16 Sprint 2 계획	gildong
2026-10-26	LP-04	target date	2026-10-28	2026-11-03	#16 Sprint 2 계획	gildong
2026-10-26	LP-05	target date	2026-11-02	2026-11-09	#16 Sprint 2 계획	gildong
2026-10-26	LP-06	target date	2026-11-04	2026-11-11	#16 Sprint 2 계획	gildong
2026-10-26	LP-05	estimate	16	20	#3 결정 기록	gildong

차이 11건(업무 추가 1, 목표일 5, 공수 2, 반복 2, 마일스톤 마감 1) 중 승인 기록이 없는 것은 LP-03의 공수 1건이다. 이 변경은 두 가지 결함을 함께 보여 준다.

  • 기록 결함: 32h에서 40h로 바꾼 결정이 어디에도 없다. 담당자가 Project 칸을 직접 고쳤을 가능성이 있다. 결정이 있었는지 담당자와 PM에게 확인한다.
  • 권한 결함: +25%는 업무당 10% 임계치를 넘으므로 결정이 있었더라도 CCB의 결정이어야 한다.

교정 통제는 사후 변경 요청이다. LP-03의 변경 요청 이슈를 지금 만들고, CCB가 40h를 승인하거나 32h로 되돌리는 결정을 남긴다. 승인하면 대장에 줄을 더한다. 소급 승인이었다는 사실은 대장의 날짜와 참조로 남는다.

임계치를 바꾸면 변동 분석 대상이 달라진다. 목표일 임계치를 3작업일로 낮추고 공수 임계치를 20%로 올리면 아래와 같다.

목표일 대상이 LP-02~LP-06의 5건으로 늘고, 총 공수 +10.7%는 20% 안이어서 원가 기준선 결정 줄이 빠진다. 공수 25% 변경은 20% 임계치도 넘으므로 LP-03, LP-05는 계속 대상이다. 임계치를 너무 낮추면 모든 변경이 CCB로 가서 결정이 늦어지고, 너무 높이면 마감에 영향을 주는 누적 변경이 PM 혼자의 결정으로 쌓인다. M1 마감까지 여유가 2작업일이었던 Launchpad(실습 13)에서는 5작업일 임계치가 여유보다 크다는 점도 함께 검토한다.

임계치를 넘은 업무마다 변동 분석을 짧게 쓴다.

업무: LP-03 방문자가 이메일로 사전신청을 완료한다
차이: 목표일 2026-10-22 → 2026-10-30 (+6작업일), 공수 32h → 40h (+25%)
원인: LP-01 정책 확정을 기다리며 10-14~10-16 막힘. 10-26 재신청 정책 변경으로 저장 로직과 테스트를 다시 작성
영향: LP-04, LP-05 시작 지연. M1 마감은 10-22 결정(11-13)으로 흡수
대응: 사후 변경 요청으로 공수 변경 결정. 정책 문서가 바뀌면 개발 착수 전에 완료 조건을 고친다
담당·기한: gildong, 11-02 CCB

8변경 통제 절차서

지금까지 정한 것을 한 문서로 묶는다. 키트의 양식을 5단계에서 docs/baseline/README.md로 복사했으므로, 그 파일을 채워 PR로 올린다.

# 변경 통제 절차서: (프로젝트 이름)

저장소의 docs/baseline/README.md 로 복사해 채운다 (트랙 B1). 이 파일과 docs/baseline/ 폴더는 CODEOWNERS로 보호한다.

## 1. 기준선

| 기준선 | 내용 | 원천 | 고정한 시점 |
| - | - | - | - |
| 범위 | 업무 이슈와 완료 조건 (마일스톤 M1) | Project 스냅숏의 업무 목록 | 태그 baseline-YYYY-MM-DD |
| 일정 | 업무별 Start date, Target date, 마일스톤 마감 | 같은 스냅숏 | 같은 태그 |
| 원가 | 업무별 Estimate (총 공수) | 같은 스냅숏 | 같은 태그 |

## 2. 결정 권한

| 변경 | 임계치 | 결정자 (D) | 의견 (C) | 통보 (I) |
| - | - | - | - | - |
| 업무 목표일 | 5작업일 이하, 마일스톤 마감 영향 없음 | PM | 담당자 | 팀 |
| 업무 목표일 | 5작업일 초과 또는 마일스톤 마감 영향 | 변경 통제 위원회 | 담당자, QA | 이해관계자 |
| 추정 공수 | 업무당 10% 이하 | PM | 담당자 | 팀 |
| 추정 공수 | 업무당 10% 초과 또는 총 공수 10% 초과 | 변경 통제 위원회 | 담당자 | 이해관계자 |
| 범위 추가·제외 | 모든 경우 | 변경 통제 위원회 | 요청자, 담당자 | 이해관계자 |
| 마일스톤 마감 | 모든 경우 | 변경 통제 위원회 | 팀 | 이해관계자 |

변경 통제 위원회: (이름과 역할). 정족수: (예: 결정자 2명 중 2명).

## 3. 절차

1. 요청자가 변경 요청 이슈(양식: change-request.yml)를 만든다.
2. PM이 영향(범위, 일정, 공수, 위험)을 적고 기준선 차이 보고(baseline-diff.sh)를 댓글로 붙인다.
3. 결정자가 결정 기록 댓글로 승인, 보류, 반려를 남긴다.
4. 승인되면 Project 값을 바꾸고, 변경 대장(docs/baseline/changes.tsv)에 한 줄씩 적는 PR을 만든다.
5. 다음 주간 보고에 변경을 알린다.

## 4. 긴급 변경

(예: 48시간 안에 결정해야 하는 경우 PM이 먼저 결정하고, 다음 위원회에서 사후 승인한다. 사후 승인 기한을 넘기면 기준선으로 되돌린다.)

## 5. 점검

- 매주 월요일: baseline-diff.sh --changes 로 기록 없는 차이를 찾는다.
- 기준선을 새로 정할 때: 새 스냅숏을 docs/baseline/에 올리고 태그를 만든다. 이전 기준선과 변경 대장은 지우지 않는다.

절차서에서 팀이 직접 정할 것은 세 가지다. 결정 권한 표의 임계치, CCB 구성원과 정족수, 긴급 변경의 사후 승인 기한이다. 실습 저장소에서는 혼자 실습하므로 CCB를 PM과 실습 짝으로 정한다.

막히면
증상확인과 해결
New issue 화면에 “변경 요청”이 없다양식 파일이 기본 브랜치에 병합되지 않았거나 경로가 .github/ISSUE_TEMPLATE/가 아니다. 문법 오류가 있으면 웹의 양식 파일 화면에 오류가 표시된다
could not add label: 'kind:change' not found라벨이 없다. gh label create kind:change를 먼저 실행한다
cp: ... snapshots/2026-10-12.json: No such file or directory그날 스냅숏이 없다. ls ../pm-lab/pm-data/snapshots | head로 있는 날짜를 보고 BASE_DATE를 고친다
codeowners/errors가 0보다 크다--jq '.errors[] | [.line, .message] | @tsv'로 줄과 이유를 본다. 없는 아이디나 쓰기 권한이 없는 사람이 소유자로 적힌 경우가 많다
차이 보고의 업무 키가 #3처럼 나온다제목 앞에 [LP-03] 같은 키가 없다. 변경 대장의 key 열도 같은 표기(#3)로 적는다
모든 차이가 “기록 없음”이다변경 대장의 열 구분이 탭이 아니다. cat -et pm-lab/changes.tsv | head -3에서 탭은 ^I로 보인다. to 열은 바뀐 뒤의 값을 Project와 같은 형식(날짜는 YYYY-MM-DD, 공수는 숫자)으로 적는다
gh project item-list --format json 결과가 아니다스냅숏 파일에 items 배열이 없다. 실습 18의 워크플로가 만든 파일인지 head -c 200으로 본다
  • Launchpad의 범위·일정·원가 기준선이 각각 어느 GitHub 기록에 있는지 말할 수 있다.
  • 변경 요청 양식이 실습 저장소의 New issue 화면에 보이고, kind:change 라벨이 있다.
  • docs/baseline/에 기준선 파일, 변경 대장, 절차서가 있고 .github/CODEOWNERS가 그 경로를 보호한다.
  • 기준선 태그를 만들고 태그로 기준선 파일을 다시 꺼냈다.
  • baseline-diff.sh --changes 결과에서 승인 기록이 없는 LP-03 공수 변경을 찾고 사후 변경 요청을 만들었다.
  • 절차서의 결정 권한 표에 팀의 임계치를 적었다.

마치며...

기준선을 파일과 태그로 고정하고 승인된 변경을 대장에 적어 두면, 두 스냅숏의 차이 하나하나를 승인 기록과 맞춰 볼 수 있다. Launchpad의 10월 30일 Project에서는 차이 11건 중 LP-03의 공수 1건이 기록 없이 바뀌었고, 그 변경은 PM의 결정 범위도 넘었다. 대조는 사후에 결함을 찾는 탐지 통제이고, CODEOWNERS는 기준선 파일이 승인 없이 바뀌지 않게 하는 예방 통제의 출발점이다. B2에서는 규칙 세트로 기본 브랜치의 승인과 검사를 강제하고, 설정과 접근 권한을 통제 매트릭스로 정리한다.