«예쁜가»를 사람 눈 대신 숫자로 판정한다. 무엇을 어떤 상자로 재고(§2), 그 상자로 무엇을 세며(§4), 그 숫자들이 어떤 게이트를 지나 한 낱말이 되는지(§6)를 코드에서 정리했다. tidyLayout 이 실패한 이유 중 하나가 판정 기준의 부재였다 — 알고리즘보다 지표가 먼저다.
original.json)이다 — before 도 정답도 아니다. 재배치가 되돌리려는 상태가 원안이라서, ①②③④⑤ 어느 것도 절대값을 보지 않는다.FAIL 게이트 셋 → SUCCESS 눈금 둘 → 그 사이가 ACCEPTABLE. 못 잰 자리는 UNSOLVABLE(알아본 결과 답이 없다)과 UNKNOWN(아직 못 알아봤다)으로 가른다.judgeDocs 하나로 모았다 — 예전에는 네 걸음이 네 군데에 복사돼 있어 화면·터미널·코퍼스 정리가 서로 다른 답을 낼 수 있었다.브랜치 feat/post-replace-relayout · 커밋 9f1dfef7 의 작업트리이고,
이 커밋은 원격에 없다 — 코드 링크는 vscode://file/… 편집기 링크로 건다.
규칙 문서는 docs/evaluation-rules.md §2·§3 이 정본이고, 이 글은 그 규칙이
코드에서 어떻게 도는지를 흐름으로 다시 그린 것이다.
케이스를 만드는 쪽은 테스트 케이스 제작 로직 에 있다.
「원안 좌표계 맞추기 → 기준 지표 → 대상 지표 → 판정」 네 걸음은
순서와 인자가 정확히 맞아야 뜻이 있는데(특히 alignDocFrame 을 빠뜨리면
겹침 면적이 배율2로 부푼다), 그 네 걸음이 예전에는 네 군데에 복사돼 있었다 —
뷰어 · relayout-metrics.ts · relayout-method-run.ts · batch/pruneCases.ts.
한 곳이 어긋나면 화면과 터미널과 코퍼스 정리가 서로 다른 답을 내므로 judgeDocs 하나로 모았다.
judgeDocs(doc, tight, original, originalTight, {excessiveFontScale, outlines})
judgeDocs 가 한다. tight bounding box 는 프레임 원점 기준 길이라 문서를 늘린 만큼 같이 늘려야 하고
(scaleTightBoxes), 안 주면 기준 쪽 텍스트가 전부 「못 잼」이 되어 ⑤ 신규 겹침이 부풀어 보인다.재배치가 되돌리려는 상태가 원안이기 때문이다 — 디자이너가 정한 글자 크기 · 정렬선 · 「의도된 겹침」이 거기 있다. 그래서 ⑤-b 는 「원안에 없던 겹침을 만들었나」가 되고 After 에서 0(PASS)이 좋다.
original.json 과 rendered.json 은 같은 컴포넌트를 서로 다른 자리·배율로 앉힌 문서다.
페이지는 둘 다 1920×1080 이지만 컴포넌트를 앉힐 때 배율이 붙고, 그 배율이
props.text.fontSizeScale 이다(원안은 언제나 1, 렌더본은 커밋된 케이스에서 0.97~1.91).
| 지표 | 배율에 어떻게 걸리나 |
|---|---|
| ② 최소 폰트 배율 | 안 걸린다. 양쪽 다 자기 배율이 따로 붙으므로 날 fontSize 의 비가 곧 정답이다 (배율이 약분된다) |
| ③ 정렬선 보존율 | 「같은 선에 있던 쌍이 아직 같은 선인가」라 닮음변환에 불변. 다만 GUIDE_TOL(4px)이 절대값이라 배율 1.9 에서 경계가 흔들린다 |
| ⑤ 신규 겹침 | 정면으로 걸린다. 면적이 배율2로 커지므로(1.912 = 3.65) 원안에 있던 의도된 겹침이 전부 「새로 생긴 겹침」으로 잡힌다 |
그래서 alignDocFrame 이 닮음변환 하나(t = b × s + (tx, ty))로 옮긴다.
이동량은 양쪽에 다 있는 노드의 차이의 중앙값이다 — 평균이 아닌 것은
대치가 실제로 옮긴 노드가 섞여 있기 때문이다(6447600 은 한 도형이 573px 옮겨져 있다).
기준은 채점에만 들어온다. 후보의 입력은 여전히 rendered.json 하나이고,
원안을 봐야 정의되는 목표를 가진 후보(「원안에 없던 겹침」을 푸는 것들)에게만 좌표계를 맞춘 사본이 간다.
풀고 나서 답안지와 맞추는 것이지 답을 보고 푸는 것이 아니다.
세 상자를 구별해야 나머지가 읽힌다. 고를 것은 없다 — 기준이 두 번 옮겨진 끝에 지금은 하나다.
| 이름 | 무엇 | 어디서 오나 |
|---|---|---|
| rendered bounding box (프레임) | 문서에 박힌 data.props.boundingBox. 오토핏 여백을 안고 있다 | metrics.ts 의 absBoxMap |
| tight bounding box | 본문 글자의 glyph extent. 글머리 기호를 뺀다 | 엔진 TextBoundingBoxCalculator → eval-out/cases/<id>/tight/ |
| visual bounding box 판정 박스 | tight + 글자에 딸린 장식(글머리 기호가 쓰는 들여쓰기 띠) | visualBox.ts 의 visualBoxMap — 구운 tight 와 문서에서 만든다 |
한 텍스트 노드 위의 세 상자
예전에는 「tight bounding box 로 채점」 토글이 있었고 기본이 꺼짐이었다. 끄면 프레임으로 쟀는데, 프레임에는 오토핏 여백이 들어 있어 넘침·겹침을 과대 보고한다 (실측: 프레임 217×46.7 vs tight 174.84×27.5). 즉 화면의 기본 상태가 틀린 숫자를 보여 주고 있었다. 토글을 지우고 글자 쪽 상자를 필수로 만들었다.
tight 는 반대 방향으로 틀렸다 — 글머리 기호를 뺀다.
엔진이 기호를 본문과 따로 그리기 때문이다(CanvasTextDrawer 의 「5. markers」).
커밋된 코퍼스에서 잰 것이 그 증거다.
| n | tight 의 left (프레임 원점 기준) 중앙값 | |
|---|---|---|
| 글머리 기호 있는 텍스트 | 117 | 30.94px |
| 없는 텍스트 | 789 | 3.78px |
기호가 있으면 tight 가 기호를 지나친 자리에서 시작한다. 그 상자로 재면 「기호는 도형 밖으로 나가 있는데 넘침 0」이 된다. visual 로 옮기면서 코퍼스 117개 노드가 중앙값 30.94px(최소 16.72 · 최대 83.85) 넓어졌다.
들여쓰기 폭이 폰트마다 달라(tight.left / listStyle.fontSize 가 0.70~2.10em)
이 층에서는 기호 글리프를 잴 수 없다. 그래서 기호가 쓰라고 비워 둔 띠 전체를 덮는다 —
기호를 자르지 않는 것이 목적이라 그 방향의 오차는 안전하다.
judgeBoxOf프레임으로 떨어지는 길이 없다.
tight 는 선택이 아니라 필수 인자이고, 프레임으로 재야 하는 자리는
frameBoxesAsTight(doc) 를 적어서 넘긴다. 그런 자리는 둘뿐이다 —
후보 안의 시행 문서(크롬을 못 부른다)와 합성 픽스처 테스트(손으로 만든 Doc).
헷갈리기 쉬운 자리라 한 표에 모아 둔다. 오버레이와 지표는 늘 같은 박스를 본다 —
둘 다 judgeBoxOf 를 지난다. 그래서 파란 점선 밖으로 나간 초록 상자의 수가 곧 「넘침 노드 수」다.
| 어디 | 판정 박스 | 코드 |
|---|---|---|
| 뷰어 오버레이 · ① 넘침 · ④ 유휴 여백 · ⑤ 신규 겹침 — 텍스트 | visual bounding box | judgeBoxOf ← visualBoxMap ← tight/ |
| 같은 곳, 도형 | 절대 박스 — 문서에서 읽은 boundingBox | absBoxMap |
| ⑥ 좁은 칼럼 | 절대 박스 — 「문서에 박힌 폭」을 되묻는 지표라 판정 박스로 물을 수 없다 | absBoxMap |
| 렌더 재검증 | tight bounding box — 줄 수를 높이 차분으로 얻는 자리라 기호(가로 몫)와 무관하다 | renderProbe.ts 의 tightBoxOf |
| 후보 안쪽 게이트 · 합성 픽스처 | 절대 박스 — tight 를 잴 수 없어 적어서 끼운다 | frameBoxesAsTight |
| 컨테이너 「담기는가」 | 배경 도형의 모양이 허락하는 최대 내접 사각형 | containerShape.ts |
computeLayoutMetrics 의 다섯째 인자 outlines(= 구운 배경 도형 외곽선)를 주면
①과 중앙 오차가 도형의 모양을 보고, ④가 도형이 실제로 칠한 자리를 센다.
코퍼스의 텍스트 컨테이너 403개 중 절반쯤이 캡슐·원·말풍선·프레임이다.
후보에게도 같은 값을 준다 — 알고리즘과 지표가 다른 자를 쓰면 개선이 숫자로 안 나온다.
안 주면 지금까지처럼 bbox 다. 실측(98건 · rendered.json): 넘침 노드 94 → 99,
유휴 여백 중앙값 +0.006.
computeLayoutMetrics(doc, tight, base, baseTight, outlines) 가 계산한다.
tight 는 필수다 — 판정 박스가 그것 하나이기 때문이다.
base(= 좌표계를 맞춘 원안)를 주면 ② 폰트 배율 · ③ 정렬선 보존율 · ⑤ 신규 겹침이 채워진다.
| # | 지표 | 정의 | 방향 |
|---|---|---|---|
| ① | 넘침 노드 수 / 넘침 면적(px²) | visual bounding box 가 컨테이너 영역(배경 도형이 이 글에게 허락하는 상자, 없으면 페이지)을 벗어난 노드 수와 총면적. OVERFLOW_EPS = 1px² 미만은 부동소수 잡음이라 무시 | 낮을수록 |
| ② | 최소 폰트 배율 | 원안 대비 가장 많이 줄어든 텍스트의 fontSize 배율(1 = 안 줄어듦). shrunkNodes 는 줄어든 노드 수 | 높을수록 |
| ③ | 정렬선 보존율 | 원안에서 같은 직선(±GUIDE_TOL = 4px)에 있던 노드 쌍이 채점 대상에서도 같은 선인 비율(0~1). 통째 평행이동은 보존 | 높을수록 |
| ④ | 유휴 여백 비율 | 1 − 콘텐츠 점유율. 점유율은 leaf 가 덮은 격자(COVERAGE_CELL = 4px) 비율 — 텍스트는 visual box, 도형은 자기 모양(구운 외곽선, 구멍 제외)으로 덮는다. 페이지 전면 배경(면적 ≥ 90%)은 제외 | 낮을수록 |
| ⑤-a | 겹침 쌍 | 지금 겹쳐 있는 leaf 쌍 수(의도된 겹침 제외 — §5). 참고용 절대량이라 원안에도 0 이 아닐 수 있다 | 낮을수록 |
| ⑤-b | 신규 겹침 쌍 수 / 면적 | 원안에 없던 겹침이 생기거나 커진 leaf 쌍의 수와 늘어난 면적 | 0 이어야 함 — 게이트 |
| ⑥ | 좁은 칼럼 노드 수 | 두 줄 이상인데 줄당 글자 수가 NARROW_CPL(=3) 미만인 텍스트 수. 폭은 문서에 박힌 boundingBox.width | 낮을수록 |
| ⑦ | 잘린 노드 수 / 면적 | 요소의 일부가 페이지(= 렌더 iframe) 밖으로 나간 leaf 수와 면적. 유일하게 원안에 안 견주는 절대값 | 낮을수록 |
셋은 서로 배타가 아니라 한 노드가 잘리면서 넘치고 겹칠 수 있고, 각각 따로 센다. ① 이 이미 「컨테이너가 없으면 페이지」를 보는데도 ⑦ 을 따로 세는 이유는 둘이다 — ① 은 글자가 그려진다고 전제하므로 「배경 도형 안에는 담겼는데 그 도형이 페이지 밖」을 0 으로 보고, ① 은 원안 대비인데 잘림은 절대값이다(원안에서 잘려 있었더라도 안 읽히면 안 읽히는 것이다).
대치가 라벨 자리에 문장을 넣으면 렌더러는 넘치는 대신 좁은 상자에 여러 줄로 흘린다. 5636021 실측: 「18%」가 있던 상자에 「여기까지 여세요」가 들어와 139px 폭에 4줄(줄당 1.8자)이 됐다. 상자가 배경 도형 안에 있으니 ① 넘침 0 · ② 폰트 배율 1.000 · ⑤ 신규 겹침도 없어 ①~⑤ 가 전부 만점을 주는데 그림은 세로쓰기처럼 보인다.
「읽기 나쁘다」는 라벨이 코퍼스에 없어서, 사람이 만든 정답이 그 노드의 폭을 넓혔나를 대신 봤다. 하한 3 에서 걸리는 59개 중 정답도 넓힌 것이 36개 · 안 건드린 것이 7개로 84% 가 같은 판단이고, 4 부터 71% · 5 부터 63% 로 흐려진다. 그 위(줄당 4~6자)는 배지·라벨의 정상 모양과 섞여 잣대로 쓸 수 없다. (2026-08-24 · 정답 104건 · 두 줄 이상 텍스트 459개 시점의 일회성 조사다 — 답하는 것이 「왜 3 인가」이지 「지금 코퍼스가 어떤가」가 아니어서 다시 재지 않는다.)
⑥ 은 지금 걸리는 것이 너무 많다. 게이트로 올리면 before 의 좁은 칼럼 58개 노드가
한꺼번에 FAIL 로 넘어가는데, 합본이 푸는 것은 33개뿐이고 나머지 25개는 slack 이 없어 어떤 후보도 못 고친다.
⑦ 은 걸리는 것이 없다. 커밋된 119건에서 페이지 밖으로 나간 leaf 는
ExtendableShapeItem 하나뿐이고 텍스트는 0 이다(2026-08-26 실측).
게이트로 올려도 아무것도 안 가른다 — 지금 ⑦ 은 후보가 만들지 않았는지 보는 자리다.
중앙 정렬 오차(meanCenterError)는 계산이 metrics.ts 에 남아 있지만
번호가 없고 표·리포트·CSV 어디에도 안 실린다. 옛 ⑤ 였고, 뺄 때 옛 ⑥ 신규 겹침이 ⑤ 로 당겨졌다 —
이 문서보다 오래된 글의 ⑥ 은 지금의 ⑤ 다.
① 은 코드에서 축별로 분해돼 있다
(overflowNodesH/V · overflowAreaH/V/Corner). 세로로 흘러넘친 것과 가로로 삐져나간 것은
알고리즘이 손쓸 방법이 다르므로 한 숫자로 뭉개지 않는다. 축별 노드 수는 서로 배타가 아니다 —
대각으로 삐져나가면 양쪽에 다 센다.
걸러내지 않으면 정상 디자인에서 상시로 울린다. 여섯을 빼면 남는 것은 「무언가가 무언가에 부분적으로 포개졌다」뿐이다.
overlapAreaMap — 여섯 필터, 그리고 게이트
④ 유휴 여백은 격자 union 점유율이라 union = Σ면적 − Σ겹침 이다.
겹치면 union 이 줄어 ④가 나빠지긴 하지만 두 현상이 한 숫자에 뭉개져 분리되지 않는다.
특히 「텍스트/배경 동반 확장」에서는 노드를 키운 Σ면적 증가가 겹침 손실을 덮어버려
글자가 서로 포개진 문서가 ④ 기준으로는 개선으로 찍힌다.
반대로 겹침이 전혀 없는 여백 넉넉한 레이아웃은 ④만 나쁘다.
①②③ 도 겹침에는 무감각하므로, ⑤ 가 없으면 「요소가 서로 포개졌다」를 벌주는 지표가 하나도 없다.
⑤ 는 새로 생긴 쌍과 이미 겹쳐 있던 쌍이 커진 것을 모두 세지만, 만드는 쪽에서 변경을 되돌리는 판정은 새로 생긴 쌍만 본다. 컨테이너를 키우면 배지가 카드 위에 걸친 것 같은 의도된 겹침이 필연적으로 커지므로, 그것까지 되돌리면 컨테이너를 조금도 키울 수 없다. 숫자는 여기 그대로 남는다 — 가리는 것이 아니라 되돌릴 이유로 쓰지 않는 것이다.
지표는 숫자를 열 몇 개로 늘어놓는다. 케이스가 열 몇 건일 때는 표를 눈으로 훑어 「이건 됐고 저건 안 됐다」를 셀 수 있었지만, 케이스가 늘면 그 셈이 안 된다 — 후보를 하나 고칠 때마다 표 전체를 다시 읽어야 하고 좋아졌는지 나빠졌는지가 숫자 사이에 묻힌다. 그래서 지표 위에 라벨을 한 겹 얹는다. 표는 그대로 두고(왜 그 라벨인지는 표가 답한다), 라벨은 셀 수 있는 것만 맡는다.
judgeMetrics(metrics, base, options) — 게이트 흐름도
SUCCESS 가 「폰트 = 1.0」을 요구하고 FAIL 이 「< 0.7」만 잡으면 그 사이가 어느 라벨도 아닌 구간으로 비는데, 렌더러 오토핏이 멈추는 자리가 정확히 0.700 이라 그 구간에 문서가 몰린다. 비워 두면 가장 흔한 결과를 못 부르므로 아래쪽으로 붙였다.
예전에는 ① 만 절대값이라 디자이너가 일부러 넣은 오버행까지 후보 탓으로 셌다. 그 결과 원안 자신이 FAIL 인 케이스가 18건이었고(2026-08-25 · 137건 시점), 그 케이스는 재배치가 원안을 완벽히 되살려도 SUCCESS·ACCEPTABLE 이 못 됐다. 판정 박스가 프레임이라 넘침을 과대 보고한 것도 그 18건을 부풀린 원인이었다. 지금은 대치·재배치가 새로 만든 넘침만 벌준다.
판정의 단위는 「몇 개가 삐져나왔나」다 — 면적을 그대로 견주면 같은 노드가 조금 더 크게 잡히기만 해도 임계 근처에서 라벨이 흔들린다. 그래서 오랫동안 노드 수만 봤는데, 그러면 같은 노드가 훨씬 크게 넘친 것이 게이트를 그냥 지난다: 5699884 는 넘침 노드가 원안과 같은 1개인데 면적이 5,691 → 14,261px²(2.5배) 로 커진 채 SUCCESS 였고, 6777793 은 420 → 23,248px²(55배) 가 그랬다.
2026-08-27 부터 면적도 본다 — 원안의 10% 까지 봐준다. 10% 는 실측으로 고른 값이다: 96건 × 후보 16개에서 「노드 수는 안 늘고 면적만 늘어 게이트를 지나던」 결과가 29건인데, 그 배율의 최솟값이 1.78배이고 1.0~1.78배 구간에는 결과가 0건이다. 1.01 로 두어도 1.5 로 두어도 지금 코퍼스의 판정은 같다.
게이트가 요구하는 것은 「원안보다 나쁘지 않다」이지 0 이 아니다 —
6777793 은 3노드 748px² 를 남긴 채 SUCCESS 다(원안 5노드 420px²).
그래서 SUCCESS 의 까닭 문구는 실제 값을 적는다. 예전에는 그 자리에 「넘침 0」이 하드코딩돼 있어
표·터미널·case.json 이 전부 거짓을 적었다.
자기와 견주므로 넘침이 같고 ②⑤ 가 만점이며 ④ 도 같다. 그것을 라벨로 적으면
「원안은 완벽하다」로 읽히므로 ⑤-b 게이트 칸과 같은 규칙으로 「기준」이라고 적는다.
②③ 은 그대로 숫자(1.000)를 적는다 — 그쪽은 0 이 아니라 만점의 모양이라
읽는 사람이 오해하지 않는다.
UNSOLVABLE 과 UNKNOWN 을 가르는 것은 케이스가 든 근거다두 라벨 다 장이 비어 있지만 까닭이 반대다 — 앞은 알아본 결과 답이 없는 것이고
뒤는 아직 알아보지 못한 것이다. 예전에는 정답이 없는 케이스가 전부 UNKNOWN 이라,
「글자를 줄이지 않으면 안 담기니 넘침을 남긴다」고 판단해 일부러 비운 자리와 아직 만들지 않은 자리가
한 칸에 섞였다. 근거는 case.json 의 expectedResult: {status, reason, at} 이고
expected-result-verify.ts 가 적는다. 색은 미결을 뜻하는 파랑이다
(빨강은 FAIL, 회색은 UNKNOWN).
표가 소수 3자리로 찍으므로 그 반올림 폭이다. 1.000 이라 적어 놓고
라벨이 「폰트 축소」라고 말하면 읽는 사람이 표를 의심하게 된다.
| 상수 | 값 | 어디에 | 근거 |
|---|---|---|---|
| EXCESSIVE_FONT_SCALE | 0.7 | ② 폰트 게이트 | 렌더러 오토핏의 하한과 같은 값 — 「렌더러가 더는 못 줄이는 선」이 곧 「사람이 못 읽겠다는 선」이다. 뷰어에서 0.5~1.0 로 옮길 수 있다 |
| FULL_FONT_SCALE | 1 | SUCCESS 조건 | 가독성 기준이 아니라 불변 조건이라 잣대를 옮겨도 안 움직인다 |
| OVERFLOW_AREA_TOL | 0.1 | ① 면적 게이트 | 96건 × 후보 16개 실측: 게이트를 지나던 29건의 배율 최솟값이 1.78배, 1.0~1.78 구간은 0건 |
| VERDICT_EPS | 5e-4 | 모든 비교 | 표가 3자리로 찍는 반올림 폭. 표와 라벨이 어긋나지 않게 |
| OVERFLOW_EPS | 1 px² | ① 넘침 하한 | 정렬 계산의 부동소수 오차로 1e-13 짜리 «넘침» 이 생겨 노드 수만 부풀던 것을 막는다 |
| OVERLAP_EPS | 100 px² | ⑤ 겹침 하한 | 변끼리 딱 붙은 박스와 모서리가 스치는 접촉을 걸러낸다. 후보도 같은 값을 본다 |
| CONTAINED_RATIO | 0.95 | ⑤ 포함 관계 | 「포갠 것이 아니라 얹은 것」의 선. 재배치의 위상 판정도 같은 값을 본다 |
| GUIDE_TOL | 4 px | ③ 정렬선 | tidyLayout 의 GUIDE_TOL 과 같은 값 |
| COVERAGE_CELL | 4 px | ④ 점유율 격자 | 작을수록 정확하고 느리다 |
| PAGE_BACKDROP_RATIO | 0.9 | ④·⑤·컨테이너 | 페이지 전면 배경판은 원래 페이지를 꽉 채운다 — 세면 전부가 겹침이 된다 |
| NARROW_CPL | 3 | ⑥ 좁은 칼럼 | 정답이 폭을 넓혔나로 대신 검증: 3 에서 84% 일치, 4 부터 71%, 5 부터 63% |
| SIZE_EPS | 0.01 px | tight 물려받기 | 좌표 계산의 부동소수 잡음만 걸러낸다 |
| DECORATION_TYPES | 2종 | ⑤ 장식 제외 | LineItem · VectorGraphicItem — 다른 요소 위에 걸치라고 놓는 것이다 |
tightMissing 이 센다이것이 실제로 문제가 되는 자리는 하나다 — 크기를 바꾼 텍스트는 구운 판정 박스를 못 물려받는다. 그래서 폭을 열어 줄 수를 줄인 후보의 결과에서 그 텍스트가 격자에서 사라지고 ④ 가 그만큼 부푼다.
| 실측 | 무슨 일이 |
|---|---|
| 4223631 | 빠진 노드 하나가 페이지의 3.0% 라 ④ 가 0.787 → 0.818 로 뛰었고, 그 0.031 때문에 「두 줄을 한 줄로 편」 답이 SUCCESS 를 놓쳤다 |
| 6720819 | 텍스트 13개가 빠져 ④ 가 실제보다 0.154 낮게(= 촘촘하게) 나왔다 — 양방향으로 튄다 |
| 최선 합본 96건 | 프레임으로 대신 세면 SUCCESS 51 → 58(내려가는 케이스 0건). 게이트·겹침·폰트는 한 자리도 안 움직인다 |
빈 텍스트(엔진이 「글자 없음」이라 답한 것)는 그대로 아무 칸도 안 덮는다 — 그건 못 잰 것이 아니라 잰 결과가 0 이다.
carryTightBoxes재배치 결과는 뷰어가 그때그때 만드는 문서라 구울 수 없다.
그 장은 rendered.json 의 tight bounding box 를 물려받되 크기가 그대로인 노드만 가져다 쓴다.
언제 물려받아도 되나 — 박스가 그대로일 때만
tightMissing 이고, 그것이 곧 위 ④ 문제의 크기다.| 자리 | 무엇을 보여 주나 |
|---|---|
| 뷰어 | 케이스 제목 옆에 지금 고른 알고리즘의 라벨, 지표 표 맨 윗줄에 네 장 전부의 라벨. 칸에 마우스를 올리면 까닭이 뜬다(걸린 게이트, 또는 SUCCESS 를 놓친 이유) |
| relayout-metrics.ts | ■ <id> 옆에 후보들의 판정 분포, 표 맨 위에 판정 줄,
맨 아래에 열 × 라벨 요약표. --json 에도 verdict·reasons 가 실린다 |
| relayout-method-run.ts | 케이스 id 바로 옆에 라벨, 맨 아래 한 줄 집계 |
| case.json 의 verdict | 들일 때의 before 판정 하나. 목록·정렬용이고 정본이 아니다 |
뷰어는 고른 알고리즘·채점 상자·폰트 잣대로 그때그때 잰다. case.json 에 굽는 것은
들일 때의 before 판정 하나이고, 답하는 질문은 「이 케이스를 왜 들였나 = 재배치가 고칠 것이 있나」다.
그래서 잣대를 함께 적는다(verdict.rule = {excessiveFontScale, box}) —
폰트 게이트의 선이 조절 가능해졌으므로 무엇으로 잰 값인지 없이는 이 값이 낡았는지 알 수 없다.
| before 판정 | 건수 |
|---|---|
| FAIL | 85 |
| ACCEPTABLE | 11 |
| SUCCESS | 0 |
| UNSOLVABLE 표시된 케이스 | 51 |
SUCCESS 0 은 성적이 아니라 프루너가 이미 뺐다는 뜻이다 — 재배치가 고칠 것이 없는 케이스는 코퍼스에 남기지 않는다.
rendered.json 을 original.json 과 노드 id 로 짝지어 fontSize 를 견주면
텍스트 745쌍 중 줄어든 것이 0개다 — 최소 폰트 배율이 전 케이스 1.000 이다.
렌더본을 오토핏을 끄고 굽기 때문이고, 못 담은 글은 전부 넘침으로 남아 있다.case.json 의 problems 는 낡아 있다problems 에는 shrink 가 77건 남아 있다.
verdict 는 2026-08-27 에 전건 다시 구워졌지만 problems 는
이미 값이 있으면 안 덮는 규칙(사람 판단 보호) 때문에 그대로다 —
제작 로직 §7 에 자세히 적었다.| 무엇 | 파일 | 진입점 |
|---|---|---|
| 라벨 규칙 · 상수 | relayout-core/verdict.ts:170 | judgeMetrics · judgeDocs |
| 지표 계산 | relayout-core/metrics.ts:1044 | computeLayoutMetrics |
| 판정 박스 좌표 옮기기 | relayout-core/metrics.ts:191 | judgeBoxOf · frameBoxesAsTight |
| tight 물려받기 | relayout-core/metrics.ts:153 | carryTightBoxes |
| 겹침 지도 | relayout-core/metrics.ts:895 | overlapAreaMap |
| 좌표계·배율 맞추기 | relayout-core/docFrame.ts:87 | alignDocFrame · scaleTightBoxes · docFontScale |
| visual bounding box | relayout-core/visualBox.ts:129 | visualBoxMap · markerIndentOf |
| 컨테이너 모양 | relayout-core/containerShape.ts:607 | containerRegions · paintedSpansOf |
| 넘침·줄바꿈·좁은 칼럼 | relayout-core/textOverflow.ts:617 | overflowOf · isNarrowColumn |
| 후보 안쪽 게이트 | relayout-core/gate.ts | — 「자기 입력보다 겹침을 늘렸나」 |
| 렌더 재검증 | relayout-core/renderProbe.ts | RenderProbe |
metrics.ts · PostReplaceRelayout.tsx · relayout-report.ts ·
expected-result-build.ts 의 각주가 docs/evaluation-rules.md 의 절 번호를 가리킨다.
절 번호를 바꾸면 그 참조도 함께 고쳐야 한다.
여기서 채점하는 케이스가 어떻게 만들어지는지는 테스트 케이스 제작 로직 에 있다 — 두 입구, 축소를 끄는 레버, 굽기 순서, 라벨·정답·프루닝.