cd ~/gh-pm-lab source pm-lab/env.sh
1세 개의 값
EVM은 1967년 미국 국방부가 계약 업체의 비용과 일정을 함께 관리하려고 만든 비용·일정 통제 기준(C/SCSC)에서 시작했고, 1998년 산업 표준 ANSI/EIA-748로 정리되었다. 소프트웨어 팀에서는 예산을 돈 대신 사람의 시간(공수)으로 잡으면 같은 식을 그대로 쓸 수 있다. 기준일 2026년 10월 21일(수)의 Launchpad 값으로 세 값을 정의한다.
| 값 | 정의 | GitHub에서 오는 곳 | 10월 21일 |
|---|---|---|---|
| BAC 총예산 | 계획한 전체 일의 추정 공수 합계 | Estimate 필드 합계 | 112h |
| PV 계획가치 | 계획대로라면 기준일까지 끝났어야 할 일의 추정 공수 | Estimate, Start date, Target date | 62.7h |
| EV 획득가치 | 실제로 끝낸 일의 추정 공수 (추정 × 진척률) | Estimate, Status, 완료 조건 체크박스 | 32h |
| AC 실제 투입 | 기준일까지 실제로 쓴 시간 | Actual 필드 합계 | 42h |
PV는 업무마다 Start date부터 Target date까지 작업일에 고르게 나눠 쌓는다. LP-03(32시간, 10월 15일~22일, 6작업일)은 10월 21일까지 5작업일이 지났으므로 32 × 5/6 = 26.7시간이 PV다. EV는 PV와 같은 추정 공수를 쓰되, 시간이 아니라 끝낸 결과로 센다. LP-03은 완료 조건 4개 중 1개를 충족했으므로 32 × 1/4 = 8시간이다.
2진척률 규칙
진행 중인 업무를 몇 퍼센트 끝났다고 볼지는 규칙으로 정한다. 같은 날의 같은 기록도 규칙에 따라 EV가 세 배 넘게 달라진다.
| 규칙 | 진행 중 업무의 진척률 | 10월 21일 EV | SPI |
|---|---|---|---|
| 0/100 | 0%. Done만 100% | 12h | 0.19 |
| 50/50 | In Progress·In Review이면 50% | 40h | 0.64 |
| 체크박스 비율 (이 과정의 기본값) | 완료 조건 중 체크한 비율 | 32h | 0.51 |
0/100은 끝나지 않은 일을 인정하지 않아 진행 중 업무가 많을수록 지연이 크게 보인다. 50/50은 시작만 해도 절반을 인정한다. 체크박스 비율은 실습 3에서 “검수자가 예·아니오로 확인할 수 있게” 쓴 완료 조건을 그대로 진척 측정에 쓴다. 규칙은 스프린트를 시작하기 전에 정하고, 중간에 바꾸지 않는다.
3실제 투입 시간 기록
Actual은 업무마다 지금까지 쓴 누적 시간이다. 실행 담당자가 매주 금요일에 갱신한다. 필드를 만들고, 10월 21일 상황을 재현하는 값을 넣는다.
gh project field-create "$PM_PROJECT" --owner "$PM_OWNER" --name Actual --data-type NUMBER
for pair in LP-01:18 LP-02:14 LP-03:10; do
key=${pair%%:*}; hours=${pair##*:}
url=$(awk -F'\t' -v k="$key" '$1 == k {print $3}' pm-lab/backlog-map.tsv)
gh project item-edit "$PM_PROJECT" --owner "$PM_OWNER" --url "$url" --field Actual --value "$hours"
done
gh project item-edit "$PM_PROJECT" --owner "$PM_OWNER" \
--url "$PM_FORM_URL" --field Status --value "In Progress"
${pair%%:*}는 LP-01:18에서 : 앞을, ${pair##*:}는 뒤를 남긴다. 이어서 웹 화면에서 LP-02 본문의 완료 조건 첫 두 개, LP-03의 첫 한 개를 눌러 체크한다. 체크는 본문에 - [x]로 저장되고, 스크립트는 이 표시의 개수를 센다.
Actual은 추정이 얼마나 맞았는지 보기 위한 값이다. 개인별 투입 시간을 비교하는 데 쓰면 기록이 실제와 달라지고, 그때부터 AC와 CPI는 의미를 잃는다. 팀 단위로만 집계한다.
4계산
M1 업무만 JSON으로 내려받아 계산한다. 마일스톤 조건으로 M2의 LP-07과 상위 이슈는 빠진다.
gh project item-list "$PM_PROJECT" --owner "$PM_OWNER" --limit 200 \ --query 'label:"kind:task" milestone:"M1 비공개 베타"' --format json \ > pm-lab/evm-input.json bash github-pm-starter-kit/evm-report.sh pm-lab/evm-input.json \ --status-date 2026-10-21 --rate 50000 --history pm-lab/evm-history.csv
실습 저장소에 위 값을 넣지 않았다면 키트의 예시 파일로 같은 결과를 얻는다: bash github-pm-starter-kit/evm-report.sh github-pm-starter-kit/samples/evm-input.sample.json --status-date 2026-10-21. --rate는 시간당 단가(원)이고, 금액 환산 표를 덧붙인다. --history는 결과 한 줄을 CSV에 덧붙이므로 매주 실행하면 추세가 쌓인다.
5지표 읽기
| 지표 | 값 | 문장으로 바꾸면 |
|---|---|---|
| SPI = EV ÷ PV | 0.51 | 계획한 일의 51%만큼 끝냈다. |
| CPI = EV ÷ AC | 0.76 | 1시간을 써서 추정 0.76시간 분량의 일을 끝내고 있다. 추정보다 1.31배 시간이 든다. |
| EAC = BAC ÷ CPI | 147h | 지금 효율이 이어지면 전체 112시간 추정의 일에 147시간이 든다. 35시간(약 4.4인일) 초과다. |
| TCPI | 1.14 | 112시간 안에 끝내려면 남은 일을 추정보다 14% 빠르게 해야 한다. 지금 CPI 0.76과의 차이가 크다. |
| ES, SV(t) | 4.97일, −3일 | 지금까지 끝낸 양은 계획상 10월 16일(금)까지 끝났어야 할 양이다. 약 3작업일 늦다. |
| 예상 완료일 | 11월 19일 | 지금 속도면 계획 18작업일이 29작업일이 되어 M1 마감(11월 6일)보다 9작업일 늦다. |
마지막 줄이 회의 안건이다. 범위를 줄일지(예: LP-04 알림을 메일 한 가지로), 인력을 더할지, 마감을 옮길지 셋 중 하나를 결정해야 한다. 실습 13의 계산기에서 LP-04를 2일로 줄였을 때 완료일이 2일 앞당겨지는 것을 확인했으므로, 범위 축소 하나로는 9일의 차이를 메우지 못한다는 것도 숫자로 말할 수 있다.
6계산기로 날짜를 움직여 보기
아래 계산기는 evm-report.sh와 같은 식으로 계산한다. 예시 데이터는 Launchpad Sprint 1의 날짜별 기록이므로, 기준일 막대를 움직이면 그날까지의 기록으로 다시 계산한다. 진척률 규칙을 바꾸면 EV가 바뀐다. 실습 저장소에서 만든 pm-lab/evm-input.json을 불러오면 내 Project의 값으로 계산한다.
그래프에서 세 가지를 확인한다. 기준일의 EV 높이에서 왼쪽으로 그은 선이 PV 곡선과 만나는 지점이 획득 일정(ES)이다. 10월 14일 이후 EV 선이 거의 평평한 구간이 LP-03이 막혀 있던 기간이다. AC 선은 EV 선보다 계속 위에 있다. 끝낸 일보다 시간을 더 쓰고 있다는 뜻이다.
7EVM의 한계와 보완
| 한계 | 구체적인 예 | 보완 |
|---|---|---|
| SPI는 끝에 가면 항상 1이 된다 | 예시 데이터의 모든 업무가 11월 10일에 끝났다고 하면 EV = PV = 112h이므로 SPI는 1.00이다. 그러나 계획보다 4작업일 늦었다. | 획득 일정 지표. 같은 경우 SPI(t) = 18 ÷ 22 = 0.82로 지연이 남는다. Walt Lipke가 2003년에 제안했다. |
| 추정이 틀리면 지표도 틀린다 | LP-03을 32시간 대신 48시간으로 추정했다면 같은 결과물에 대해 EV가 달라진다. | Estimate는 계획 회의에서 정하고 바꾸지 않는다. 바꿔야 하면 기준선 변경으로 기록한다. |
| 범위가 늘면 BAC가 바뀐다 | LP-07을 Sprint 1에 넣으면 BAC가 늘어 이전 주의 지표와 비교할 수 없다. | 범위 변경 기록과 함께 새 기준선을 정하고, 추세 파일에 표시한다. |
| 시간 기록 부담 | Actual을 매일 적게 하면 기록이 빠지고 부정확해진다. | 주 1회 누적값만 적는다. AC 없이 SPI와 SPI(t)만 써도 일정 판단은 할 수 있다. |
스크럼 팀은 시간 대신 스토리 포인트와 스프린트 단위로 같은 계산을 할 수 있다. Tamara Sulaiman 등이 2006년에 제안한 AgileEVM이 이 방식이다. 이 과정의 스크립트에서는 Estimate에 포인트를, Start date·Target date에 릴리스 기간을 넣으면 된다.
- Project에 Actual 필드가 있고 LP-01~03에 값이 있다.
evm-report.sh결과에서 SPI, CPI, SPI(t), 예상 완료일을 찾았다.- 계산기에서 진척률 규칙을 바꿔 EV가 어떻게 달라지는지 확인했다.
- 예상 완료일과 M1 마감의 차이를 회의 안건 문장으로 썼다.
pm-lab/evm-history.csv에 한 줄이 기록되었다.
막히면
| 증상 | 확인과 해결 |
|---|---|
오류: Estimate, Start date, Target date가 모두 채워진 업무가 없다. | 실습 13의 cpm-apply.sh를 실행했는지 확인한다. JSON에 "estimate", "start date" 키가 있는지 head -c 600 pm-lab/evm-input.json으로 본다. |
| “계산에서 제외한 업무”가 나옴 | 표에 적힌 필드가 비어 있다. Project 표에서 채운 뒤 JSON을 다시 내려받는다. |
| EV가 예시와 다름 | 체크박스 개수와 Status를 확인한다. 본문의 체크는 - [x]로 저장되어야 한다. |
| 항목이 하나도 없음 | --query의 마일스톤 이름이 다르다. 실습 2의 조회 명령으로 이름을 확인한다. |
--rate는 숫자다 | 쉼표 없이 50000처럼 쓴다. |
마치며...
Estimate, Actual, 완료 조건 체크박스, 기준선 일정으로 PV, EV, AC를 계산했고, 10월 21일의 Launchpad는 SPI 0.51, CPI 0.76, 예상 완료일 11월 19일이라는 결과를 얻었다. 이 결과는 “LP-03이 늦다”는 보고를 “M1까지 9작업일이 모자라 범위, 인력, 마감 중 하나를 결정해야 한다”는 안건으로 바꾼다. 실습 15에서는 공수 추정 없이 과거 처리량만으로 완료 시점의 확률을 계산한다.