4회차실습 20115–145분

마일스톤과 리드·래그 분석

M1은 11월 11일에 끝났다. schedule.tsv로 계산한 계획 완료일(11월 4일)보다 5작업일 늦었고, 10월 22일에 바꾼 마감(11월 13일)보다는 2작업일 일찍 끝났다. 5작업일은 업무 기간이 늘어서 생겼을 수도 있고, 업무 사이에서 기다려서 생겼을 수도 있다. 반대로 어떤 업무는 선행 업무가 끝나기 전에 시작해 시간을 줄였을 수도 있다. 이 실습은 기록에서 업무별 실제 시작일과 완료일을 꺼내고, 계획한 선후행 관계마다 리드(lead)와 래그(lag)를 잰다.

진행
설명 10분, 실습 20분
결과
pm-lab/event-log.csv, 리드·래그 보고, pm-lab/schedule-v2.tsv
명령
event-log.sh, lead-lag.sh, cpm.sh, gh api …/milestones
cd ~/gh-pm-lab
source pm-lab/env.sh

1선후행 관계 네 가지와 리드·래그

실습 13의 schedule.tsv는 모든 관계를 “선행이 끝나야 후행이 시작한다” 하나로 적었다. 선후행 관계 도표법(Precedence Diagramming Method, PDM)은 관계를 네 가지로 나누고, 관계마다 기다리는 시간(래그)이나 당기는 시간(리드)을 붙인다. PDM은 1961년 존 폰달(John Fondahl)이 CPM을 컴퓨터 없이 계산하는 방법으로 제안했고, 1964년 IBM 1440 Project Control System 사용자 설명서를 통해 널리 쓰였다.

유형뜻schedule.tsv 표기Launchpad 예
FS (finish-to-start)선행이 끝나야 후행이 시작한다LP-01LP-03 저장 로직은 LP-01 정책이 정해진 뒤 시작한다
SS (start-to-start)선행이 시작하고 N작업일 뒤 후행이 시작할 수 있다LP-03:SS+3LP-04 알림은 LP-03의 저장 API가 나오면(시작 3작업일 뒤) 시작할 수 있다
FF (finish-to-finish)선행이 끝나고 N작업일 뒤 후행이 끝난다LP-05:FF+1베타 초대 준비는 QA가 끝난 다음 작업일에 끝난다
SF (start-to-finish)선행이 시작해야 후행이 끝날 수 있다LP-05:SF드물다. 새 시스템이 가동해야 이전 시스템 운영이 끝나는 경우

래그는 후행을 늦추는 시간이고, 리드는 후행을 앞당기는 시간이다. PMBOK 가이드는 리드를 “선행 활동에 대해 후행 활동을 앞당길 수 있는 시간”, 래그를 “선행 활동에 대해 후행 활동을 늦춰야 하는 시간”으로 정의한다. 표기에서는 래그를 +, 리드를 −로 적는다. LP-01:FS-1은 LP-01이 끝나기 1작업일 전에 후행을 시작한다는 뜻이다. 키트의 cpm.sh는 네 유형과 리드·래그를 모두 계산한다.

2기록에서 실제 날짜 꺼내기

event-log.sh는 업무 이슈의 타임라인, 업무를 닫는 PR의 커밋·리뷰·병합, 실습 18의 Project 스냅숏을 합쳐 사건 하나를 한 줄로 쓴 이벤트 로그(event log)를 만든다. 스냅숏을 먼저 최신으로 받는다.

git -C pm-lab/pm-data pull -q
bash github-pm-starter-kit/event-log.sh "$PM_REPO" --snapshots pm-lab/pm-data/snapshots > pm-lab/event-log.csv
활동가져오는 기록시각
업무 생성이슈 생성생성 시각
작업 시작스냅숏에서 처음 In Progress로 보인 날그날 스냅숏 시각(18:00)
막힘 · 막힘 해소blocked 라벨을 붙이고 뗀 기록라벨 시각
결정 기록“결정 기록”이 들어간 업무 댓글댓글 시각
첫 커밋업무를 닫는 PR의 커밋 중 가장 이른 것커밋 작성 시각
PR 생성 · PR 병합 · PR 닫힘업무를 닫는 PR(Closes #번호)PR 시각
변경 요청 · 리뷰 승인PR 리뷰의 CHANGES_REQUESTED, APPROVED리뷰 제출 시각
업무 완료 · 업무 닫힘 · 다시 열림이슈를 완료로 닫음, 완료 아닌 이유로 닫음, 다시 엶타임라인 시각

열은 사례(case_id), 활동, 시각, 수행자(resource), 관련 PR 번호(ref), 영역(area, 업무 이슈의 첫 area:* 라벨) 순서다. 영역은 업무 종류별로 흐름을 나눠 볼 때 쓴다.

실습 저장소에는 Sprint 2와 Sprint 3의 기록이 없다. 자기 저장소의 로그를 한 번 만들어 열어 본 뒤, 이후 단계는 키트의 예시 로그로 진행한다.

cp github-pm-starter-kit/samples/event-log.sample.csv pm-lab/event-log.csv

3관계마다 리드와 래그 재기

lead-lag.sh는 업무마다 실제 시작일(작업 시작, 없으면 첫 커밋)과 실제 완료일(마지막 업무 완료)을 작업일 번호로 바꾸고, 계획과 비교한다. 관계마다 FS, SS, FF 세 기준의 실제 간격을 모두 계산하므로, 계획한 유형과 다른 유형으로 일했는지도 보인다.

읽는 순서는 세 가지다.

  1. 기간이 늘어난 업무. LP-03은 계획 6작업일, 실제 16작업일이다. 이 중 11월 3일~4일은 닫혀 있던 기간이고, 11월 5일에 다시 열려 이틀 더 걸렸다.
  2. 당겨 시작한 관계(리드). 7개 관계 중 5개가 FS 음수다. LP-01 → LP-03의 −1은 LP-01이 닫힌 날 바로 시작한 것이고, 나머지 4개는 선행이 끝나기 전에 시작했다. LP-04는 LP-03의 최종 완료일보다 7작업일 먼저 시작했다(FS −8). 실제로는 LP-03 시작 8작업일 뒤에 시작한 SS 관계로 일한 것이다.
  3. 기다린 관계(래그). LP-02 → LP-05는 4작업일을 기다렸다. LP-05는 세 선행 중 마지막인 LP-04가 끝난 다음 작업일에 시작했으므로(FS 0), 이 4작업일은 LP-05를 늦춘 원인이 아니라 LP-02의 여유다.

계획의 주경로 LP-01 → LP-03 → LP-04 → LP-05 → LP-06에서 LP-03이 10작업일 늘었지만 M1은 5작업일만 늦었다. LP-04와 LP-06을 선행 완료 전에 시작한 기간이 그 차이를 줄였다.

4다음 계획의 관계 다시 정하기

측정값을 그대로 다음 계획에 옮기지 않는다. LP-04의 실제 SS 8에는 LP-03이 늘어난 기간이 섞여 있다. 팀이 다음 마일스톤에서 지킬 수 있는 관계로 고친다. 아래는 회고에서 정한 관계다.

cat > pm-lab/schedule-v2.tsv <<'EOF'
LP-01	3	12	-
LP-02	5	24	LP-01:SS+2
LP-03	6	32	LP-01
LP-04	4	20	LP-03:SS+3
LP-05	3	16	LP-02,LP-03,LP-04
LP-06	2	8	LP-05:FF+1
EOF
관계근거가 된 기록
LP-02 ← LP-01:SS+2LP-02는 정책 PR이 리뷰 중일 때(LP-01 시작 3작업일 뒤) 시작했다. 정책 초안이 나오는 LP-01 시작 2작업일 뒤로 정한다
LP-04 ← LP-03:SS+3LP-04는 LP-03의 저장 API만 필요했다. API가 나오는 LP-03 시작 3작업일 뒤로 정한다
LP-06 ← LP-05:FF+1LP-06은 QA가 끝나기 1작업일 전에 시작해 QA 다음 날 끝났다. 시작이 아니라 끝을 맞추는 관계다

탭 문자를 입력하기 어려우면 위 블록을 그대로 복사해 붙여 넣는다. 같은 업무 기간으로 다시 계산한다.

업무 기간은 그대로이고 관계만 바꿨는데 18작업일이 14작업일이 된다. 위 리드·래그 화면의 “계획 막대”를 schedule-v2.tsv로 바꾸면 같은 결과를 막대로 볼 수 있다. 관계를 바꾼 이유는 결정 기록으로 남기고, link-deps.sh를 다시 실행해 이슈 의존성도 맞춘다. GitHub의 의존성에는 관계 유형을 적을 칸이 없으므로 업무 키만 연결된다.

5마일스톤 단위로 보기

M1 비공개 베타날짜근거
계획 완료일11-04(수)cpm.sh, 실습 13
원래 마감11-06(금)결정 기록(10-22)에만 남아 있다. GitHub 마일스톤은 현재 마감만 보여 준다
10-21 기준 EVM 예상 완료일11-19(목)실습 14
10-21 기준 확률 예측 50% · 85%11-13(금) · 11-20(금)실습 15
바꾼 마감11-13(금)마일스톤 due_on
실제 완료11-11(수)마지막 업무 LP-06이 닫힌 날, 마일스톤 closed_at

10월 21일의 예측은 모두 실제보다 늦었다. 그 뒤 팀은 LP-04와 LP-06을 선행 완료 전에 시작했다. 처리량 기반 예측과 EVM은 과거의 속도로 앞을 계산하므로, 일하는 순서를 바꾼 효과는 바꾼 뒤의 기록에만 나타난다. 예측과 실제를 마일스톤마다 이 표처럼 남겨 두면, 다음 예측을 얼마나 믿을지 정하는 근거가 된다.

6지표 사이의 선행과 후행

리드와 래그는 업무 사이의 관계에만 쓰는 말이 아니다. 지표에도 먼저 움직이는 것과 나중에 움직이는 것이 있다. 리뷰를 기다리는 PR 수, 진행 중 업무 수(WIP), 막힘 수처럼 결과보다 먼저 변하는 지표를 선행 지표(leading indicator), 처리량, SPI, 완료일처럼 결과를 나중에 보여 주는 지표를 후행 지표(lagging indicator)라고 한다.

두 지표의 시차를 확인하려면 주별 값을 나란히 놓고, 선행 지표를 k주 밀어 후행 지표와의 상관계수를 k별로 계산한다(교차상관, cross-correlation). 일별 WIP는 실습 18의 스냅숏에서 바로 얻는다.

for f in pm-lab/pm-data/snapshots/*.json; do
  printf '%s\t%s\n' "$(basename "$f" .json)" \
    "$(jq '[.items[] | select(.status == "In Progress" or .status == "In Review")] | length' "$f")"
done

Launchpad처럼 3~5주 기록으로 계산한 상관계수는 한두 주의 값에 크게 흔들린다. 여러 분기의 주별 기록이 쌓인 뒤에 계산하고, 상관이 높다는 결과를 원인으로 읽지 않는다.

  • 자기 저장소로 event-log.sh를 실행해 이벤트 로그를 열어 봤다.
  • lead-lag.sh 결과에서 겹쳐 시작한 관계와 기다린 관계를 각각 하나씩 설명할 수 있다.
  • schedule-v2.tsv를 만들고 cpm.sh로 다시 계산했다.
  • M1의 계획, 마감, 예측, 실제 날짜를 한 표로 정리했다.

마치며...

리드·래그 분석은 계획에 적은 관계가 실제 일하는 방식과 맞았는지를 관계 하나씩 확인하는 일이다. Launchpad에서는 “모두 FS”라는 계획과 달리 팀이 업무를 겹쳐 진행했고, 그 겹침이 LP-03의 지연을 일부 흡수했다. 다음 실습에서는 같은 이벤트 로그로 업무가 지나간 활동의 순서 전체를 그리고, 팀이 합의한 절차와 비교한다.