- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다 - 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5 (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를 techviz 로 만들었다 - 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs 돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다. Concept 이 인용한 코드가 SSOT 에 없어 뺐다 - candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
124 lines
5.4 KiB
Markdown
124 lines
5.4 KiB
Markdown
---
|
|
kind: CONCEPT
|
|
slug: file-state-machine-and-ready
|
|
title: 파일 상태 기계와 READY가 뜻하는 것
|
|
topic: fileserver-state-and-fencing
|
|
project: clean-architecture-backend-template
|
|
status: 게시 전
|
|
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
rootTreeNode: concept:file-state-machine-and-ready
|
|
evidenceCapturedOn: 2026-09-01
|
|
assets:
|
|
- key: file-state-machine-and-ready
|
|
file: ../../../final/evidence/rendered/file-state-machine-and-ready.svg
|
|
- key: file-state-machine-and-ready-diagram
|
|
file: ../../../final/assets/diagrams/file-state-machine-and-ready.svg
|
|
evidence:
|
|
- ../../../final/evidence/raw/file-state-machine-and-ready.txt
|
|
source:
|
|
- 원본 분석 절은 final/document.md#4-4 · final/document.md#a08 §V1 이다.
|
|
---
|
|
|
|
# 파일 상태 기계와 READY가 뜻하는 것
|
|
|
|
파일이 공개적으로 읽을 수 있는지는 파일시스템이 아니라 관계형 레코드가 정한다. 그래서 모든 상태 전이가 상태와 버전 양쪽으로 가드된다.
|
|
|
|
## 관계
|
|
|
|
- **공개 읽기 가능한 상태는 완전한 identity를 DB 제약으로 요구한다**
|
|
이 개념에서 끌어낸 규칙이다.
|
|
- **물리 경로와 원본 파일명을 저장하지 않는다**
|
|
이 메타데이터가 무엇을 담지 않는지 정한 결정이다.
|
|
- **claim이 소유자와 토큰과 만료를 기록하지 않아 죽은 worker의 항목이 영영 남았다**
|
|
같은 리프의 상태 기계에서 나온 사례다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
파일이 11개 상태를 지나고 **공개 읽기 가능한 상태는 `READY` 하나뿐**이라는 설계의 설명이다. V1 헤더가 원칙을 적는다 — "파일시스템이 아니라 관계형 레코드가 파일이 공개적으로 읽을 수 있는지 결정한다."
|
|
|
|
## 공개 읽기가 가능한 상태
|
|
|
|
:::evidence key="file-state-machine-and-ready-diagram" alt="READY 만 공개 읽기 가능 경계 안에 놓이고 업로드 중과 검증 중, 실패와 삭제 대기가 바깥에 빗금으로 놓인다" caption="공개 읽기가 가능한 상태" zoom="false"
|
|
:::
|
|
|
|
## 전이와 완전성을 무엇이 가드하나
|
|
|
|
모든 전이가 `state`와 `version` 둘 다로 가드되고, `READY`의 완전성이 DB CHECK 제약으로 강제된다 — `content_key`·`actual_size`·`sha256`·`strong_etag`·`published_at`이 전부 NOT NULL이다.
|
|
|
|
## V1 헤더가 적은 원칙
|
|
|
|
:::evidence key="file-state-machine-and-ready" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true"
|
|
:::
|
|
|
|
## 저장하지 않는 것
|
|
|
|
물리 경로·마운트·원본 물리 파일명을 저장하지 않는다 — `content_key`는 서버 생성 opaque key이고 `original_name`은 신뢰할 수 없는 표시용 텍스트다.
|
|
|
|
:::note
|
|
|
|
컨테이너 레인 미실행
|
|
|
|
:::
|
|
|
|
## 진실의 출처
|
|
|
|
```sql
|
|
-- Fileserver platform metadata. The relational record — not the filesystem — decides whether a
|
|
-- file is publicly readable, so every state transition is guarded by both `state` and `version`.
|
|
```
|
|
|
|
파일시스템에 바이트가 있다는 것이 공개 가능하다는 뜻이 아니다. 레코드가 그것을 정한다.
|
|
|
|
이 선택의 결과가 전이 가드다. 상태만 보면 동시에 두 전이가 일어날 수 있으므로 버전도 함께 본다.
|
|
|
|
## 무엇을 담지 않는가
|
|
|
|
```sql
|
|
-- No physical path, mount, or original physical filename is stored here: `content_key` is a
|
|
-- server-generated opaque key and `original_name` is untrusted display text only.
|
|
```
|
|
|
|
세 가지를 담지 않는다. 물리 경로와 마운트와 원본 물리 파일명이다.
|
|
|
|
콘텐츠 키는 서버가 만든 불투명 키다. 원본 이름은 신뢰할 수 없는 표시용 텍스트일 뿐이라고 명시된다. 즉 그 값으로 무언가를 찾거나 열지 않는다.
|
|
|
|
## 스키마가 자기 전제를 검사한다
|
|
|
|
```sql
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM capability_schema_registry
|
|
WHERE capability_id = 'jpa-flyway-migration'
|
|
AND core_epoch >= 1
|
|
AND lifecycle_state = 'ACTIVE'
|
|
) THEN
|
|
RAISE EXCEPTION 'fileserver metadata requires active core epoch 1';
|
|
END IF;
|
|
```
|
|
|
|
이 스트림은 코어 에포크가 활성일 때만 적용된다. 능력 스키마 레지스트리가 그 사실을 답한다.
|
|
|
|
:::note
|
|
|
|
스키마 설치와 사용 승인을 나눈 레지스트리가 여기서 실제로 쓰인다. 이 마이그레이션은 레지스트리에 질의해 전제를 확인하고, 아니면 예외로 멈춘다.
|
|
|
|
:::
|
|
|
|
## 상태와 버전이 함께 가드하는 이유
|
|
|
|
상태만으로 전이하면 같은 상태에서 출발한 두 전이가 모두 성공할 수 있다. 버전을 함께 조건에 넣으면 하나만 성공하고 다른 하나는 갱신 건수 0 이 된다.
|
|
|
|
이 형태는 이 저장소의 다른 상태 기계와 같다. 소유자 튜플을 조건에 반복하고 갱신 건수를 답으로 쓰는 구조다.
|
|
|
|
## 공개 가능 상태의 무게
|
|
|
|
공개적으로 읽을 수 있는 상태는 다른 상태보다 요구가 많다. 그 상태에 도달한 레코드는 신원이 완전해야 하고, 그 완전성은 애플리케이션 검사가 아니라 데이터베이스 제약으로 표현된다.
|
|
|
|
애플리케이션 검사로 두면 그 검사를 지나지 않는 경로가 언젠가 생긴다.
|
|
|
|
<!-- body:end -->
|