docs(proofline): approve GHCR image publication spec

This commit is contained in:
Hermes Agent
2026-08-10 12:12:10 +09:00
parent c0f36946a3
commit 21f7e7de77
9 changed files with 192 additions and 2 deletions
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0004"
status: active
---
# 검증 성공 이미지에 한정된 GHCR 게시
## Criterion
`main` 또는 `v*` tag push의 정확한 source commit에 대해 repository가 정의한 검증 gate, image build, built-container smoke와 tested-image artifact 생성·전달·checksum·load 검증이 모두 성공한 경우에만 GitHub Actions가 registry login/push 단계에 진입해야 한다. 이 push 전 gate 중 하나라도 실패하면 registry write 없이 fail-closed 해야 한다. push 이후에만 반환되는 digest가 누락되거나 형식이 잘못되면 job은 nonzero로 종료하고 성공 output·summary를 남기지 않아야 하며, 이미 발생한 registry write를 발생하지 않은 것으로 보고해서는 안 된다.
## Verification
- 성공 조건: synthetic workflow fixture에서 모든 push 전 gate가 성공한 경우에만 publish job의 login/push가 실행 가능하고, push가 반환한 유효한 digest가 확인된 경우에만 성공 output과 summary가 생성된다.
- 실패·경계 조건: repository 검증, build, smoke, artifact 생성·upload·download, checksum 비교 또는 load 실패는 login/push 전 nonzero로 종료된다. push 후 digest 누락·형식 오류는 job nonzero와 성공 output·summary 부재로 이어진다.
- 검사 방법: workflow parser 기반 구조 테스트와 publication helper의 recording-runner 단위 테스트로 push 전/후 실패 시점을 분리해 검증하고, `publish.needs` 및 `packages: write`의 publish-job 한정을 정적 검사한다. 실제 최초 GHCR 실행은 별도 승인된 `main` 반영 이후 integration/release evidence로 확인한다.
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0005"
status: active
---
# 검증 이미지와 게시 이미지의 동일성
## Criterion
verify job은 한 번 빌드하여 built-container smoke를 통과한 `trex-core` 이미지를 archive로 export하고 archive bytes의 SHA-256을 기록한 뒤 image archive와 checksum을 immutable workflow artifact로 전달해야 한다. publish job은 download한 archive의 SHA-256을 load 전에 비교하고 일치하는 archive만 load·tag·push해야 한다. publish job에서 source를 다시 checkout하거나 `docker build` 또는 동등한 재빌드를 수행해서는 안 된다.
## Verification
- 성공 조건: smoke가 성공한 local image를 export한 archive의 SHA-256과 publish job이 download한 archive의 SHA-256이 일치하고, checksum 확인 뒤 load된 image가 GHCR tag의 유일한 원본이 된다.
- 실패·경계 조건: archive 또는 checksum 누락, archive byte 변조, checksum 불일치, load 실패, publish job의 checkout·build 또는 별도 source-based image 생성은 registry login/push 전 nonzero로 종료된다.
- 검사 방법: workflow 구조 테스트로 smoke→save→checksum→upload 및 download→checksum compare→load→tag→push 순서를 검사하고, recording-runner 단위 테스트에서 원본·변조 archive fixture를 사용해 mismatch 시 load/login/push가 호출되지 않음을 검증한다.
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0006"
status: active
---
# stable SHA tag와 immutable digest 추적성
## Criterion
모든 성공 게시 이미지는 전체 40자리 lowercase hexadecimal source commit에서 결정적으로 파생된 앞 12자리 lowercase SHA tag와 전체 commit 값을 담은 `org.opencontainers.image.revision` label을 가져야 한다. SHA tag는 source를 찾기 위한 stable selector이며 배포·rollback의 불변 정본은 registry가 반환한 `sha256` digest다. `v*` tag event에서는 같은 loaded image에 해당 Git tag를 추가하지만 이동 가능한 `latest` tag는 게시하지 않아야 하며, workflow output 또는 summary는 GHCR image reference, 64-hex digest와 전체 source commit을 함께 기록해야 한다.
## Verification
- 성공 조건: `main` event는 source commit 앞 12자리 SHA tag를, `v*` event는 같은 loaded image의 SHA tag와 release tag를 생성한다. OCI revision과 summary/output의 image reference·`sha256` digest·전체 source commit이 해당 실행 입력 및 push 결과와 일치한다.
- 실패·경계 조건: source commit 형식 오류, SHA tag 파생 불일치, 빈/형식 오류 digest, source commit 불일치, release tag용 별도 build, `latest` tag 생성 또는 OCI revision 누락은 성공 output·summary를 만들 수 없다. digest 오류가 push 이후 발견되면 job은 nonzero로 종료한다.
- 검사 방법: synthetic `main`/`v*` event와 유효·무효 commit/digest를 publication helper에 입력하는 단위 테스트, Docker image label inspection, workflow의 tag/summary 정적 검사 및 `latest` 생성 금지 회귀 검사를 실행한다.
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0007"
status: active
---
# built-container package 및 entrypoint smoke
## Criterion
GHCR 게시 후보는 source tree가 아니라 실제로 빌드된 image 안에서 `python -c "import trex_core"`와 `trex-core-daemon --help`, `trex-core --help`, `trex-core-reset --help`를 각각 실행하여 package와 세 console entrypoint가 설치되어 있음을 입증해야 한다. 각 probe는 exit code `0`이어야 하며 daemon setup, migration, DB·RabbitMQ·Redis·portfolio-hub·KIS 연결, 실제 주문 또는 credential 해석을 수행해서는 안 된다.
## Verification
- 성공 조건: network가 차단되고 운영 config·credential이 없는 최소권한 container에서 네 probe가 각각 정해진 timeout 안에 exit code `0`으로 끝나며 container가 정리된다.
- 실패·경계 조건: package import 실패, entrypoint 누락, nonzero exit, timeout, 외부 연결 시도 또는 cleanup 실패는 smoke nonzero로 이어지고 image publish를 차단한다. `trex-core-reset` probe에는 `--yes` 또는 config argument를 전달하지 않는다.
- 검사 방법: built image를 대상으로 하는 smoke harness와 recording-runner 단위 테스트로 정확한 네 command, per-command timeout, network 차단, no-config/no-secret 환경, failure propagation 및 cleanup을 검증하고 CI에서 실제 local image smoke를 실행한다.
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0008"
status: active
---
# 운영 설정과 자격증명의 이미지 비포함
## Criterion
`trex-core` Dockerfile은 package 설치에 필요한 `pyproject.toml`과 `trex_core/`만 application source로 copy하고 repository 전체를 copy하지 않아야 한다. `.dockerignore`는 최소한 `.git`, `.env`, `.env.*`, `config/`와 `.proofline/`을 build context에서 제외해야 한다. image filesystem·history·inspect metadata와 export archive에는 운영 per-instance TOML, `.env`, credential, token, private key, 실제 connection string 또는 synthetic canary marker가 없어야 한다. daemon의 필수 config와 secret은 runtime에 read-only mount, secret 또는 environment로만 주입하고, 문서는 digest pin과 이전 digest rollback을 안내하며 `trex-core-reset`을 자동 rollback 절차에 포함하지 않아야 한다.
## Verification
- 성공 조건: 임시 build context의 제외 대상 `.env.ci-canary`에 고정 marker `TREX_SECRET_CANARY_DO_NOT_SHIP`을 둔 상태로 이미지를 빌드해도 marker가 image filesystem, `docker history --no-trunc`, `docker image inspect` 결과와 exported image archive 어디에서도 발견되지 않는다. Dockerfile에는 `COPY .`가 없고 runtime 문서는 외부 주입과 digest rollback 경계를 설명한다.
- 실패·경계 조건: 필수 ignore path 누락, repository 전체 copy, synthetic canary 또는 금지 파일·값이 검사 surface에 존재하면 FAIL이다. helper의 locally captured stdout/stderr에 canary가 노출되거나 rollback 안내가 DB reset·자동 data mutation을 실행하도록 제시해도 FAIL이다.
- 검사 방법: Dockerfile·`.dockerignore` contract test, synthetic canary가 있는 임시 context의 실제 image build, filesystem/history/inspect/export archive scan, helper의 local output 검사와 runtime documentation contract test를 실행한다. 실제 credential이나 실제 운영 connection string은 fixture·명령·evidence에 사용하지 않는다.