Skip to content
Back to skills

Finalize Workitem

ASecurity

Finalize a passed workitem — set status done, stage explicit files, and commit.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 29, 2026
ai-agentsgobashnodegit

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add kohj1018/agentic-dev-harness --skill finalize-workitem --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Finalize Workitem?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Finalize Workitem
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kohj1018-finalize-workitem-agentic-dev-harness/badge)](https://www.skillsdirectory.com/skills/kohj1018-finalize-workitem-agentic-dev-harness)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: finalize-workitem
description: Finalize a passed workitem — set status done, stage explicit files, and commit.
argument-hint: "<task-id> [--apply --rationale \"<why>\"]"
allowed-tools: Read Glob Grep Write Edit Bash(git add *) Bash(git -c core.quotePath=false status *) Bash(git -c core.quotePath=false diff *) Bash(git status *) Bash(git diff *) Bash(git commit *) Bash(pnpm validate) Bash(pnpm validate *) Bash(npm run validate) Bash(npm run validate *) Bash(make validate) Bash(make validate *) Bash(task validate) Bash(task validate *)
---

이 skill은 검증을 통과한 workitem을 마감한다 — status 갱신 + 명시적 파일 add + 커밋. 메인 세션에서 실행한다 — fork 실행은 다른 skill 절차 안에서 Skill 도구로 부를 때의 인자 미전달·background 경쟁 위험이 있어 해제했다(ADR-050 D1의 «finalize fork 유지»를 ADR-076 D6이 개정).

입력:
- `$ARGUMENTS`에는 **task ID 1개**가 들어온다. 여러 ID를 받던 이전 형태는 파싱 규칙이 정의되지 않아 무관 task를 처리한 사례가 관측돼 철회했다 — 여러 task를 함께 마감해야 하면 각각 순차로 호출한다.
  - **task-id sanitization 강제**: `T-[0-9]+` 패턴 정확히 1개만 허용. ID가 0개이거나 2개 이상이면 "task ID 1개만 지정" 안내 후 종료한다(파일·git index 무변경). `/`, 공백, glob 메타문자(`*`, `?`, `[`)가 포함되면 즉시 종료 (`/repair-workitem` 가드와 대칭).
  - **플래그·값과 ID를 분리해 파싱한다**: `--`로 시작하는 토큰과 그 값은 ID 후보에서 제외한다. `--rationale`의 값은 따옴표로 감싼 문자열 *전체*가 하나의 값이며, **그 안에 `T-NNN`이 등장해도 task ID로 해석하지 않는다**.
  - **정의되지 않은 플래그가 있거나, 같은 플래그가 2회 이상이거나, `--rationale` 값이 빈 문자열이면** 추측하지 말고 안내 후 종료한다(파일·git index 무변경).
- 선택 플래그 `--apply` — task 문서 `## 4-1. 변경 예정 파일/경로`와 git 실제 변경이 어긋나도 git 실제 변경을 신뢰하고 진행(아래 5-(4) 차이 처리에서 종료하지 않는다). 단 민감 경로 가드는 그대로 적용된다.
  - **사유 입력 (ADR-007#amend-3)**: `--apply`는 사용자가 **`--rationale "<왜 4-1과 다른지>"`** 를 함께 넘겨야 한다(`$ARGUMENTS` 파싱). finalize는 이 사유를 커밋 body의 `--apply rationale: <...>` 줄에 기록한다. `--apply`인데 `--rationale`이 없으면 **사유를 스스로 만들지 않고** `Needs Rationale`로 종료 + `--rationale` 동봉 재실행 안내(executor가 사유를 발명하면 다시 "자아"가 생긴다).

반드시 먼저 할 일:
1. 관련 task 문서를 읽는다.
1-G. **착수 상태 게이트 (ADR-057#amend-3 결정 5 — `in-progress → done` 입구)**: 읽은 task 문서의 `## 0. Status`를 확인한다 — **`in-progress`일 때만** 아래 단계로 진행한다. `draft`/`ready`(아직 구현 안 함)면 "`/implement-workitem` 먼저 실행" 안내 후 종료(**`ready → done` 건너뛰기 차단** — 구현 없이 validate·finalize만으로 done 방지), `done`이면 read-only no-op("이미 완료" 안내, 파일·git 무변경). **단 `git diff --cached --name-only`에 그 task 문서가 있고 staged diff에 이번 `- closure` 줄이 포함돼 있으면 «커밋 실패 잔존»이다 — 수행 7·8만 다시 수행한다**(검사·편집은 반복하지 않는다. 워킹트리에만 dirty한 done 문서는 accept-milestone receipt 등 정상 상태이므로 건드리지 않는다 — 아래 결정 줄 분기만 예외). **또 산하에 `done`이 아닌 task가 남은 마일스톤(아직 task 층)에서 그 문서에 HEAD에 없는 `- repair-workitem` 결정 줄이 있으면** — done task의 repair가 finding을 전부 기각해 재개방 없이(ADR-057#amend-3 결정 5(e)) 결정 이력을 남긴 상태다 — 둘로 나눈다. (i) **«결정 기록 잔존»**: 그 문서의 `git diff HEAD`가 `## 8`에 줄을 추가한 것뿐이고(`## 0. Status`·다른 절·기존 줄 변경 없음) `git -c core.quotePath=false status --porcelain -uall`에 그 문서 말고 변경이 없으면, 그 문서 하나만 `git add`하고 수행 7·8(커밋 — type `docs`)만 한다. 고친 코드가 없고 재개방·새 마감도 아니므로 통합 명령·report 판정(2·3)과 status·closure 편집(6)은 하지 않는다(ADR-076 D10·D13). 커밋이 실패하면 다음 호출이 같은 판정으로 다시 들어온다. (ii) 그 밖(다른 파일이나 `## 8` 밖의 변경이 함께 있음 — staged 포함)이면 검증을 건너뛸 근거가 없다 — 아무것도 add하지 않고 차이를 출력한 뒤 `Needs Review`로 종료한다. **본 게이트에서 종료하는 경우(위 재개·결정 기록 분기 제외) 파일·git index·`## 0. Status`를 전혀 건드리지 않는다.**
2. 통합 검증 명령(`pnpm validate` / `npm run validate` / `make validate` / `task validate`)이 있으면 실행한다.
   - `--changed` 옵션 지원 시 `validate --changed`로 변경 파일만 빠르게 검증 권장 (ADR-020). full validate는 `/stabilize-milestone`에서 실행.
   - 실패 → `Needs Fix`로 종료. 커밋하지 않음. `/repair-workitem <task-id>`를 텍스트로 제안.
   - **통합 명령이 없을 때 (ADR-007#amend-3)**: `docs/00-meta/STACK_SETUP_PLAN.md`가 존재하면(스택 확정) **`Needs Stack Guard`로 종료** + `/stack-guard` 안내. STACK_SETUP_PLAN.md가 없으면(스택 미정) 이 단계 skip.
3. AC 미충족 점검 — 직전 `/validate-workitem`의 report(`docs/40-validation/reports/<task-id>.md`)의 `## AC ↔ 검증 매핑`이 모두 충족인지 확인한다.
   - report 파일이 없거나 stale(파일 mtime이 task 문서 또는 변경된 구현 파일보다 오래됨)하면 `/validate-workitem <task-id>` 선행을 안내하고 `Needs Validation`으로 종료한다(커밋하지 않음).
   - 미충족 AC가 있으면 **아래 「분기 우선순위」에 따라 판정한다**(여기서 무조건 종료하지 않는다). **`미관측`도 미충족이다.**
   - **`## 6-2. TDD opt-out`은 예외가 아니다 (ADR-065 D2)** — opt-out은 Red-first 절차의 면제이지 AC 충족의 면제가 아니다(ADR-009 `opt-out 절차`). opt-out task는 `[산출물 검사]` 등 다른 modality로 충족해야 통과한다. 단 **출력에는 opt-out 사유와 follow-up task ID를 명시한다**(ADR-009가 요구하는 "finalize 시점 사용자 확인").
   - **분기 우선순위 (반드시 이 순서로 판정한다 — 근거는 report의 `- 판정:` 값이다, ADR-065 D6)**: ① 판정이 **`Needs Fix`** 면 → `Needs Fix`로 종료 + `/repair-workitem <task-id>` 안내(코드로 고칠 것이 있다). ② 판정이 **`Pending Acceptance`** 면 → **통과시킨다.** 그 AC의 receipt는 마일스톤 수용 라운드(`/accept-milestone <M>` — [ADR-066](../../../docs/90-decisions/boilerplate/ADR-066-milestone-acceptance.md) D1)에서 발급되며(ADR-065 D1), 미발급은 졸업 item 4가 잡는다([ADR-068](../../../docs/90-decisions/boilerplate/ADR-068-milestone-closure-and-graduation-v3.md) D3). ③ 판정이 **`Pass`** 면 통과.
   - **②로 통과할 때의 의무 2가지**: (i) 미충족 관측 AC마다 task `## 8`에 `- ac-pending <날짜> <AC-N>: modality=<...> — 마일스톤 수용 라운드에서 확인 예정`을 append한다(같은 AC의 `- ac-pending`이 이미 있으면 중복 append 금지 — **중복 판정은 HTML 주석 밖의 줄만 센다.** TASK_TEMPLATE `## 8` 주석의 형식 예시를 세면 «이미 있다»로 오판해 실제 줄이 영원히 안 남는다). **`## 0. Status`를 `done`으로 쓰는 것과 같은 편집 라운드에서 쓴다**(별도 mtime 갱신을 만들지 않는다). (ii) 마지막 출력에 `수용 라운드 대상 AC: <AC-N 목록>`을 명시하고, 이 마일스톤은 그 receipt 전까지 졸업이 `PENDING_ACCEPTANCE`임을 한 줄 안내한다.
   - **에이전트가 `- ac-acceptance` receipt를 대신 쓰지 않는다**(ADR-065 D1). `- ac-pending`은 receipt가 아니라 미발급 표시이므로 이 금지에 걸리지 않는다.
   - **finalize의 종료값은 `Needs Fix`·`Needs Validation`·`Needs Review`·`Needs Rationale`·`Needs Stack Guard`·`Needs Commit`(수행 8 실패 분기)·정상 마감이다** — 관측 AC 전용 종료값을 따로 두지 않는다(마감을 막지 않으므로 필요 없다).

수행:
4. `git -c core.quotePath=false status --porcelain` / `git -c core.quotePath=false diff --name-only`로 실제 변경 파일을 회수한다(기본 설정은 한글 경로를 8진수로 바꿔 `## 4-1`의 평문 경로와 어긋난다 — ADR-076 D13).
5. 명시적 파일 add — **`git add -A` / `git add .`는 사용하지 않는다**.
   파일 목록 산출 우선순위:
   - **(0) 자동 포함**: 본 skill이 갱신하는 task 문서 자체는 (안전검사 통과 후 status=done을 쓴 뒤) 항상 add 대상에 포함하고, 아래 (1)·(2) 비교에서는 제외한다.
   - **(1) task 문서의 `## 4-1. 변경 예정 파일/경로`** — 있으면 우선 참조. 본 섹션은 task 문서 자체를 다시 적지 않는다(자동 포함됨).
   - **(2) git 실제 변경 파일** — task 문서를 제외한 나머지.
   - **(3) 제외 규칙** — 다음을 add 대상에서 제외:
     - 민감 경로(`.env*`, `secrets/**`, `*.jks`, `*.keystore`, `key.properties`, `*.p12`, `*.mobileprovision`, `*.p8`, `*-firebase-adminsdk-*.json`, `serviceAccount*.json`, `service-account*.json` — 파일명 열거는 완결될 수 없으므로 credential 은 `secrets/` 하위에 두는 것이 경계 있는 통제다) (ADR-059 D9)
     - 빌드 산출물(`node_modules/`, `dist/`, `build/`, `.next/`, `coverage/`)
     - task 범위와 명백히 무관한 파일
   - **(3-lock) lock file 자동 화이트리스트** — TASK_TEMPLATE `## 4-1`에 명시되지 않아도 자동 add 허용 (ADR-007 amend):
     `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lockb`, `Cargo.lock`, `Gemfile.lock`, `composer.lock`, `go.sum`, `Pipfile.lock`, `poetry.lock`, `uv.lock`, `pubspec.lock`
   - **(4) 차이 처리** — 어느 파일을 커밋할지는 추측으로 정하지 않는다(메인 세션 실행이어도 같다 — ADR-076 D6). **(1)에 있지만 지금 변경이 없는 파일은 차이로 보지 않는다** — 이전 라운드에 이미 커밋된 산출물이다(재개방 부분 수리 — ADR-076 D13). (1)과 (2)(둘 다 task 문서 제외 기준)가 어긋나면(또는 (1)이 비어 있고 (2)에 add 대상으로 의심되는 파일이 섞여 있으면) **차이를 출력에 명시하고 즉시 종료**한다(`Needs Review` 종료). **단, (3-lock) whitelist에 해당하는 파일은 (1)에 없어도 차이로 보지 않고 자동 add한다.** 사용자가 task 문서의 `## 4-1`을 갱신하거나 `--apply` force 모드로 재실행하도록 안내한다.
   민감 경로가 staged 영역에 들어오면 즉시 종료한다.
6. staging·안전검사(수행 4-5)가 abort 없이 통과한 뒤에만 task 문서를 갱신한다(커밋 성공 직전 — 검사 중단 시 아무것도 쓰지 않아 "done인데 미커밋" 방지). **아래 둘을 *한 번의 편집*으로 함께 쓴다** — 별도 편집으로 나누면 뒤엣것이 staging 밖에 남을 수 있다.
   - (i) `## 0. Status`를 `done`으로 갱신.
   - (ii) **closure receipt 발급 (ADR-068 D2)** — 「반드시 먼저 할 일 3」에서 읽은 채점표의 결론을 `## 8. 메모`에 한 줄 append.
     ```
     - closure <YYYY-MM-DD> <task-id>: verdict=<Pass|Pending Acceptance> / 기계AC=<충족/전체> / audit=<complete|미완:<축>> / 관측대기=<AC-N 목록|없음> / 자동화율=<%>
     ```
     - `verdict` = 채점표의 `- 판정:` 값 그대로.
     - `기계AC` = `## AC ↔ 검증 매핑`에서 modality가 `[자동 테스트]`·`[산출물 검사]`이거나 표기 부재인 AC의 충족/전체.
     - `audit` = `## Orchestration`의 `감사 미완(unavailable)` 항목이 없으면 `complete`, 있으면 `미완:<축>`.
     - **`관측대기` = task `## 6-1`에서 modality가 `[사용자 관측]`·`[플랫폼 관측]`인 AC 중, `## 8`의 (HTML 주석 밖) 그 AC 마지막 이벤트가 `- ac-acceptance`가 아닌 것 전부** (없으면 `없음`). **«이 라운드에 `- ac-pending`을 남긴 AC»가 아니다** — `- ac-pending`은 `/implement-workitem` 6-R도 쓰고 본 skill은 중복 append를 금지하므로, implement가 이미 남긴 AC는 이 라운드에 append가 0건이 되어 목록이 비고 **receipt 없는 관측 AC가 졸업을 통과한다.** 반드시 `## 6-1`을 직접 스캔한다.
     - `자동화율` = 채점표에 기록된 값.
     - **같은 task에 `- closure` 줄이 이미 있어도 덮어쓰지 않고 append한다** — 마지막 줄이 현재 상태다.
     - **이 줄이 졸업 item 1의 유일한 입력이다.** 채점표는 gitignore된 checkout-local 파일이라 커밋되지 않으므로, 이 줄이 없으면 그 마일스톤은 졸업할 수 없다.
     - 값을 발명하지 않는다 — 채점표에서 읽을 수 없는 칸은 `미상`으로 적고 마지막 출력에 명시한다.
7. 커밋 메시지 초안을 Conventional Commits 스타일로 생성한다(정책: ADR-008).
   - 형식: `<type>(<scope>): <summary>` — `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf` 등.
   - 본문에 변경 요약 한 단락 + task ID 참조.
   - **`--apply` 모드면** body에 사용자가 넘긴 `--rationale` 값을 `--apply rationale: <...>` 한 줄로 포함 (ADR-007#amend-3). `--rationale` 부재 시 `Needs Rationale` 종료(커밋 X).
   - footer에 `Refs: T-NNN (AC-X, AC-Y)` 형식 포함 (ADR-008#amend-2). 누락 시 *footer 추가 권장 텍스트* 출력 — 자동 차단은 하지 않음 (사용자 결정).
8. `git commit -m "..."` 실행.
   - **금지**: `--no-verify`, `--amend`, `git push`.
   - **실패 분기**: `git commit`이 0이 아니면 아무것도 되돌리지 않는다 — staging(수행 5의 파일 + 수행 6의 task 문서)을 그대로 두고 stderr 요약과 함께 `Needs Commit: <원인>`으로 종료한다. 이 상태의 서명은 «task 문서가 staged인데 커밋되지 않음»이며 1-G가 그것으로 재개한다.
9. **feature-완료 감지 (ADR-057 결정 5)**: 직전 단계에서 status를 `done`으로 갱신한 본 task(⚠ 0C-6이 status=done을 커밋 안전검사 뒤로 옮겼으므로 옛 "step 4" 번호에 의존하지 말 것)의 `## 7. 관련 문서` Feature 링크로 같은 feature를 참조하는 sibling task 문서를 Glob/Grep 회수한다. 전원 `## 0. Status` 값이 `done`이면(값은 heading *다음 줄*에 있다 — TASK_TEMPLATE 형식, `Status: done` 인라인 표기가 아니다) 마지막 출력에 **Feature-완료 블록**을 추가한다(본 블록은 ADR-046 압축 대상 아님 — 전량 보존):
   - FAC closure 요약: feature `## 7-1` 매핑표의 각 `T-NNN:AC-N`이 `docs/40-validation/reports/<task-id>.md`에서 ✅인지 (report 부재 task는 "확인 불가 — report checkout-local" degrade).
   - 다음 단계 제안(텍스트만): 다음 의존성 task가 있으면 그 task를 `/implement-workitem`, 마일스톤 전 task가 done이면 `/stabilize-milestone M-N` (refresh·F-NNN 재계획 경로 없음 — ADR-057#amend-3).
   - Feature 링크 부재 시 "feature 소속 불명 — task `## 7` 링크 보강 권장" 1줄만.

마지막 출력:
- 커밋 해시
- 커밋 메시지
- 갱신된 task status
- **수용 라운드 대상 AC**: `[사용자 관측]`·`[플랫폼 관측]`로 미충족 통과시킨 AC-N 목록 + `- ac-pending` append 건수 / 해당없음
- **closure receipt**: append한 `- closure` 줄 전문 (ADR-068 D2)
- 다음 권장 단계 (다음 task로 진행 또는 마일스톤이면 `/stabilize-milestone`)

가드:
- 작업 트리에 변경이 없으면 "변경 없음" 종료.
- `git add -A` / `git add .` 금지.
- 민감 경로 staged 시 즉시 종료.
- `--amend` 금지(--amend는 직전 커밋 변경 — 작업 단위가 흐려진다).
- `--no-verify` 금지(pre-commit hook은 우회하지 않는다).
- `git push`는 사용자 명시 요청 없이 실행하지 않는다.

## Context 정책 (ADR-019)
`반드시 먼저 읽을 파일`은 *최소 충분*. 추가 ADR/architecture 섹션은 task 본문에서 발화 시 인용 — 사전 fork-load 금지.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.