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-01 | LP-03 저장 로직은 LP-01 정책이 정해진 뒤 시작한다 |
| SS (start-to-start) | 선행이 시작하고 N작업일 뒤 후행이 시작할 수 있다 | LP-03:SS+3 | LP-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 세 기준의 실제 간격을 모두 계산하므로, 계획한 유형과 다른 유형으로 일했는지도 보인다.
읽는 순서는 세 가지다.
- 기간이 늘어난 업무. LP-03은 계획 6작업일, 실제 16작업일이다. 이 중 11월 3일~4일은 닫혀 있던 기간이고, 11월 5일에 다시 열려 이틀 더 걸렸다.
- 당겨 시작한 관계(리드). 7개 관계 중 5개가 FS 음수다. LP-01 → LP-03의 −1은 LP-01이 닫힌 날 바로 시작한 것이고, 나머지 4개는 선행이 끝나기 전에 시작했다. LP-04는 LP-03의 최종 완료일보다 7작업일 먼저 시작했다(FS −8). 실제로는 LP-03 시작 8작업일 뒤에 시작한 SS 관계로 일한 것이다.
- 기다린 관계(래그). 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+2 | LP-02는 정책 PR이 리뷰 중일 때(LP-01 시작 3작업일 뒤) 시작했다. 정책 초안이 나오는 LP-01 시작 2작업일 뒤로 정한다 |
LP-04 ← LP-03:SS+3 | LP-04는 LP-03의 저장 API만 필요했다. API가 나오는 LP-03 시작 3작업일 뒤로 정한다 |
LP-06 ← LP-05:FF+1 | LP-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의 지연을 일부 흡수했다. 다음 실습에서는 같은 이벤트 로그로 업무가 지나간 활동의 순서 전체를 그리고, 팀이 합의한 절차와 비교한다.