Plan Linter (게이트 1 계획 검증기)은(는) 무엇을 하나요?
이 스킬은 단일하고 엄격하게 제한된 책임을 가집니다: 개발 시작 전에 tasks/ 아래의 계획된 task 계약 및 번들에 대한 게이트 1 결정론적 정적 검증.
- 게이트 1은 이 스킬의 결정론적 스크립트입니다: 빠르고, 오프라인이며, 표준 라이브러리만 사용합니다.
- 게이트 2는 프롬프트 전용 의미론적 리뷰입니다(
review스킬, 폴백으로references/gate-2-review.md사용). - 비목표: plan-linter는 코드를 실행하지 않으며, CI 파이프라인을 구축하거나 실행하지 않으며, AST/코드 복잡도 분석을 수행하지 않으며, 테스트나
03-qa-verification.md에 기록된 QA 복잡도/뮤테이션 증거를 감사하지 않습니다(플레이스홀더 스캔 및 존재 여부 확인만 수행). 모든 CI 파이프라인과 검증 게이트는quality-engineering이 소유하며, 로컬 테스트는qa가 소유합니다.
게이트 1: 결정론적 검사
| 검사 | 기본값 | 재정의 가능 여부 |
|---|---|---|
| 01-contract.md가 존재하고 유효한 메타데이터를 가짐 | 필수 | 아니요 |
| task_id가 디렉토리 이름과 일치 | 필수 | 아니요 |
| task_id가 번들 전체에서 고유 | 필수 | 아니요 |
| touch_files 개수 | 1..3 | max_touch_files |
| estimated_lines | 50..250 | min_diff_lines, max_diff_lines |
| origin_spec_anchor가 #sec-[a-z0-9-]+와 일치 | 필수 | require_anchor |
| adherence_adrs가 최소 하나의 ADR을 나열 | 필수 | require_adrs |
| dod.type_check, dod.lint, dod.test_file | 필수 | 아니요 |
| dod.edge_cases 개수 | 최소 2 | min_edge_cases |
| 02-dev-workspace.md, 03-qa-verification.md, 04-process.md 존재 | 필수 | require_docs |
| 금지된 touch 접두사 | tests/acceptance/ | forbidden_touch_prefixes |
| 01/02/03의 미해결 플레이스홀더 | 차단 | scan_placeholders |
| 03-qa-verification.md 콘텐츠 수준 QA 증거 | 감사하지 않음 (게이트 3) | 아니요 |
| 역방향 토폴로지: 수정 경로는 존재, 생성 경로는 존재하지 않음 | 경고 | check_topology, strict_topology, --repo-root |
| size_class micro: change_id 존재, touch 파일 1개, 더 작은 예산 | micro일 때 필수 | micro_min_diff_lines, micro_max_touch_files |
| change_id가 변경 디렉토리 아래에 열린 제안을 가짐 | --changes-dir가 주어질 때 필수 | --changes-dir |
| 명세 앵커 커버리지 매트릭스 (미커버 섹션) | 보고서; --require-full-coverage 시 오류 | --spec, --coverage-out |
| 명세에 없는 계약 앵커 | 경고; --strict-anchor 시 오류 | --spec |
| 의존성 그래프 | 비순환, 누락된 task 없음 | 아니요 |
모든 것이 검사됩니다; 출력 순서는 안정적입니다.
빠른 시작
# 표준 보고서 또는 기계 판독 가능 JSON
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks --json
# 사용자 정의 설정 또는 레거시 형식
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks --config plan-linter.json
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks --legacy
# 게이트 2 휴리스틱 및 차단 CI 모드
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks \
--repo-root . --spec .specs/02-tech-spec.md --changes-dir .specs/changes --json
python .agents/skills/plan-linter/scripts/plan_linter.py --tasks-dir ./tasks \
--spec .specs/02-tech-spec.md --strict-topology --strict-anchor --require-full-coverage
스크립트는 선택 사항입니다. Python을 사용할 수 없는 경우 references/gate-2-review.md를 수동 체크리스트로 사용하고 동일한 필드를 수동으로 검토하십시오.
게이트 2는 별도의 review 스킬입니다. 게이트 1이 0으로 종료된 후, review 스킬(plan-review 모드)이 설치되어 있으면 이를 사용하여 독립적인 의미론적 감사를 수행합니다. 이 스킬은 references/gate-2-review.md를 review 스킬이 설치되지 않은 경우의 자체 포함 폴백으로 유지합니다; 결코 게이트 1을 대체하지 않습니다.
종료 코드
| 코드 | 의미 |
|---|---|
| 0 | 모든 task 번들에 대해 게이트 1 통과 |
| 1 | 위반 발견 (또는 계약 머리말을 구문 분석할 수 없음) |
| 2 | 사용법 또는 설정 오류 |
| 3 | 예상치 못한 내부 오류 |
계약 형식
01-contract.md의 YAML 머리말이 권위를 가집니다. 아래의 사람이 읽을 수 있는 테이블은 선택적인 가독성 보조 도구입니다.
---
task_id: task-001-auth
title: "사용자 인증"
module: auth
dependencies: [task-000-bootstrap]
estimated_lines: 120
touch_files:
- action: create
path: src/auth/service.py
- action: modify
path: src/auth/routes.py
origin_spec_anchor: "#sec-auth"
adherence_adrs: [ADR-001]
dod:
type_check: "npm run type-check"
lint: "npm run lint"
test_file: "tests/acceptance/test_auth.ts"
edge_cases:
- "빈 자격 증명은 400 반환"
- "만료된 토큰은 401 반환"
---
규칙:
task_id는 task 디렉토리 이름과 같아야 합니다; 경로는 저장소 기준이며 슬래시를 사용합니다.touch_files는 금지된 접두사(기본적으로tests/acceptance/)를 가리킬 수 없습니다.- 01/02/03에 플레이스홀더(
{{...}},[TBD],TODO)를 남기지 마십시오.
레거시 폴백
YAML 머리말이 없는 계약은 v2 이전 레이아웃에 대해 테이블 폴백을 사용하며, LEGACY_FORMAT 경고를 출력합니다. --legacy를 추가하여 폴백을 강제합니다.
설정
{
"max_touch_files": 3,
"min_diff_lines": 50,
"max_diff_lines": 250,
"require_anchor": true,
"require_adrs": true,
"min_edge_cases": 2,
"require_docs": ["02-dev-workspace.md", "03-qa-verification.md", "04-process.md"],
"forbidden_touch_prefixes": ["tests/acceptance/"],
"scan_placeholders": true,
"micro_min_diff_lines": 10,
"micro_max_touch_files": 1,
"check_topology": true,
"strict_topology": false,
"ignore_task_dirs": ["archive"]
}
임계값은 저장소 규칙이지 보편적인 법칙이 아닙니다. 프로젝트별로 재정의하십시오; 알 수 없는 키는 경고를 생성하고, 잘못된 유형의 값은 종료 코드 2를 발생시킵니다.
JSON 출력
{
"gate": "1",
"passed": true,
"tasks_scanned": 3,
"errors": [],
"warnings": [],
"coverage": {
"spec": ".specs/02-tech-spec.md",
"spec_anchors": 3,
"covered": ["#sec-alpha", "#sec-beta"],
"uncovered": ["#sec-gamma"],
"contract_anchors_missing_from_spec": [],
"coverage_ratio": 0.6667
}
}
coverage는 --spec이 전달된 경우에만 존재합니다; --coverage-out은 이를 파일에 기록합니다.
각 오류 객체는 task, code, message, file, line 키를 가집니다. 오류 코드는 안정적인 영어 식별자입니다(예: MISSING_DOC, TASK_ID_MISMATCH, DAG_CYCLE, PLACEHOLDER, TOUCH_FILE_MISSING, FORBIDDEN_TOUCH_FILE, BDD_MISSING_PRECONDITION, BDD_MISSING_ACTION, BDD_MISSING_OUTCOME, BDD_INVALID_SCENARIO, SPEC_SECTION_UNCOVERED). 보관된 제안은 오류 대신 CHANGE_ALREADY_ARCHIVED를 생성하며, ignore_task_dirs(tasks/archive)는 보류 번들로 스캔되지 않습니다. 전체 오류 참조: references/gate-2-review.md.
게이트 2: 의미론적 리뷰 (프롬프트 전용)
게이트 1이 통과되면 references/gate-2-review.md를 따라 독립적인 리뷰어 역할을 합니다. 다음 중 하나로 요약하십시오:
게이트 2 계획 리뷰 통과: 누락 0개, 환각 0개; 또는- 찾기 목록: task 디렉토리, 오염된 필드, 위반된 ADR ID.
게이트 2는 수동입니다: 스크립트는 의미론적 진실성을 판단할 수 없습니다. 리뷰 없이 통과시키지 마십시오.
이식성, 경계 및 비목표
스크립트는 표준 라이브러리만 사용하며, 자신의 디렉토리를 기준으로 상대 경로를 해석하고, 파일을 절대 쓰지 않습니다.
엄격한 경계 및 비목표:
- 코드 실행 없음: DoD 명령, 애플리케이션 코드 또는 테스트 스위트를 절대 실행하지 않습니다.
- CI 오케스트레이션 없음: CI 파이프라인을 구축, 관리 또는 실행하지 않습니다(
quality-engineering소유). - AST 또는 복잡도 분석 없음: 순환 복잡도 $V(G)$를 계산하지 않습니다(
quality-engineering소유). - 테스트 또는 검증 감사 없음: 03 QA 증거를 감사하지 않습니다. 오직 네 문서 존재 확인과 미해결 플레이스홀더 스캔만
03-qa-verification.md를 건드립니다; 복잡도, 베이시스 경로 커버리지 및 뮤테이션 MSI는 게이트 3(quality-engineering/verification_linter.py)이 감사합니다. - 의미론적 판단 없음: 의미론적 진실성을 판단하지 않습니다(게이트 2는 프롬프트 리뷰).
- RBAC 시행 없음: git 기반 RBAC 감사를 대체하지 않습니다.