# 08. 구조/로직/파이프라인 개선 아이디어

> 원본 코드/프롬프트/기존 문서를 수정하지 않고 생성한 read-only 기반 제안 문서입니다. 이 문서는 코드 수정안이 아니라 구조적 방향, 로직 정리, 파이프라인 효율화 아이디어를 정리합니다.

## 목표

현재 레포의 핵심 문제는 개별 함수 한두 개보다 "실행 경로, 상태 truth, 프롬프트/모델 source, asset 검증, DB schema 관리"가 분산되어 있다는 점이다.

따라서 개선 목표는 다음이다.

| 목표 | 설명 |
|---|---|
| 실행 경로 단일화 | 같은 기능은 하나의 orchestrator를 통해 실행 |
| 상태 truth 단순화 | completed/running/failed/partial 판단 기준을 한 곳으로 수렴 |
| asset 검증 강화 | 파일 생성, DB row, checkpoint가 함께 맞아야 성공 |
| prompt/model provenance 명확화 | 어떤 prompt/model이 실제 호출됐는지 항상 추적 |
| pipeline 비용 절감 | 재실행 범위 축소, cache, diff 기반 invalidation |
| 운영 안전성 강화 | silent failure 제거, dry-run 기본, durable queue |
| legacy 분리 | active/orphan/experiment 경계 명확화 |

## 권장 목표 아키텍처

```mermaid
flowchart TB
    FE[Frontend] --> API[Single Pipeline API]
    API --> Orchestrator[Episode Pipeline Orchestrator]
    Orchestrator --> Lock[Episode-level durable lock]
    Orchestrator --> Catalog[Step Catalog]
    Catalog --> Runner[Step Runner]
    Runner --> PromptResolver[Effective Prompt/Model Resolver]
    Runner --> Checkpoint[Checkpoint Store]
    Runner --> AssetVerifier[Asset Verifier]
    Runner --> StepRun[(step_run)]
    AssetVerifier --> AssetDB[(image_asset)]
    AssetVerifier --> Files[project assets]
    Checkpoint --> Projection[Checkpoint Projection]
    Projection --> ReadDB[(read model tables)]
    ReadDB --> FE
    StepRun --> FE
```

핵심은 모든 실행을 "Episode Pipeline Orchestrator"로 통과시키는 것이다. 직접 image service를 호출하는 legacy endpoint도 내부적으로는 같은 orchestrator request로 변환되어야 한다.

## 1. 실행 경로 단일화

### 현재 문제

참조 이미지와 씬 이미지 생성이 두 경로로 실행된다.

| 경로 | 특징 |
|---|---|
| `/steps/ref_image_gen`, `/steps/scene_image_pipeline` | StepRunner/checkpoint/step_run 중심 |
| `/generate-reference-images`, `/generate-images` | legacy/direct service 중심 |

이 구조에서는 같은 사용자 행동이 서로 다른 상태 저장과 검증을 만든다.

### 제안

모든 실행을 `PipelineCommand` 개념으로 정리한다.

| Command | 의미 |
|---|---|
| `RUN_STEP` | 단일 step 실행 |
| `RUN_CATEGORY` | analysis/image/all 실행 |
| `GENERATE_REFERENCE_IMAGES` | 내부적으로 `RUN_STEP ref_image_gen` |
| `GENERATE_SCENE_IMAGES` | 내부적으로 `RUN_STEP scene_image_pipeline` |
| `REPAIR_PROJECTION` | checkpoint -> DB projection 재실행 |
| `REVALIDATE_ASSETS` | asset file/DB/checkpoint 재검증 |

```mermaid
flowchart LR
    LegacyEndpoint[legacy image endpoint] --> Command[PipelineCommand]
    StepEndpoint[steps endpoint] --> Command
    UIAction[UI action] --> Command
    Command --> Orchestrator[Single orchestrator]
    Orchestrator --> Runner[StepRunner]
```

### 기대 효과

| 효과 | 설명 |
|---|---|
| 중복 실행 감소 | endpoint가 달라도 같은 lock/runner 사용 |
| 상태 일관성 | `step_run`과 checkpoint가 항상 남음 |
| 디버깅 단순화 | 사용자가 누른 버튼과 실제 step이 1:1로 추적 |
| legacy 제거 쉬움 | endpoint는 compatibility wrapper만 유지 |

## 2. 상태 truth 재정의

### 제안하는 상태 계층

```mermaid
flowchart TB
    ExecutionTruth[Execution truth: step_run] --> CheckpointTruth[Output truth: checkpoint manifest]
    CheckpointTruth --> ProjectionTruth[Read truth: DB projection tables]
    ProjectionTruth --> UITruth[UI read model]
    AssetTruth[Asset truth: file + image_asset + checkpoint asset manifest] --> ProjectionTruth
```

| 계층 | source | 책임 |
|---|---|---|
| 실행 truth | `step_run` | step 실행 상태, error, hash, counts |
| output truth | checkpoint manifest | LLM/step 결과 원본 |
| asset truth | file + `image_asset` + asset manifest | 이미지 생성 실재성 |
| read truth | projection DB | UI/API 조회 최적화 |
| UI truth | frontend read model | 사용자 표시 |

### 상태 정책

| 상태 | 의미 | downstream 허용 |
|---|---|---|
| `completed` | output contract와 verify 모두 통과 | 허용 |
| `partial` | 일부 output 존재, contract 미달 | step별 정책 필요 |
| `failed` | output 사용할 수 없음 | 불허 |
| `blocked` | dependency 미충족 | 불허 |
| `stale` | output은 있으나 upstream 변경됨 | 기본 불허, 명시적 override만 |
| `not_applicable` | 조건상 실행 대상 아님 | dependency로는 중립 처리 |

### 핵심 아이디어

`Episode.status = analyzed` 같은 넓은 상태를 gate truth로 쓰지 않는다. UI 편의용 summary로만 사용하고, 실제 실행 가능 여부는 `step_run + checkpoint contract`로 판단한다.

## 3. Asset step 공통 contract

이미지 계열 step은 transform step보다 강한 성공 조건이 필요하다.

### 공통 contract

| 항목 | 설명 |
|---|---|
| expected count | 생성 대상 수 |
| generated file count | 실제 파일 수 |
| DB row count | `image_asset` 등록 수 |
| checkpoint asset count | manifest에 기록된 asset 수 |
| path check | 모든 path가 project root 기준 resolve 가능 |
| type check | `asset_type`, `variant_label`, `still_id/entity_id` 계약 확인 |
| selected filter check | selected 대상만 생성했는지 |
| duplicate check | 같은 대상/variant가 중복 등록되지 않았는지 |
| reference chain check | 부모/참조 이미지가 실제 존재하는지 |

### 공통 판정

```mermaid
flowchart TB
    Expected[expected targets] --> Compare[compare]
    Files[generated files] --> Compare
    Rows[image_asset rows] --> Compare
    Manifest[checkpoint asset list] --> Compare
    Paths[path resolver] --> Compare
    Compare --> OK{all matched?}
    OK -->|yes| Completed[completed]
    OK -->|no, recoverable| Partial[partial with reason]
    OK -->|no, fatal| Failed[failed]
```

### 기대 효과

| 효과 | 설명 |
|---|---|
| false completed 차단 | 파일/DB/checkpoint mismatch 즉시 발견 |
| 사용자 신뢰 회복 | 완료 표시가 실제 사용 가능 상태를 의미 |
| 재실행 판단 쉬움 | 누락된 대상만 retry 가능 |
| 문제 위치 명확화 | provider failure, DB insert failure, path failure 구분 |

## 4. Prompt/Model effective resolver

### 현재 문제

프롬프트와 모델 정보가 여러 위치에 있다.

| 종류 | 위치 |
|---|---|
| step default model | `STEP_MANIFEST` |
| runtime text model map | `llm_client.PIPELINE_STEPS` |
| file prompt | `prompts/_base` |
| DB prompt | `prompt_template` |
| direct file prompt | 일부 module hard-code |
| image model | config/hard-code 혼재 |

### 제안

`EffectivePromptModelResolver` 같은 개념을 둔다.

입력:

| 입력 | 예 |
|---|---|
| `step_id` | `scene_detail` |
| `module` | `scene_detail` |
| `prompt_names` | `system`, `user`, `schema` |
| `project_id` | project-level override |
| `mode` | production/test/experiment |

출력:

| 출력 | 설명 |
|---|---|
| prompt source | DB/file/direct |
| prompt version | 실제 사용 version |
| schema version | 실제 schema version |
| pack consistency | same version 여부 |
| model provider | openai/gemini/fal |
| model name | 실제 호출 model |
| image model | 이미지 provider/model |
| provenance hash | checkpoint/LLM log에 저장 |

```mermaid
flowchart LR
    StepID[step_id] --> Resolver[Effective Resolver]
    ProjectConfig[project config] --> Resolver
    DBPrompt[(prompt_template)] --> Resolver
    FilePrompt[prompts/_base] --> Resolver
    Catalog[Step Catalog] --> Resolver
    Resolver --> Call[LLM/Image call]
    Resolver --> Provenance[checkpoint provenance]
```

### 효율화 포인트

| 방법 | 효과 |
|---|---|
| prompt hash 기반 cache | 동일 입력/프롬프트/model이면 재호출 생략 가능 |
| prompt pack atomicity | schema mismatch로 인한 재시도 감소 |
| effective prompt UI | 운영자가 실제 사용 prompt를 즉시 확인 |
| model cost visibility | step별 비용/품질 튜닝 가능 |

## 5. Incremental invalidation 설계

현재 force/re-run은 downstream을 넓게 invalidation할 수 있다. 더 효율적인 방식은 artifact dependency graph를 명시하는 것이다.

### 제안 dependency 단위

| 단위 | 예 |
|---|---|
| project | planning doc, visual world rules |
| episode | text cleanup, scene segmentation |
| scene | scene summary, scene detail |
| shot | shot extract, shot staging, scene image |
| entity | entity detail, entity t2i, reference image |
| background group | background plan/render |
| asset | image file + DB row |

```mermaid
flowchart TB
    EntityChange[entity t2i changed] --> RefImage[ref_image_gen for entity]
    EntityChange --> Composite[composite for affected outlooks]
    EntityChange --> SceneShots[only shots referencing entity]
    SceneShots --> SceneImage[scene_image_pipeline partial retry]
    BackgroundChange[background prompt changed] --> BGAsset[affected background asset]
    BGAsset --> ShotsUsingBG[shots using background]
```

### 기대 효과

| 개선 | 설명 |
|---|---|
| 재실행 범위 축소 | episode 전체 대신 affected scene/shot/entity만 재생성 |
| 비용 절감 | LLM/image call 감소 |
| 시간 절감 | selected/changed 대상만 처리 |
| 디버깅 쉬움 | 어떤 변경이 어떤 asset을 stale로 만들었는지 표시 |

## 6. Image pipeline 효율화

### 6.1 선택된 shot 중심 처리

`selected=true` shot만 최종 scene image 대상이라면, pipeline 중 이미지 비용이 큰 부분은 selected 기반으로 줄인다.

| 단계 | 아이디어 |
|---|---|
| shot planning | 전체 shot 유지 |
| t2i/detail | 전체 또는 selected+context만 |
| reference image | selected shot에 등장하는 entity 우선 |
| background render | selected shot이 쓰는 background만 우선 |
| scene image | selected shot만 생성 |
| non-selected | lazy/on-demand |

### 6.2 background asset reuse

배경은 shot보다 location/group/variant 단위로 reuse해야 한다.

| 방식 | 설명 |
|---|---|
| background fingerprint | location + time + weather + damage/state + camera-independent properties |
| variant label normalization | 긴 semantic label 대신 slug + hash |
| parent chain cache | 같은 parent/ref prompt면 재사용 |
| floor plan anchor cache | 같은 floor plan prompt/path면 재사용 |

### 6.3 retry granularity

현재 retry가 step 단위라면 비용이 크다. image asset 단위 retry가 필요하다.

| retry 단위 | 예 |
|---|---|
| entity asset | 특정 character reference만 |
| background node | 특정 background variant만 |
| scene still | 특정 selected shot만 |
| failed provider call | transient failure만 재시도 |

## 7. Pipeline mode 분리

하나의 pipeline이 모든 상황을 처리하려고 하면 복잡해진다. 명시적 mode가 필요하다.

| Mode | 목적 | 특징 |
|---|---|---|
| `draft` | 빠른 분석/검토 | 저비용 모델, 이미지 생략 또는 저해상도 |
| `production` | 최종 생성 | strict verify, full asset generation |
| `repair` | DB/checkpoint/projection 복구 | LLM 호출 없이 검증/동기화 중심 |
| `regen-assets` | 이미지 재생성 | selected target만 asset retry |
| `audit` | 상태 진단 | write 없이 mismatch report |
| `experiment` | chain/floorplan 등 실험 | active pipeline과 state 분리 |

```mermaid
flowchart LR
    Draft[draft] --> Review[human review]
    Review --> Production[production]
    Production --> Audit[audit]
    Audit --> Repair[repair]
    Audit --> Regen[regen-assets]
    Experiment[experiment] -. isolated .-> Findings[feed back into production design]
```

## 8. DB와 checkpoint 역할 재정의

### 제안

| 저장소 | 역할 |
|---|---|
| checkpoint | step output 원본, LLM response, provenance |
| DB projection | UI/API 조회, 검색, 필터 |
| `step_run` | 실행 상태와 재개 판단 |
| asset manifest | file/DB row/checkpoint asset contract |
| audit report | mismatch/read-only 진단 결과 |

### 중요한 원칙

DB projection 실패는 step completed를 막거나, 최소한 `completed_with_projection_error` 같은 명시 상태로 보여야 한다. 사용자는 "완료"를 "사용 가능"으로 이해하기 때문이다.

## 9. Legacy/experiment 격리

실험 코드는 필요하지만 active pipeline과 같은 이름/DB/path를 쓰면 위험하다.

### 제안 구조

| 구분 | 정책 |
|---|---|
| active | app에서 import/execute되는 코드 |
| deprecated | compatibility 유지, UI 기본 숨김 |
| experiment | 별도 output root, 별도 manifest namespace |
| archive | 검색 기본 제외 |
| runtime data | source audit 제외 |

### 실험 코드 원칙

| 원칙 | 설명 |
|---|---|
| project DB write 금지 기본 | 실험은 파일 output만 생성 |
| write 필요 시 explicit flag | `--apply` 또는 `--write-db` |
| output root 분리 | `scripts_output/experiments/<name>/<run_id>` |
| prompt/model 기록 | 실험 결과만 봐도 재현 가능 |
| active pipeline import 금지 또는 명시 | 실험이 production service를 직접 호출할 때 표시 |

## 10. 운영 관찰성 개선

### 필요한 dashboard/log

| 관찰 대상 | 표시 |
|---|---|
| step run | status, duration, model, prompt hash, input hash |
| asset step | expected/generated/db/file mismatch |
| prompt | effective source/version/schema |
| model | provider/model/cost/latency |
| queue | running/queued/stale locks |
| projection | last sync status/error |
| path | unresolved path count |

### 사고 분석에 필요한 최소 trace

| trace field | 이유 |
|---|---|
| `run_id` | 같은 실행 묶음 추적 |
| `step_id` | 어떤 step인지 |
| `target_id` | entity/shot/background node |
| `prompt_hash` | prompt 변경 영향 |
| `model` | 모델 변경 영향 |
| `input_hash` | 입력 변경 영향 |
| `asset_file_path` | 파일 존재 확인 |
| `image_asset_id` | DB row 확인 |
| `verify_result` | completed 판정 근거 |

## 11. 비용/속도 효율화 아이디어

| 아이디어 | 설명 | 효과 |
|---|---|---|
| prompt+input hash cache | 같은 입력이면 LLM 재호출 생략 | 비용 절감 |
| asset fingerprint cache | 같은 배경/참조 이미지 재사용 | 이미지 비용 절감 |
| selected-first generation | selected shot 우선 생성 | 사용자 체감 속도 향상 |
| lazy non-selected assets | 필요할 때 생성 | 총 비용 감소 |
| batch validation | 여러 asset path/DB row를 한 번에 검증 | DB roundtrip 감소 |
| group-level planning | location/background group 단위 plan | 중복 prompt 감소 |
| failure-class retry | transient/provider/schema/path/DB 실패를 구분 | 불필요 retry 감소 |
| local schema validation early | downstream 실패 전 차단 | 디버깅 시간 감소 |
| projection repair mode | LLM/image 호출 없이 DB 재동기화 | 빠른 복구 |
| audit-only mode | write 없이 문제 탐지 | 안전한 운영 진단 |

## 12. 단계별 적용 로드맵

### Phase A. 사고 방지 우선

| 작업 | 목적 |
|---|---|
| image endpoint 경로 단일화 | 같은 기능이 다른 상태를 만들지 않게 함 |
| asset verifier 도입 | false completed 차단 |
| migration fail-fast | DB schema drift 은폐 차단 |
| episode-level lock | 중복 실행 차단 |

### Phase B. 비용/속도 개선

| 작업 | 목적 |
|---|---|
| selected-first image generation | 빠른 결과 확보 |
| target-level retry | 실패한 asset만 재시도 |
| prompt/input hash cache | LLM 중복 호출 감소 |
| background reuse fingerprint | 배경 이미지 재사용 |

### Phase C. 운영/디버깅 개선

| 작업 | 목적 |
|---|---|
| effective prompt/model view | 실제 호출 근거 표시 |
| projection/audit dashboard | mismatch 실시간 발견 |
| path invariant report | cwd/path 문제 조기 발견 |
| run_id 기반 trace | 사고 재현 단순화 |

### Phase D. 레포 정리

| 작업 | 목적 |
|---|---|
| active/deprecated/experiment/archive registry | orphan 혼동 감소 |
| script safety convention | 실수로 DB/file 변경 방지 |
| docs generated sync | 문서 drift 감소 |
| CI lane 정리 | PG/path/frontend critical flow 보장 |

## 13. 최종 권장 우선순위

가장 먼저 할 일은 "더 많은 코드"가 아니라 "판정 기준을 좁히는 것"이다.

우선순위는 다음이 합리적이다.

1. 이미지 생성 실행 경로를 하나로 만든다.
2. asset step은 파일/DB/checkpoint가 모두 맞아야 completed로 본다.
3. DB migration 실패를 절대 숨기지 않는다.
4. prompt/model effective source를 checkpoint와 UI에 노출한다.
5. selected/changed target만 재실행하는 incremental pipeline으로 비용을 줄인다.
6. legacy/experiment/runtime data를 active code와 명확히 분리한다.

이 순서가 중요한 이유는, 현재 문제의 대부분이 "생성 자체 실패"보다 "성공 판정과 실제 사용 가능 상태가 다름"에서 발생하기 때문이다.

