docs(proofline): capture issue 57 specification
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: "dcy-0004"
|
||||
status: confirmed
|
||||
---
|
||||
# requester-versioned·runtime-locked image publication
|
||||
|
||||
## Problem
|
||||
|
||||
현재 `.github/workflows/publish-image.yml`은 `main`과 `v*` push 모두에서 GHCR publication을 실행한다. 이 때문에 문서·governance-only `main` commit도 새 registry artifact를 만들며, publication을 요청자가 선택한 release version과 분리해서 통제할 수 없다.
|
||||
|
||||
repository verification은 `uv sync --extra dev --locked`를 사용하지만 현재 `Dockerfile`은 `pyproject.toml`만 복사한 뒤 `pip install .`을 실행한다. 따라서 CI 검증 환경과 built image의 runtime dependency graph가 동일한 repository-owned `uv.lock` resolution을 사용한다는 보장이 없다.
|
||||
|
||||
이 Discovery는 기존의 single build, built-image smoke, image ID, archive SHA-256, canary scan, OCI source revision, rebuild 없는 publish와 multi-tag same-digest 계약을 유지하면서 publication authority를 strict requester-selected version tag로 제한하고 runtime dependency identity를 lockfile에 결속한다.
|
||||
|
||||
## Evidence
|
||||
|
||||
- GitHub issue #57 `https://github.com/fourblocks2020/trex-core/issues/57`은 requester-versioned·runtime-locked publication 변경과 완료 조건을 기록한 원본 제안이다.
|
||||
- 요청자는 모든 OQ에서 정확히 하나의 선택지를 선택한 뒤 이슈 본문 갱신과 Discovery 승인을 명시적으로 지시했다.
|
||||
- 승인 결정에 따라 `vX.Y.Z` Git tag는 container publication version authority이며 `pyproject.toml`의 `[project].version`과 독립적이다. 두 값을 일치시키는 검증이나 package version 변경은 요구하지 않는다.
|
||||
- 승인 결정에 따라 별도 비게시 CI를 추가하지 않는다. full Ruff와 full pytest는 strict version-tag publication gate에서 실행하고, 일반 `main`/branch push에는 이 Discovery가 별도 CI workflow를 추가하지 않는다.
|
||||
- 조사 기준 source revision은 `1a2b50072238ea72186d99b3ec951fc9511100aa`이며 조사 시 `main`과 `origin/main`은 동기화되어 있고 worktree는 clean이었다.
|
||||
- `.github/workflows/publish-image.yml`은 현재 `main`과 `v*` push를 모두 trigger로 사용하고, exact `github.sha` checkout 후 `uv sync --extra dev --locked`, full Ruff, full pytest, single Docker build, built-image smoke, image ID 기록, archive export·canary scan·SHA-256 기록과 immutable artifact handoff를 수행한다. 별도 publish job만 `packages: write`를 가지며 tested artifact를 재빌드 없이 게시한다.
|
||||
- `Dockerfile`은 현재 `pyproject.toml`과 `trex_core/`만 copy한 뒤 `pip install --no-cache-dir .`을 실행하므로 `uv.lock`을 runtime dependency installation input으로 사용하지 않는다.
|
||||
- `scripts/image_release.py::release_tags()`는 현재 `refs/heads/main`을 허용하고 `v`로 시작하는 넓은 tag 형식을 허용한다. publish helper는 archive checksum, tested/loaded image ID, OCI revision, registry credential 경계, 두 tag의 same-digest와 성공 evidence 생성을 검증하지만 strict `vX.Y.Z` event만 허용하지는 않는다.
|
||||
- `tests/release/test_image_contracts.py`는 현재 `main`/`v*` trigger와 Dockerfile의 기존 COPY allowlist를 고정하고 있어 승인된 trigger·runtime lock 계약에 맞춰 변경해야 한다.
|
||||
- `docs/operations.md`는 source-derived tag를 stable selector로, registry digest를 immutable deployment/rollback identity로 설명하고 runtime config·secret 외부 주입 및 reset 분리 경계를 보존한다. version tag 생성·push가 별도 사용자 승인 외부 쓰기라는 절차는 아직 설명하지 않는다.
|
||||
- 기존 active AC 중 AC-0004는 `main` 또는 `v*` event의 verification-gated publication, AC-0006은 source tag·release tag·digest 추적성, AC-0008은 Docker COPY allowlist와 secret/config 비포함을 소유한다. AC-0005의 tested-artifact identity와 AC-0007의 built-container smoke는 이번 변경에서도 의미를 유지한다.
|
||||
- 비교 기준 `trex-mega-swing-v2` revision `88e90caea7e4ab740ed785fc1f57aed8b6f2da5f`의 workflow는 strict `vX.Y.Z` tag-only trigger, event/ref/commit fail-closed validation, exact tagged commit checkout, locked verify, single build와 tested-artifact publication을 사용한다. workflow run `31468042611`은 `v0.1.0` tag에서 성공했다.
|
||||
- 기준 revision에서 `proofline validate`는 exit `0`, `uv run ruff check .`은 `All checks passed!`, `uv run pytest -q`는 `1040 passed, 51 skipped`를 반환했다. skip은 환경 의존 integration 경계이며 현재 repository baseline이 승인된 변경을 이미 구현했다는 의미는 아니다.
|
||||
|
||||
## Scope
|
||||
|
||||
- AC admission은 기존 동작의 권한·식별자·build input을 변경하는 `update`와 새로운 runtime lock 동작을 정의하는 `create`다.
|
||||
- `update`: AC-0004의 publication event를 일반 `main`/`v*`에서 strict version-tag-only로 변경하고 malformed/non-version event가 registry credential·write 전에 실패하도록 한다.
|
||||
- `update`: AC-0006에 strict requester-selected `vX.Y.Z` version tag, source-derived tag와 version tag의 same-digest, version을 포함한 publication evidence를 반영한다.
|
||||
- `update`: AC-0008의 좁은 Docker build input allowlist에 repository-owned `uv.lock`과 locked installation에 필요한 도구만 추가하면서 기존 config·credential·canary 비포함 경계를 보존한다.
|
||||
- `create`: repository verification과 runtime image가 동일한 repository-owned lock resolution을 사용하고 lock mismatch 또는 unlocked runtime install을 거부하는 독립적인 장기 AC를 추가한다.
|
||||
- AC-0005의 tested-artifact identity와 AC-0007의 built-container package·entrypoint smoke는 변경 없이 유지한다.
|
||||
- GHCR publication workflow의 유일한 trigger는 requester가 exact source commit에 생성·push한 strict `vX.Y.Z` tag다. 각 숫자 구성요소는 `0` 또는 leading zero가 없는 non-negative decimal integer여야 하며 prerelease/build suffix, malformed tag, branch ref와 non-push event는 허용하지 않는다.
|
||||
- workflow는 event·ref·40자리 lowercase source commit을 registry credential 사용 전에 fail-closed로 검증하고, exact tagged commit을 checkout했음을 다시 확인한다.
|
||||
- version tag는 container publication identity이며 `pyproject.toml`의 `[project].version`과 독립적으로 취급한다. package version 일치 검사, 자동 version 증분과 package metadata 변경을 수행하지 않는다.
|
||||
- 일반 `main`과 branch push는 registry login, `docker push`, `packages: write` 또는 image publication을 수행하지 않는다. 요청자 결정에 따라 이번 Scope는 일반 `main`/branch push를 위한 별도 비게시 CI workflow를 추가하지 않는다.
|
||||
- 허용된 version-tag event는 exact source checkout 후 pinned `uv`와 repository-owned `uv.lock`으로 full Ruff와 full pytest를 실행하고, 성공한 경우에만 이미지를 한 번 빌드한다.
|
||||
- Docker build는 `pyproject.toml`, `uv.lock`과 allowlisted package source로 runtime environment를 `uv sync --locked --no-dev --no-editable` 또는 의미상 동등한 locked 방식으로 설치한다. lock mismatch, missing lockfile 또는 lock을 우회한 runtime dependency install은 build/publication 전에 실패한다.
|
||||
- 동일한 tested image에 `:<source-commit-first-12>`와 `:vX.Y.Z`를 부여하고 두 tag가 동일한 registry digest를 가리키는지 확인한다. immutable deployment·rollback identity는 `@sha256:<digest>`다.
|
||||
- 기존 `scripts/image_release.py`의 archive checksum, tested/loaded image ID, OCI revision, canary surface scan, no-rebuild publication, registry credential 경계와 multi-tag same-digest 검증을 유지한다.
|
||||
- `latest`를 생성하지 않으며 성공 evidence에는 source revision, immutable image reference, digest와 selected version tag를 함께 기록한다.
|
||||
- workflow contract와 helper tests는 일반 branch/main non-publication, strict event validation, exact checkout, lock mismatch, locked runtime build, same-digest tags, no-`latest`, no-rebuild 및 기존 failure boundaries를 검증한다.
|
||||
- operator documentation은 version 선택과 Git tag 생성·push가 구현과 분리된 사용자 승인 외부 쓰기이고, tag push가 verify/publication을 시작한다는 점을 설명한다.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 이 Discovery 또는 후속 구현 중 concrete version 선택, version tag 생성·push, 최초·후속 GHCR package write, production deployment 또는 운영 서버 pull/restart
|
||||
- 일반 `main`/branch push를 위한 별도 lint/test CI workflow 신설 또는 기존 publication workflow 외 CI 정책 변경
|
||||
- `pyproject.toml` package version 변경, version tag와 package version의 일치 강제 또는 자동 version 증분
|
||||
- 기존 published tag·digest 삭제, 이동 또는 registry retention 변경
|
||||
- live credential, 실제 account·database·RabbitMQ·Redis·KIS·portfolio-hub 연결, database migration/reset 또는 운영 데이터 변경
|
||||
- image signing, SBOM, provenance attestation, multi-architecture build와 moving `latest`
|
||||
- 다른 TREX repository의 workflow, image 또는 release policy 변경
|
||||
|
||||
## Risks and Unknowns
|
||||
|
||||
### Risks
|
||||
|
||||
- trigger 변경 후 일반 `main` push는 새 runtime image뿐 아니라 현재 publication workflow가 제공하던 full Ruff/pytest도 실행하지 않는다. 이는 요청자가 선택한 정책이며, branch protection 또는 지속적 검증이 필요해지면 registry 권한이 없는 별도 CI 변경으로 다룬다.
|
||||
- version tag와 package version을 독립적으로 두면 image `:vX.Y.Z`와 installed Python package metadata version이 다를 수 있다. container publication version authority는 Git tag임을 문서화하고, package version synchronization이 필요해지면 별도 변경으로 다룬다.
|
||||
- GitHub trigger glob만으로는 malformed `v*.*.*`를 모두 배제할 수 없다. workflow 내부 helper가 strict ref/event/commit을 registry credential 전에 재검증해야 한다.
|
||||
- Docker build가 lockfile을 copy만 하고 실제 runtime install에 소비하지 않으면 CI lock PASS만으로 runtime reproducibility를 주장할 수 없다. build contract와 tests가 locked runtime command 및 mismatch failure를 직접 검증한다.
|
||||
- version tag와 source-derived tag를 별도 build에서 만들면 같은 release identity가 서로 다른 image를 가리킬 수 있다. 단일 tested artifact를 재빌드 없이 두 tag로 push하고 registry digest equality를 확인한다.
|
||||
- 기존 commit-derived selector와 immutable digest는 보존해야 하며 migration 과정에서 과거 tag를 삭제하거나 이동하지 않는다.
|
||||
- tag 생성·push는 즉시 publication workflow와 registry write를 유발할 수 있다. operator 문서가 이를 별도 사용자 승인 외부 쓰기로 명시하고 구현·테스트 중 실제 tag push를 금지한다.
|
||||
|
||||
### Approval State
|
||||
|
||||
- Discovery status: `confirmed`
|
||||
- 승인 근거: 요청자가 이슈의 모든 OQ에서 하나의 선택지를 명시적으로 선택한 뒤 이슈 본문 업데이트와 승인을 지시했다.
|
||||
- 채택 결정: version tag와 package version은 독립적으로 취급하며, 일반 `main`/branch push용 별도 비게시 CI는 추가하지 않는다.
|
||||
- 추가로 필요한 제품 결정: 없음
|
||||
- 이 승인은 Discovery 범위 확인이며 Requirement/AC 승인, 구현, tag 생성·push, GHCR publication, delivery, release 또는 deployment 완료를 의미하지 않는다.
|
||||
@@ -0,0 +1,59 @@
|
||||
# 구현 완료 evidence
|
||||
|
||||
이 파일은 ProofLine canonical lifecycle artifact가 아닌 GitHub issue comment 원문 evidence입니다. 기록된 구현·테스트 결과는 로컬 기능 브랜치의 사후 증거이며 ProofLine delivery closure, publication, release 또는 deployment 완료를 의미하지 않습니다.
|
||||
|
||||
- Source URL: https://github.com/fourblocks2020/trex-core/issues/57#issuecomment-5290864375
|
||||
- Comment ID: `5290864375`
|
||||
- Node ID: `IC_kwDOSvywKc8AAAABO1wu9w`
|
||||
- Author: `genichin`
|
||||
- Created at: `2026-08-14T07:47:03Z`
|
||||
- Updated at: `2026-08-14T07:47:03Z`
|
||||
- Original body SHA-256: `2a57a0b702957cb534cc9aa35e08618e76e38d9da5d1926e8055f84973783b51`
|
||||
- Captured from GitHub API: `2026-08-14T16:51:15+09:00`
|
||||
|
||||
## Original Comment Body
|
||||
|
||||
<!-- BEGIN ORIGINAL COMMENT BODY -->
|
||||
## 구현 완료
|
||||
|
||||
승인된 #57 범위의 requester-versioned·runtime-locked image publication 구현과 독립 검증을 완료했습니다.
|
||||
|
||||
### 구현 내용
|
||||
|
||||
- GHCR publication trigger를 strict `vX.Y.Z` tag push로 제한하고 일반 `main`/branch push, non-push event, malformed·leading-zero·prerelease/build tag를 fail-closed 처리
|
||||
- exact `${GITHUB_SHA}` checkout 후 실제 `git rev-parse HEAD`를 다시 비교하여 source identity 검증
|
||||
- Git tag version을 `pyproject.toml` package version과 독립적인 container publication authority로 유지
|
||||
- Docker runtime dependency 설치가 repository-owned `uv.lock`을 실제로 소비하도록 `uv sync --locked --no-dev --no-editable` 적용
|
||||
- 기존 full Ruff·full pytest publication gate와 single build, built-image smoke, tested image ID, archive SHA-256, canary scan, OCI revision, no-rebuild publish 계약 보존
|
||||
- source-derived tag와 version tag를 같은 tested image에 부여하고 동일 registry digest를 가리키는지 검증
|
||||
- 성공 output·summary에 immutable image reference, digest, source commit과 selected version tag를 함께 기록하고 `latest` 생성 금지
|
||||
- operator documentation에 version tag 생성·push가 구현과 분리된 별도 사용자 승인 외부 쓰기임을 명시
|
||||
- 초기 후보의 checkout 재검증·version evidence 누락을 별도 후속 커밋에서 보완하여 이력을 보존
|
||||
|
||||
### 검증 결과
|
||||
|
||||
Release 집중·전체 회귀, 정적 검사, ProofLine validation, Docker build/smoke와 독립 read-only 리뷰를 모두 통과했으며 승인 차단 finding은 없습니다.
|
||||
|
||||
- 최종 HEAD: `e3fa8243d926efd0b81463dbfc5403cf6e4889f9`
|
||||
- 최종 tree: `ea05e23139965abed1f6a454c4ca2b5d356f8ab9`
|
||||
- Release 집중 테스트: `75 passed`
|
||||
- 전체 테스트: `1065 passed, 51 skipped`
|
||||
- 전체 Ruff: `All checks passed!`
|
||||
- `proofline validate`: exit `0`
|
||||
- `git diff --check`: PASS
|
||||
- checkout mismatch fail-closed 실동작: PASS
|
||||
- Docker build, built-image smoke, image ID, archive export·checksum, canary scan: PASS
|
||||
- image user `10001:10001`, `trex-core-daemon` entrypoint와 OCI source revision 확인
|
||||
- 독립 read-only 리뷰: **PASS**, `mutation=false`, 승인 차단 finding 없음
|
||||
- 기능 브랜치 `feat/issue-57-versioned-locked-publication`과 worktree: clean
|
||||
|
||||
### 비차단 후속 권고
|
||||
|
||||
- `TREX_POSTGRESQL_TEST_DSN`이 준비되면 PostgreSQL integration 41건을 실제 DB에서 재실행
|
||||
- `TREX_RABBITMQ_TEST_URL`이 준비되면 RabbitMQ integration 9건을 재실행
|
||||
- 안전한 KIS sandbox credentials가 준비되면 sandbox integration 1건을 재실행
|
||||
- 로컬에 `actionlint`를 마련하거나 향후 GitHub workflow 실행에서 Actions-level YAML·shell 해석을 추가 확인
|
||||
- version tag 생성·push와 GHCR publication은 별도 사용자 승인 후 수행하고, 게시 결과의 source/version tag가 동일 digest를 가리키는지 실제 registry evidence로 확인
|
||||
|
||||
> 현재 상태는 **격리 기능 브랜치의 로컬 구현·검증·커밋 완료**입니다. push·PR·main 반영·version tag 생성·GHCR 게시·배포·릴리스 완료를 의미하지 않습니다.
|
||||
<!-- END ORIGINAL COMMENT BODY -->
|
||||
@@ -0,0 +1,63 @@
|
||||
# 구현 진행 상황 evidence
|
||||
|
||||
이 파일은 ProofLine canonical lifecycle artifact가 아닌 GitHub issue comment 원문 evidence입니다. 기록된 구현·테스트 결과는 로컬 기능 브랜치의 사후 증거이며 ProofLine delivery closure, publication, release 또는 deployment 완료를 의미하지 않습니다.
|
||||
|
||||
- Source URL: https://github.com/fourblocks2020/trex-core/issues/57#issuecomment-5290665935
|
||||
- Comment ID: `5290665935`
|
||||
- Node ID: `IC_kwDOSvywKc8AAAABO1knzw`
|
||||
- Author: `genichin`
|
||||
- Created at: `2026-08-14T07:22:00Z`
|
||||
- Updated at: `2026-08-14T07:41:51Z`
|
||||
- Original body SHA-256: `c9631a1402a51de699676a4d8791c206e9b6f4e197d134e16027cdc179f96c5f`
|
||||
- Captured from GitHub API: `2026-08-14T16:51:15+09:00`
|
||||
|
||||
## Original Comment Body
|
||||
|
||||
<!-- BEGIN ORIGINAL COMMENT BODY -->
|
||||
## 구현 진행 상황
|
||||
|
||||
- **대상:** [Discovery] requester-versioned·runtime-locked image publication
|
||||
- **브랜치:** `feat/issue-57-versioned-locked-publication`
|
||||
- **기준:** `main` (`1a2b50072238ea72186d99b3ec951fc9511100aa`)
|
||||
- **상태:** 🟢 로컬 구현·검증 완료 — 독립 리뷰 PASS
|
||||
- **최종 업데이트:** 2026-08-14 16:41:50 KST
|
||||
|
||||
### 구현 계획 및 작업 목록
|
||||
|
||||
- [x] **1. 기존 게시 안전장치와 변경 영향 범위 확인**
|
||||
- tag trigger, 검증 순서, tested-image handoff, digest·canary·secret 경계와 기존 회귀 테스트를 기준선으로 고정합니다.
|
||||
- [x] **2. 요청자 버전 태그 전용 게시 흐름 구현**
|
||||
- strict `vX.Y.Z` tag push만 허용하고 일반 `main`/branch push와 malformed event는 registry write 전에 차단합니다.
|
||||
- [x] **3. 컨테이너 runtime dependency lock 적용**
|
||||
- repository의 `uv.lock`을 실제 runtime 설치에 사용하고 lock mismatch·unlocked 설치를 fail-closed 처리합니다.
|
||||
- [x] **4. 이미지 식별자·게시 근거와 운영 문서 갱신**
|
||||
- source tag와 version tag의 same-digest, no-`latest`, source/version/digest evidence 및 tag push 승인 경계를 반영합니다.
|
||||
- [x] **5. 회귀 테스트와 전체 검증 수행**
|
||||
- release contract 집중 테스트, 전체 Ruff, 전체 pytest, ProofLine validation과 가능한 local image build/smoke를 실제 실행합니다.
|
||||
- [x] **6. 독립 검토와 최종 구현 근거 정리**
|
||||
- 구현자와 분리된 read-only 검토를 받고, 반려 시 보완·재검증한 뒤 최종 commit과 검증 결과를 기록합니다.
|
||||
|
||||
### 진행 기록
|
||||
|
||||
- 승인된 #57 Discovery 본문과 OQ 결정(A: package version 독립, B: 일반 main/branch용 별도 CI 미추가)을 구현 범위의 기준선으로 고정했습니다.
|
||||
- 격리 worktree와 기능 브랜치를 `1a2b50072238ea72186d99b3ec951fc9511100aa`에서 생성했습니다.
|
||||
- 기준선 확인 완료: 기존 workflow의 single build→smoke→image ID→archive checksum/canary scan→tested artifact handoff→no-rebuild publish와 publish-job-only `packages: write` 경계를 확인했습니다.
|
||||
- AC 영향 범위 확인: AC-0004·AC-0006·AC-0008 update, runtime lock AC create, AC-0005·AC-0007 유지 경계로 고정했습니다.
|
||||
- 변경 전 기준선 검증: `proofline validate` PASS, 전체 Ruff PASS, 전체 pytest `1040 passed, 51 skipped`; 기준 branch와 worktree는 clean입니다.
|
||||
- version tag 생성·push, GHCR publication, PR, main 반영, release와 deployment는 수행하지 않습니다.
|
||||
- 초기 구현 commit `cb8fcee226ab71f522fe1bbef35d60197947850c` 생성: strict tag-only trigger와 runtime `uv.lock` 설치, 기존 release safety contract 및 운영 문서 변경을 포함합니다.
|
||||
- 초기 후보 검증: release 집중 `71 passed`, 전체 `1061 passed, 51 skipped`, Ruff·ProofLine·diff check PASS. skip은 PostgreSQL 41건, RabbitMQ 9건, KIS sandbox 1건입니다.
|
||||
- 팀장 diff 검토에서 승인 계약 누락 2건을 확인해 최종 완료를 보류했습니다: (1) checkout 후 실제 `HEAD == GITHUB_SHA` 재검증 없음, (2) 성공 output/summary에 selected version tag evidence 없음.
|
||||
- 위 2건은 계획 변경이 아니라 승인된 #57의 결함 보완이며, 초기 후보 위에 별도 수정 commit을 만들고 전체 검증·독립 리뷰를 다시 수행합니다.
|
||||
- 보완 commit `e3fa8243d926efd0b81463dbfc5403cf6e4889f9` 생성: checkout HEAD 재검증과 selected version tag output/summary evidence를 추가했고 초기 커밋은 보존했습니다.
|
||||
- 팀장 최종 후보 재검증: release 집중 `75 passed`, 전체 `1065 passed, 51 skipped`, Ruff·ProofLine·diff check PASS, checkout mismatch fail-closed 실동작 확인.
|
||||
- Docker 재검증: built-image smoke, image ID, archive export/checksum, canary scan PASS; non-root `10001:10001`, daemon entrypoint와 OCI revision을 확인했습니다.
|
||||
- 구현·검증 항목 2~5를 완료했으며, 최종 후보 `e3fa824`에 고정한 독립 read-only 리뷰를 진행합니다.
|
||||
- 독립 read-only 리뷰 최종 **PASS** (`mutation=false`, target `e3fa8243d926efd0b81463dbfc5403cf6e4889f9`): release `75 passed`, 전체 `1065 passed, 51 skipped`, Ruff·ProofLine·diff check PASS, 승인 차단 finding 없음.
|
||||
- skip 분류: PostgreSQL integration 41건(DSN 없음), RabbitMQ integration 9건(URL 없음), KIS sandbox 1건(credentials 없음).
|
||||
- 독립 리뷰의 비차단 참고: 새 review environment는 `uv sync --extra dev --locked` 후 검증했으며, candidate Docker build/registry write는 리뷰에서 수행하지 않았습니다. Docker contract는 구현자와 팀장이 별도로 실제 build/smoke/scan으로 확인했습니다.
|
||||
- 최종 기능 브랜치 HEAD와 tree는 각각 `e3fa8243d926efd0b81463dbfc5403cf6e4889f9`, `ea05e23139965abed1f6a454c4ca2b5d356f8ab9`; worktree clean. 임시 detached review worktree는 검토 후 정리했습니다.
|
||||
- 현재 완료 경계는 격리 기능 브랜치의 로컬 구현·검증·커밋입니다. push, PR, main 반영, tag 생성·push, GHCR publication, release와 deployment는 수행하지 않았습니다.
|
||||
|
||||
> 각 작업이 실제로 완료되고 검증될 때마다 이 댓글의 체크박스와 진행 기록을 갱신한다. 체크 표시는 구현 완료 또는 해당 검증의 실제 통과를 의미하며, 배포·릴리스 완료를 의미하지 않는다.
|
||||
<!-- END ORIGINAL COMMENT BODY -->
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
id: "line-0004"
|
||||
---
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: "req-0004"
|
||||
status: approved
|
||||
discovery: "dcy-0004"
|
||||
criteria:
|
||||
create:
|
||||
- "ac-0014"
|
||||
update:
|
||||
- "ac-0004"
|
||||
- "ac-0006"
|
||||
- "ac-0008"
|
||||
retire: []
|
||||
satisfy: []
|
||||
---
|
||||
|
||||
# requester-versioned·runtime-locked image publication
|
||||
|
||||
## Objective
|
||||
|
||||
GHCR image publication authority를 요청자가 exact source commit에 생성·push하는 strict `vX.Y.Z` Git tag로 제한하고, repository verification과 container runtime installation이 동일한 repository-owned `uv.lock` resolution을 사용하게 한다. 기존의 검증 선행, single build, built-image smoke, tested artifact identity, canary·secret 방어, no-rebuild publication과 multi-tag same-digest 계약은 유지한다.
|
||||
|
||||
## Scope
|
||||
|
||||
- GHCR publication workflow의 유일한 trigger를 strict `vX.Y.Z` tag push로 제한한다. 숫자 구성요소는 `0` 또는 leading zero 없는 non-negative decimal integer이며 prerelease/build suffix, malformed tag, branch ref와 non-push event를 거부한다.
|
||||
- event, ref와 40자리 lowercase source commit을 registry credential 또는 write 전에 fail-closed로 검증하고, exact `${GITHUB_SHA}` checkout 뒤 실제 `HEAD`를 다시 비교한다.
|
||||
- strict version-tag event에서 pinned `uv`와 repository-owned `uv.lock`으로 full Ruff와 full pytest를 실행하고, 성공한 경우에만 이미지를 한 번 빌드한다.
|
||||
- 일반 `main`과 branch push에서는 registry login, `docker push`, `packages: write`와 image publication을 수행하지 않으며, 요청자 결정에 따라 별도 비게시 CI workflow를 추가하지 않는다.
|
||||
- Docker runtime environment는 `pyproject.toml`, `uv.lock`과 allowlisted package source만으로 `uv sync --locked --no-dev --no-editable` 또는 의미상 동등한 locked install을 수행한다. missing/mismatched lockfile 또는 unlocked install은 build/publication 전에 실패한다.
|
||||
- single built image에 source commit 앞 12자리 tag와 selected `vX.Y.Z` tag를 부여하고 두 push 결과가 동일 digest인지 확인한다. `latest`는 생성하지 않는다.
|
||||
- archive checksum, tested/loaded image ID, OCI revision, built-image package·CLI·migration smoke, canary surface scan, artifact handoff와 publish-job-only registry credential 경계를 유지한다.
|
||||
- push 성공과 digest 검증 뒤에만 immutable image reference, digest, 전체 source commit과 selected version tag를 output·summary evidence로 기록한다. push 후 오류를 registry write 미발생으로 표현하지 않는다.
|
||||
- operator documentation은 container publication version authority가 Git tag이고 package metadata version과 독립임을 설명하며, version 선택과 tag 생성·push가 구현·검증과 분리된 requester-approved external write임을 명시한다.
|
||||
- workflow/parser/helper/Docker contract tests는 strict trigger, exact checkout, lock mismatch, locked runtime install, same-digest/no-`latest`, no-rebuild와 기존 실패 경계를 독립적으로 검증한다.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Git tag version과 `pyproject.toml`의 `[project].version`을 일치시키거나 자동 증분하지 않는다.
|
||||
- 기존 commit-derived selector와 immutable digest를 보존하고 기존 published tag·digest를 삭제하거나 이동하지 않는다.
|
||||
- repository 전체를 Docker build input으로 copy하지 않으며 runtime config, `.env`, credential, private key, 실제 connection string, ProofLine artifact와 synthetic canary를 image에 포함하지 않는다.
|
||||
- package write permission과 registry credential은 검증 job이 아닌 gated publish job에만 부여한다.
|
||||
- 실제 account·database·RabbitMQ·Redis·KIS·portfolio-hub 연결, 운영 migration/reset과 다른 TREX repository 계약을 변경하지 않는다.
|
||||
- Normative Design Documents: 없음. 이 REQ와 active AC가 normative specification을 소유한다.
|
||||
|
||||
### Current Implementation Assessment
|
||||
|
||||
- 이 문서는 이미 로컬 기능 브랜치에서 구현된 GitHub issue #57을 현재 ProofLine schema에 사후 명세화한 것이다. 과거 구현이 ProofLine delivery chronology를 따랐다는 뜻이 아니다.
|
||||
- 구현은 `feat/issue-57-versioned-locked-publication`의 local commit `e3fa8243d926efd0b81463dbfc5403cf6e4889f9`(tree `ea05e23139965abed1f6a454c4ca2b5d356f8ab9`)에 있으며, baseline `1a2b50072238ea72186d99b3ec951fc9511100aa` 위 두 개의 append-only commit으로 기록되었다. 현재 local `main`과 `origin/main`에는 아직 반영되지 않았다.
|
||||
- issue comment evidence에는 release 집중 `75 passed`, 전체 `1065 passed, 51 skipped`, Ruff·ProofLine·diff check, checkout mismatch fail-closed, Docker build·smoke·image ID·archive checksum·canary scan과 독립 read-only review `PASS`가 기록되어 있다.
|
||||
- 환경 의존 PostgreSQL 41건, RabbitMQ 9건, KIS sandbox 1건은 설정·credential 부재로 skip되었다. 로컬 `actionlint`도 실행 파일 부재로 수행되지 않았으며 향후 hosted workflow 실행 또는 별도 도구로 확인할 비차단 검증 공백이다.
|
||||
- version tag 생성·push, GHCR write, PR, main 반영, runtime rollout, deployment와 release는 수행되지 않았다. 따라서 live registry same-digest와 hosted Actions 실행 결과는 현재 `unverified` evidence다.
|
||||
- 이 REQ의 `approved`와 AC의 `active`는 현재 specification authority를 나타내며 구현 통합, publication, delivery closure, release 또는 deployment 완료를 의미하지 않는다.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- concrete version 선택, version tag 생성·push, 최초·후속 GHCR package write, production deployment, 운영 서버 pull/restart와 post-deployment verification
|
||||
- 일반 `main`/branch push용 별도 lint/test CI workflow 또는 branch protection 정책 신설
|
||||
- package version 변경, Git tag와 package version 일치 강제 또는 자동 version 증분
|
||||
- 기존 published tag·digest의 삭제·이동 또는 registry retention 변경
|
||||
- image signing, SBOM, provenance attestation, multi-architecture build와 moving `latest`
|
||||
- live credential, 운영 account·database·broker·KIS 연결, database migration/reset 또는 운영 데이터 변경
|
||||
- 다른 TREX repository의 workflow, image, wire/HTTP 계약 또는 release policy 변경
|
||||
- ProofLine delivery/release lifecycle의 소급 완료 주장
|
||||
Reference in New Issue
Block a user