149 lines
11 KiB
Markdown
149 lines
11 KiB
Markdown
---
|
|
title: Skeleton Governance를 Registry와 Verification으로 닫기
|
|
source_type: blog
|
|
status: verified
|
|
confidence: high
|
|
tags: [blog, ca-tmpl, governance, archunit, testing]
|
|
related_projects: [ca-tmpl]
|
|
last_reviewed: 2026-07-03
|
|
canonical_sources:
|
|
- wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard
|
|
audience: backend-engineer
|
|
target_publish:
|
|
status_label: ready
|
|
---
|
|
|
|
# Skeleton Governance를 Registry와 Verification으로 닫기
|
|
|
|
## Parent / 부모 (필수)
|
|
|
|
- 핵심 canonical: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
- 관련 개념 문서: [[wiki/concepts/skeleton-governance-registry-verification-test-scorecard]] - registry, verification, test taxonomy, scorecard의 일반 배경. 현재 이 글의 구현 사실 근거는 verified project canonical에 둔다.
|
|
|
|
## 타깃 독자 / Target reader
|
|
|
|
- 독자 profile: template skeleton의 품질 기준을 registry, test, gate로 유지하려는 백엔드/플랫폼 엔지니어.
|
|
- 이미 안다고 가정하는 것: Gradle test, ArchUnit, YAML registry, CI gate.
|
|
- 처음 듣는다고 가정하는 것: governance를 규칙 문서가 아니라 owner, registry row, verification mechanism, test taxonomy로 연결하는 방식.
|
|
|
|
## 도입 / Hook
|
|
|
|
Skeleton 프로젝트에서 좋은 규칙을 많이 쓰는 것은 어렵지 않습니다. “application layer는 framework에 의존하지 않는다”, “환경 변수는 registry에 등록한다”, “quarantine test는 만료일을 가진다” 같은 문장을 README에 적으면 됩니다. 문제는 시간이 지난 뒤입니다. 규칙은 남아 있는데 owner가 사라지고, gate matrix는 workflow와 어긋나고, registry row는 코드와 다른 이름을 가리키기 시작합니다.
|
|
|
|
ca-tmpl은 이 문제를 governance 계약으로 다뤘습니다. registry family를 두고, 각 row가 owner와 required test를 갖게 하며, gate matrix가 실제 Gradle task/test/workflow job과 맞는지 검사합니다. 다만 scorecard badge, 11 gate 전체 hosted release-blocking history, 5분 budget 강제 같은 항목은 아직 구현됐다고 말하면 안 됩니다. 이 글은 구현된 registry/verification slice와 계획으로 남은 governance slice를 분리합니다.
|
|
|
|
## 본문 outline / Body outline
|
|
|
|
1. governance는 규칙 목록이 아니라 drift를 줄이는 구조다.
|
|
2. registry는 row owner와 required test를 연결한다.
|
|
3. verification은 matrix와 실제 task/test/job을 대조한다.
|
|
4. test taxonomy는 classpath와 boundary를 지킨다.
|
|
5. scorecard는 아이디어와 자동화 범위를 나눠 말한다.
|
|
|
|
## 본문 / Body
|
|
|
|
governance라는 단어는 무겁지만, skeleton에서 필요한 질문은 단순합니다. “이 규칙을 누가 소유하는가?”, “이 규칙이 깨지면 어떤 테스트가 실패하는가?”, “문서에 적힌 gate가 실제 CI에 남아 있는가?” ca-tmpl은 이 질문에 답하기 위해 registry, verification, test taxonomy, scorecard를 한 묶음으로 기록했습니다.
|
|
|
|
registry 축은 `docs/registries/` 아래의 7개 YAML family에서 시작합니다. `error-codes.yaml`, `env-keys.yaml`, `secrets-classification.yaml`, `headers.yaml`, `mdc-keys.yaml`, `metrics.yaml`, `capabilities.yaml`가 있고, `ContractRegistrySchemaGovernanceTest`가 각 family의 schema owner header, identity column, `owner_branch`, `compatibility_impact`, `required_test` 같은 필드를 확인합니다. 핵심은 registry row가 단순 목록이 아니라 “누가 책임지고 어떤 test가 지키는가”를 담는다는 점입니다.
|
|
|
|
이 registry는 모든 것을 해결하지 않습니다. canonical은 markdown SSOT와 YAML registry의 관계, generated constants/code generator, markdown과 YAML의 full drift gate가 아직 남았다고 구분합니다. 따라서 이 글에서 말할 수 있는 것은 7개 registry artifact와 schema governance test가 존재한다는 사실입니다. registry YAML이 모든 계약의 최종 SSOT라고 말하면 범위를 넘습니다.
|
|
|
|
verification 축은 `.github/ci-gate-matrix.yml`와 `verify-gate-matrix.sh`에서 잘 드러납니다. matrix row에는 gate id, release blocking 여부, owner branch, mechanism, ref, workflow가 들어갑니다. script는 mechanism별로 실제 존재를 확인합니다. `gradle-custom-task`라면 `tasks.register('<ref>')`가 있어야 하고, `contract-test`라면 test class 파일이 있어야 하며, `workflow-job`이라면 workflow에 job id가 있어야 합니다. 문서와 실행 경로가 벌어지는 것을 줄이려는 구조입니다.
|
|
|
|
Gradle 쪽 custom gate도 같은 방향입니다. `verifyEnvKeys`는 `.env`, `application.yml`, `docs/registries/env-keys.yaml` 사이를 맞춥니다. required placeholder가 `.env`에 없거나, `.env`의 `APP_` key가 registry에 없으면 실패합니다. `verifyTrivyignore`, `verifyQuarantineSunset`, `verifyCleanArchitectureDependencies` 같은 task도 같은 계열입니다. 규칙은 글로만 남지 않고 build graph에 들어가야 회귀를 잡습니다.
|
|
|
|
test taxonomy는 boundary를 강제하는 쪽에 가깝습니다. `CleanArchitectureTest`, `DisabledAdapterArchitectureTest`, `NamingConventionTest`, `ProductionClassImportOption`, sample-off source set은 production classpath와 test fixture boundary가 섞이는 것을 줄입니다. Testcontainers integration test도 outbox/idempotency 같은 runtime contract를 검증하는 데 쓰입니다. 다만 canonical은 6 level 전체의 budget 측정과 강제 mechanism이 아직 없다고 명시합니다.
|
|
|
|
scorecard는 더 조심해서 말해야 합니다. ca-tmpl은 binary pass/fail readiness scorecard를 설계했지만, 별도 CI badge나 자동 산출물까지 구현한 것은 아닙니다. 그래서 이 글에서는 scorecard를 “좋은 방향의 governance 모델”로 설명할 수는 있어도, 자동화된 release readiness dashboard가 존재한다고 쓰면 안 됩니다. 현재 구현의 중심은 registry와 verification, 그리고 일부 Gradle/test gate입니다.
|
|
|
|
결국 ca-tmpl의 skeleton governance는 개발자의 선의에만 기대지 않으려는 시도입니다. registry row에 owner와 required test를 붙이고, gate matrix와 실제 task/test/job을 대조하며, architecture boundary를 ArchUnit으로 고정합니다. 구현된 것은 이 정도입니다. 조직 전체 rollout, 장기적 defect 감소, hosted release gate 차단 이력은 아직 별도의 근거가 필요합니다.
|
|
|
|
## 코드 예제 / Code samples (있다면)
|
|
|
|
```yaml
|
|
# 출처: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
# 실제 파일: .github/ci-gate-matrix.yml, ca-tmpl @f6fbd4e196b4
|
|
gates:
|
|
- id: architecture-test
|
|
release_blocking: true
|
|
owner_branch: feature-architecture-enforcement-rules
|
|
mechanism: contract-test
|
|
ref: app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/CleanArchitectureTest.java
|
|
runs_in: ci-quality-gates
|
|
```
|
|
|
|
```java
|
|
// 출처: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
// 실제 파일: app-bootstrap/.../contract/ContractRegistrySchemaGovernanceTest.java, ca-tmpl @f6fbd4e196b4
|
|
private static final List<Registry> REGISTRIES =
|
|
List.of(
|
|
new Registry("error-codes.yaml", "errors", "code"),
|
|
new Registry("env-keys.yaml", "env_keys", "name"),
|
|
new Registry("secrets-classification.yaml", "secrets", "name"),
|
|
new Registry("headers.yaml", "headers", "name"),
|
|
new Registry("mdc-keys.yaml", "mdc_keys", "key"),
|
|
new Registry("metrics.yaml", "metrics", "name"),
|
|
new Registry("capabilities.yaml", "capabilities", "name"));
|
|
```
|
|
|
|
```groovy
|
|
// 출처: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
// 실제 파일: src/build.gradle, ca-tmpl @f6fbd4e196b4
|
|
tasks.register('verifyEnvKeys') {
|
|
description = 'Verifies src/.env covers application.yml placeholders and every APP_ key is registered.'
|
|
|
|
File envFile = file("${rootProject.projectDir}/.env")
|
|
File appYml = file("${rootProject.projectDir}/app-bootstrap/src/main/resources/application.yml")
|
|
File registryFile = file("${rootProject.projectDir}/../docs/registries/env-keys.yaml")
|
|
}
|
|
```
|
|
|
|
```bash
|
|
# 출처: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
# 실제 파일: .github/scripts/verify-gate-matrix.sh, ca-tmpl @f6fbd4e196b4
|
|
# Cross-checks every row of .github/ci-gate-matrix.yml against reality:
|
|
# gradle-custom-task -> a tasks.register('<ref>') exists
|
|
# contract-test -> the <ref> test-class file exists under src/
|
|
# workflow-job -> the <ref> job id exists in .github/workflows/<runs_in>.yml
|
|
```
|
|
|
|
## Sources / 근거 (canonical 인용 필수, derived layer 의무)
|
|
|
|
- [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]] - 이 글의 1차 canonical. registry files, schema governance test, gate matrix, Gradle verification tasks, test taxonomy, scorecard 미자동화 경계를 따른다.
|
|
- [[wiki/concepts/skeleton-governance-registry-verification-test-scorecard]] - 관련 개념 문서. governance/test taxonomy/scorecard의 일반 배경으로만 둔다.
|
|
|
|
## 사실 vs 의견 / Fact vs opinion 구분
|
|
|
|
- 사실: ca-tmpl에는 7개 registry family, `.github/ci-gate-matrix.yml`, `ContractRegistrySchemaGovernanceTest`, registry/gate 관련 contract tests, 여러 Gradle verification task가 존재한다. 근거: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
- 사실: `./gradlew check`가 2026-07-02 기준 통과했고, `verifyCleanArchitectureDependencies`, `verifyEnvKeys`, `verifyQuarantineSunset`, `verifyReadmeCommands`, `verifyTrivyignore`가 canonical에 기록되어 있다. 근거: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
- 사실: scorecard CI badge/auto artifact, 11 gate 전체 hosted release-blocking history, generated constants/code generator 전체, 5분 budget 강제는 구현됐다고 말할 수 없다. 근거: [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]]
|
|
- 의견: skeleton governance는 규칙 문서보다 owner와 verification mechanism을 같이 남길 때 오래 유지된다.
|
|
- 알지 못하는 것: 팀 단위 rollout 효과, 장기 defect 감소율, 실제 release 차단 사례.
|
|
|
|
## 답할 수 있는 범위 / Answer boundary
|
|
|
|
- 자신 있게 답할 수 있는 후속 질문:
|
|
- registry row에 owner와 required test를 두는 이유는 무엇인가?
|
|
- gate matrix와 실제 Gradle/test/workflow를 대조하는 이유는 무엇인가?
|
|
- ArchUnit/test taxonomy가 skeleton governance에서 맡는 역할은 무엇인가?
|
|
- 다음 글로 넘길 부분:
|
|
- scorecard badge와 자동 산출물.
|
|
- multi-team governance process.
|
|
- hosted release gate 차단 이력.
|
|
|
|
## 게시 체크리스트 / Publish checklist
|
|
|
|
- [x] 모든 사실 주장에 canonical 링크 있음
|
|
- [x] 사실 vs 의견 분리 명시됨
|
|
- [x] 금지 마케팅 표현 없음
|
|
- [x] 코드 예제 출처 명시
|
|
- [x] 타깃 독자 가정과 톤 일치
|
|
- [x] `/lint` 통과
|
|
- [ ] 게시 URL 기록 (게시 후):
|
|
|
|
## Related / 관련
|
|
|
|
- 후속 글 후보: [[wiki/blog/ca-tmpl-devops-ci-supply-chain-dx-2026-07-02]]
|
|
- 후속 글 후보: [[wiki/blog/ca-tmpl-sample-fixture-and-adoption-2026-07-02]]
|
|
- 후속 글 후보: [[wiki/blog/ca-tmpl-knowledge-capture-workflow-2026-07-02]]
|