Files
llm-wiki/vault/40-publish/blog-topics/ci-gate-wiring-vs-policy-ownership-2026-06-20.md
T

5.1 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label, target_audience, inspiration_url, archive_url
title source_type status related_branches related_projects tags created status_label target_audience inspiration_url archive_url
blog-topic / ci-gate-wiring-vs-policy-ownership blog-topic raw
feature-ci-quality-gates-contract
ca-tmpl
blog-topic
ca-tmpl
ci
github-actions
gradle
2026-06-20 ready-for-canonical backend-engineer

blog-topic: ci-gate-wiring-vs-policy-ownership

Layer: raw/blog-topics/ — 작업·트러블슈팅에서 나온 블로그 글감 원석. status_label: captured

Parent / 부모

트리거 / Trigger

글감 / Topic seed

  • 한 줄 요약: CI 품질 게이트를 "배선(wiring)" 과 "정책(policy)" 으로 쪼개면, 20개 게이트를 한 워크플로에 욱여넣지 않고도 소유권이 깨끗해지고 게이트가 silent-pass 하지 않는다.
  • 풀어야 할 질문들:
    • 소유권 분리. vulnerability 스캔의 release-blocking 여부(wiring)와 scanner 선택·severity 임계값(policy)을 왜 다른 owner 가 갖나? → 한 branch 가 둘 다 가지면 정책 변경이 매번 게이트 그래프를 건드려 결합도가 폭증. ca-tmpl 은 .github/ci-gate-matrix.yml(20행 SSOT) + verify-gate-matrix.sh cross-check 로 "표 ↔ 실제 task/test/job" 정합을 매 PR 강제.
    • fan-in 이 차단을 보장하려면. needs + if: success() aggregator 는 상위 실패 시 skipped — 차단 안 됨. always() + needs.*.result 스캔이라야 "1건 실패 → 릴리스 block". (evidence-first: 공식 문서가 보장하는 건 매핑 가능성뿐, 실제 차단은 의도적 실패 잡으로 검증해야.)
    • 위임 게이트의 정직한 표현. owner branch 가 아직 없는 게이트(SBOM/Cosign/SLSA/gitleaks)는 가짜 통과 잡으로 채우지 말고 delegated-pending 으로 명시적으로 미구현 이라 표시 → cross-check 가 개수까지 보고.
  • 독자가 얻어갈 것: "게이트를 늘리는 것" 보다 "게이트가 실제로 막는지 + 누가 그 정책을 소유하는지" 가 본질이라는 관점.

확장 메모 / Expansion notes

  • 곁가지: flaky quarantine 의 14일 sunset 을 Gradle 거버넌스 태스크(verifyQuarantineSunset)로 강제 — @Tag("quarantine") 격리 + repo-루트 레지스트리 + drift/sunset 이중 검사. quarantine 이 영구 주차장 이 되는 걸 빌드가 막는다. (별도 글감 가능.)
  • 대비 사례: .trivyignore suppression 거버넌스(raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20)와 같은 패턴 — "정책 파일 + CI 필드검증 + CODEOWNERS merge 승인" 삼중 통제.

핵심 주장 후보 / Claim candidates

  • 사실 후보:
    • CI gate matrix는 gate wiring과 policy owner를 분리해 기록한다.
    • GitHub Actions fan-in은 always()needs.*.result 확인을 써야 upstream failure가 skipped로 묻히지 않는다.
  • 의견/해석 후보:
    • CI gate의 본질은 gate 수가 아니라 실제 차단 여부와 policy ownership의 분리다.

Outline seed

  1. gate wiring과 policy ownership을 분리하는 이유를 설명한다.
  2. needs + if: success() fan-in의 skipped 함정을 다룬다.
  3. delegated-pending gate를 가짜 green으로 만들지 않는 표현 방식을 정리한다.

Canonical 전환 후보 / Canonical extraction candidates

  • wiki/projects/ca-tmpl/devops-ci-supply-chain-dx.md 후보:
    • CI gate wiring vs policy ownership 글감.
  • 필요한 추가 검증:
    • 실제 workflow fan-in 실패 검증과 matrix cross-check 구현 여부.

Sources / 근거 후보

미해결 / Unknown

  • 아직 확인해야 할 사실: hosted CI에서 fan-in 차단 검증이 수행됐는지.
  • 과장하면 안 되는 부분: delegated-pending gate를 구현 완료 gate처럼 쓰지 않는다.

Decision / 처리 결정

  • 액션: promote-to-canonical
  • 이유: wiki/projects/ca-tmpl/devops-ci-supply-chain-dx.md 에 CI gate wiring과 policy ownership 분리 글감으로 반영했다.
  • 다음 단계: target canonical이 아직 draft 이므로 blogify 전 GitHub Actions fan-in 차단 검증과 delegated-pending 범위를 분리한다.