# 감사 2-A 「major 재생성 분리」 — 수정안 반려

2026-08-27

## 감사가 말한 것

> `multiroll_select.py:902-914` 심각도 게이트가 major/minor 를 걷어내고,
> `:917` 이 **이미 critical 만 남은 목록에서** 재생성 후보를 뽑는다.
> 그래서 구조·카메라 결함인 major 가 편집에서도 재생성에서도 빠진다.
> 수정 — 국소 편집은 critical 전용 유지, 그 필터 **앞의 원본 목록**에서
> 「관찰자 합의 + 프롬프트 근거 + regeneration 범주」인 major 만
> 재생성 후보로 분기한다.

합계 15건(7샷)으로 셌다.

## 실측 — 감사보다 크다

`records.json` 23개(무료):

    게이트가 걸린 샷        484
    걷어낸 이슈           1,325   major 1,134 · minor 191
    그중 major + needs_regeneration + not unfixable  **295건**

전체 이슈 6,369건 기준:

| 칸 | 분포 |
|---|---|
| `severity` | None 3,134 · major 2,270 · critical 583 · minor 382 |
| `unfixable` | None 4,425 · False 1,808 · **True 136** |
| `needs_regeneration` | None 3,986 · False 1,553 · **True 830** |
| `observation_index` | 3,235 / 6,369 |

## 그런데 수정안을 받으면 안 된다 — 근거 넷

### ① ★재생성이 **스틸 경로에 배선돼 있지 않다** (Codex 판정, 확인함)

AST 로 세었다:

    run_multiroll_select / run_branch_select 호출 3개
      outdoor_structure_seed_step.py:1473   regeneration_issue_policy 만
      plate_multiroll.py:205                없음
      still_recipe_service.py:3784          없음
    → regen_gen_fn 을 넘기는 곳 **0개**

`:917` 의 `regen_issues` 는 지금 스틸에서 재생성 후보가 되어도 `:930`
조건(`regen_gen_fn is not None`)을 못 타고 edit 로 내려간다.

★**감사 수정안은 「필터 수리」가 아니라 「새 유료 재생성 기능 신설」이다.**
 295건을 열면 그림 295장을 새로 사는 것이고, 그 전에 배선부터 만들어야
 한다. 나는 근거 셋(②③④)을 댔지만 **이 전제를 못 봤다.**

### ② `needs_regeneration` 은 자가신고다

`observation_index` 재결속(`:231-241`)은 **`severity` 만** 보호한다
(`item["required"] = [..., "severity", "observation_index"]`).
`needs_regeneration` 은 취합자가 매기고 아무도 되짚지 않는다.

### ③ 그 값이 **계약을 벗어나 쓰이고 있다**

스키마 description:

> true when the fault is in the structure's overall form — its storey
> count, massing, footprint or how many units it reads as holding

295건의 실물:

    · 식당 출입구가 중좌 배경의 사선이 아니라 프레임 정중앙에 정면으로 놓여 있다
    · 식탁이 실내로 후퇴하는 배경이 아니라 화면 하단 전경에 크게 들어와 있다
    · 카메라가 방 안 바닥 근처 로우가 아니고 중간 높이에서 …
    · 프롬프트의 지시와 달리 인물의 후면 3/4 측면이 아닌 전면 3/4 측면을 …
    · 카메라가 눈선보다 약간 위가 아니라 모자 챙 아래가 드러나는 눈높이 …

카메라·구도 결함이다. 코드가 직접 「카메라/시점은 `unfixable` 관할」이라고
말한다(`:861-863`) — 필드 분류가 잘못된 것이다.

★Codex 추가 지적: `build_regen_prompt` 는 "STRUCTURAL FAULTS" 와
 storey/massing 전용 tail 을 붙인다. 카메라 오분류를 그대로 넣으면
 **「구조 결함이다」라고 말하면서 low angle 을 고치라는 모순 프롬프트**가
 된다.

### ④ 감사가 말한 두 조건은 **스키마에 그런 칸이 없다**

「관찰자 합의」·「프롬프트 근거」 — 없다. 지어내면 안 된다.
수정안에서 삭제해야 한다.

## 그래서 2-A 는

**감사 수정안 반려 + 근거 정정.** 지금 코드를 손대지 않는다.

## 남은 별건 셋 (전부 무료로 시작)

### (가) 295건을 계약 안/밖으로 가른다

각 건에 관찰 원문 · `observation_index` · `severity` · producer · 팩 · 시각 ·
실제 caller 를 붙인다. 그 분포를 본 뒤 **structural 재생성 자체를 새
기능으로 설계할지**를 따로 정한다.

★분류를 **글자로 하지 않는다.** 이 저장소 규칙(2026-05-24)이고, 하려면
 구조화 판정이어야 한다.

### (나) `severity` 미부착 3,134건 (49%) — ★**결함이 아니다** (닫음)

producer 칸으로 갈라 재었다(무료):

| producer | sev 있음 | sev 없음 | `observation_index` |
|---|---|---|---|
| `critique` | 1,910 | 2,909 | 1,910 / 4,819 |
| `composition_critique` | 0 | 198 | **0 / 198** |

★**섞인 목록이 0건이다.** `critique` 결과 2,066벌 중 전부있음 536 ·
 전부없음 1,530 · **섞임 0**. Codex 가 「현행 스키마에서 mixed list 는
 나올 수 없다」고 한 그대로이고, 기록 손상은 없다.

★**구도 critique 이 버려지는 판도 0건이다.** `composition_critique` 가
 돈 200샷을 전수로 보면 **전부 `main sev없음`** 이다:

    main sev없음 · comp 0건   74
    main sev없음 · comp 1건   72
    main sev없음 · comp 2건   39
    main sev없음 · comp 3건   12
    main sev없음 · comp 4건    3
    main sev있음 · comp 있음    0   ← 게이트가 걸려 버려질 판

`issues += comp["issues"]` 로 severity 없는 구도 이슈가 합쳐지는 것은
맞지만, 그 판에서는 main 도 severity 가 없어 게이트(`if any("severity"
in issue …)`)가 아예 안 걸린다. **한 번도 안 일어났다.**

결론: 3,134건은 **구팩·다른 producer 의 의도된 무severity 계약**이고
(Codex 의 (b) 갈래), 현행 GG46 계약에서 누락된 것은 **0건**이다.
별건으로 세우지 않는다.

<details><summary>원래 적었던 것 (틀림)</summary>

게이트 조건이 `if any("severity" in issue for issue in fixable)` 라
그 경로엔 게이트가 통째로 안 걸린다. 다만 **49% 전체를 결함으로 세우면
안 된다** (Codex):

    a) 현행 GG46 계약에서 severity 누락  → 실제 결함, 별건 HIGH
    b) 구팩·다른 producer 의 무severity   → 의도된 호환 경로, 집계에서 제외

`build_critique_schema` 호출 13개 중 `with_severity=True` 는 6개,
안 켜는 7개는 GQ·legacy·`gpt_composition` 이다. 먼저 3,134건을
producer 로 갈라야 한다.

★한 이슈만 빠지는 mixed list 는 현행 스키마에서 나올 수 없다. 그런 건이
 있으면 **기록 손상/병합 문제**로 따로 잡는다.

</details>

### (다) 재생성이 카메라 결함에 실효가 있나 — 유료 전 무료 판별

Codex 안(동의):

1. 기존 multiroll 후보가 이미 **같은 브리프·같은 refs 로 다시 찍은 표본**
   이다. 새 그림을 사지 말고 그 샷의 A/B 후보와 저장된
   `judge readings.direction` / `hard_violations` 를 먼저 대조한다.
2. 다른 후보는 카메라를 지켰는데 **선택본만** 어겼다면 → 재생성 문제가
   아니라 **선정 문제**다.
3. 후보 전부 어겼다면 브리프/모델 준수 문제가 확인된다. **그 경우에만**
   교정문을 덧댄 재생성 5~10샷 canary 를 산다.
4. 기록이 부족한 샷은 새 VLM 보다 **기존 PNG 를 사람 눈으로** 먼저 본다.

#### 무료로 갈 수 있는 데까지 갔다 — 여기가 한계다

    게이트가 걸린 샷            484
      readings 있음             343
      readings 없음             141
    재생성 후보가 있는 샷        202
      └ 후보 2장 이상 = 대조 가능  **143**
      └ readings 없음 = 눈으로     59

    hard_violations 전수  비어 있음 4,776 · 내용 있음 2,450

★**그 다음은 무료가 아니다.** `readings[i].direction` 도
 `hard_violations` 안도 **자유 서술**이라, 「어느 후보가 카메라 지시를
 지켰나」를 가르려면 구조화 판정이 필요하다. 글자로 가르지 않는다.

★그리고 그 판정은 **structural 재생성을 새 기능으로 만들지**를 정하기
 위한 것이다. 아직 정해지지 않았으므로 **지금 사지 않는다.**
 정하고 나서 143샷 중 표본으로 시작한다.

## 내가 배운 것

감사표의 수정안은 **재료를 확인하기 전에 쓰였다.** 나도 근거 셋을 대면서
「배선이 되어 있나」를 안 물었다.

★**「이 수정이 무엇을 켜는가」를 묻기 전에 「그 스위치가 연결돼 있는가」를
 먼저 묻는다.** 만들어 놓고 안 부른 관문이 없는 것과 같듯이, 안 배선된
 갈래에 후보를 더 보내는 것도 아무 일이 아니다 — 배선을 만드는 순간
 **돈이 열린다**는 것만 다르다.
