2026-10-26 보관. 1.0.0 → 1.1.0 · MINOR: miricanvas-iui origin/main 04585231 재대조, Stage bit 설명과 제목 링크 추가 본문과 자동 동기화 표는 보관 당시 내용입니다.
현재 기준과 원본 보기 → · 보관 목록검색 실행은 Rust, 색인·공통 계약·클라이언트·화면은 TypeScript가 맡는다. 2026-10-17 고정 소스로 tier·중첩·대치 정책과 표·나눠 담기를 함께 읽는다.
comp-frame은 사용자 내용이 기존 디자인의 어느 슬롯에 들어갈지 검색 단계에서 미리 계산한다. 2026-10-12 이후 검색·랭킹·중첩·Content Threading은 Rust 서버만 구현한다. 브라우저가 후보 DB를 직접 조회하고 TS 검색을 실행한다는 이전 설명은 현재 경로가 아니다.
| 구분 | 무엇을 바꾸나 |
|---|---|
| Tier 1·2·3 | 검색할 카테고리: 요청 type / 자기 행 fallback / 종단 하나 |
| Stage 0·1·2 | 같은 카테고리 안에서 슬롯 모양 비트 차이 0 / 1 / 2 |
| N1~N5 | 중첩 구조와 노드별 카테고리를 어느 순서로 포기하나 |
| 0군·1군 | 사용자 지정 종류 결과 / 추천 결과. Tier와 다른 축 |
코드 근거 · 문서 한 번 요청
코드 근거 · TS 검색 제거 기록
공개 ComponentSearchClient.search는 raw-text 또는 visual-summary를 받는다. 원문 경로는 생성·검색·병합·랭킹을 서버가 한 요청 안에서 끝낸다. entries에는 단일 후보와 여러 컴포넌트의 묶음 후보가 함께 들어올 수 있다.
| 출력 | 읽는 법 |
|---|---|
| binding | 실제 sheet_id와 사용자 글. 표·차트 grid는 matrix를 함께 갖는다 |
| blank / preserve | 미대치 슬롯의 분류. preserve도 최종 원문 보존 확정은 아니다 |
| outside_text / inside_unbound_text | 선택된 경계 밖 / 경계 안의 미매핑 글 |
| threading.pages | 여러 장으로 나눠 담은 경우의 장별 binding. 상위 binding은 첫 장 |
| meta / tier / matched_category | 검색·배제·투영을 진단하는 정보. 운영 품질 점수와 다르다 |
제품은 별도 백엔드에서 받은 searchKey·활성 componentVersion을 전달하고, 디자인 문서를 component.uuid로 받아 buildReplacement에 넣는다. 검색 통과 후에도 실제 렌더의 겹침·잘림·문장 의미를 확인해야 한다.
코드 근거 · 제품 호출 흐름
질의 Frame은 넣을 글을, 색인 Frame은 실제 노드 주소와 글 용량을 담는다. units는 항목, fields는 label·value·items 등의 슬롯, satellites는 공통 머리말, dataset은 표·차트 데이터다. aliases는 같은 물리적 칸의 다른 필드 이름이며 한 노드를 두 번 채우는 허가가 아니다.
현재 FRAME_VERSION = 5다. 적재 측 buildIisFrame은 IIS 구조 대응을 실제 노드와 연결하고, 만들 수 없으면 규칙 기반 Frame을 시도한다. 표 셀 지도와 표 기하도 색인에 들어간다. Frame 스키마 버전, IIS 발행분, 제품 componentVersion, 서버 배포 버전을 혼동하지 않는다.
코드 근거 · packages/comp-frame-shared/src/frame.ts
코드 근거 · packages/comp-frame-index/src/frame/component-frame.ts
| Tier | 현재 Rust 규칙 |
|---|---|
| 1 | type의 성립 조건을 통과한 카테고리. alternatives는 읽지 않는다 |
| 2 | 원래 type의 fallback 행을 순서대로. 각 도착지는 원본 내용에서 projection한 뒤 성립 검사 |
| 3 | List·LongFormTextLayout·HighlightedMessage 중 내용으로 고른 종단 하나. 이미 앞 군에 있으면 생략 |
예: Timeline → Steps → Staircase → List. Steps의 행으로 갈아타지 않고 Timeline의 행을 끝까지 본다. 날짜 전용 필드를 못 읽는 도착지에서는 P3이 날짜를 items로 옮긴다. P2는 읽지 않는 params를 제거하고 P4/P5/P6은 데이터 형태를 바꾸며 P7은 관계의 설명을 옮긴다. 관계 전체의 의미가 언제나 무손실이라는 보장은 아니다.
P8은 폐기됐다. 상한 15인 카테고리에 17항목을 억지로 접어 맞추지 않는다. 이후 align이 상세 문장을 한 슬롯에 합치는 일, 여러 장으로 나눠 담는 일은 별개의 처리다. 생성기가 처음부터 읽지 않는 필드에 내용을 쓰면 fallback P3이 자동 구제한다는 보장도 없다(B-33).
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/query_frame.rs
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/visual_summary/summary_projection.rs
후보는 서버 메모리 스냅샷에서 카테고리·중첩 카테고리·unit 수·dataset 종류·shape bits·용량 하한으로 먼저 좁힌다. Stage 0은 모양 비트가 같고, Stage 1·2는 각각 정확히 1·2비트 차이다. 20비트 가운데 앞 17개만 완화하며 dataset과 extraGrids는 하드 조건으로 남는다.
이것은 정확한 배치 일치나 최종 가독성 검사가 아니다. 제목 글자 수에 맞춘 사전 하한은 후보를 줄이는 근사 조건이고, 본문과 실제 줄바꿈·슬롯 대응은 후속 배정과 용량 검사가 본다. 과거 DB의 gc_passed 옵션은 현재 검색의 품질 통과와 같지 않으며 해당 컬럼 제거 마이그레이션이 존재한다.
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/filter.rs
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/shape.rs
코드 근거 · packages/comp-frame-index/sql/2026-09-22-drop-gc-passed.sql
9월 판의 “모든 카테고리는 목표 수 ×4까지만 스캔” 설명은 바뀌었다. 현재 첫 번째로 존재하는 tier는 하드 필터 통과 행을 전부 검사하고, 승인 후보 전체에서 순위를 매긴다. tier1_max_candidates=0은 무제한이다. 원래 tier 1이 비면 tier 2가 이 첫 tier 취급을 받을 수 있다.
| 설정 / 상태 | 현재 의미 |
|---|---|
| top_n = 50 | 최종 정렬·중복 제거 후 반환 상한 |
| min_candidates = 500 | 첫 tier 이후의 누적 승인 목표 |
| tier_targets = [50,50] | tier 처리가 끝난 뒤 하위 tier로 내려갈지 보는 누적 승인 문턱 |
| tier1_max_candidates = 0 | 첫 존재 tier의 승인 상한 없음. 양수를 주면 그 상한에서 자를 수 있다 |
| CATEGORY_SCAN_MULTIPLIER = 4 | 첫 tier 이후 카테고리의 스캔 예산 배율 |
| FETCH_PAGE_SIZE = 1000 | 후보 처리 페이지 상한. 현재는 메모리 풀 안에서 읽는다 |
행을 읽은 수, 배정·용량 검사를 통과한 수, fingerprint 중복 제거 후 반환 수는 서로 다르다. 통과 수가 0이면 다음 공급을 볼 수 있지만, 통과 행이 같은 Frame으로 중복되면 최종 카드 수가 적을 수 있다. 최신 메타의 tier1_fetched_rows·tier1_exhausted로 첫 tier를 어디까지 읽었는지도 확인한다.
코드 근거 · rust/comp-pass/crates/comp-frame-pool/src/search.rs
코드 근거 · packages/comp-frame-shared/search-defaults/options.json
| 단계 | 역할 |
|---|---|
| N1 | 구조와 종류를 유지해 exact 검색 |
| N2 | 중첩 모양을 유지하며 노드별 자기 행 fallback 조합 검색 |
| N3 | 부모 한 층을 벗겨 자식 묶음을 검색 |
| N4 | 필요하면 부모 벗기기를 반복 |
| N5 | 자식 내용을 글로 평탄화. Hierarchy는 부모 벗기기 대신 이 경로 |
현재 구현은 Rust nested_search.rs다. N1 결과가 있으면 반환하는 실제 분기가 있다. 위키 D-7의 과거 이종중첩 공급 제외를 근거로 최신 풀의 N1이 “언제나 0”이라고 쓰지 않는다. N2의 조합 수, 검색 대상 풀, 성공 여부를 따로 확인한다. 부모 내용·관계 설명의 보존과 형제 순서도 함께 검사해야 한다.
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/nested_search.rs
align은 질의 슬롯과 디자인 슬롯을 맞추어 binding·blank·preserve·내용 손실을 만든다. 랭커는 이 배정을 비용 계산보다 먼저 실행한다. content_loss > 0 후보는 제외한다. 내용이 남았다는 계산만으로 원문 의미 전체가 보존됐다고 보장하지는 않으므로 원본 → projection → Frame → binding을 추적한다.
표는 별도 조건이 있다. native 표의 확장이 공간 예산을 넘으면 검색에서 제외하고, 측정할 기하가 없는 표는 tableUnmeasured로 낮춘다. 글상자 표는 dataset.cells의 IIS 셀 지도에 맞춰 셀별로 배정할 수 있다. matrix라는 이유만으로 모든 후보를 native Chart로 취급하지 않는다.
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/align.rs
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/rank.rs
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/table_fit.rs
기본 rank_mode=tier_pool·clean_first=above_tier에서는 사용자 내용이 아닌 잔여가 0인지 → tier → fallback 순서 → 꾸밈 선호 → 비용 → 단독 태그와 나머지 동점 규칙 순으로 비교한다. 조회된 tier 2의 온전한 후보가 tier 1의 잔여 있는 후보보다 앞설 수 있다. 조회하지 않은 후보를 정렬이 찾아 주지는 않는다.
같은 fingerprint 묶음에서는 잔여 0인 후보를 대표로 바꾸고 다시 정렬한다. unauthored_count는 임시 문구 대상 등을 세는 구현 지표다. Marker·비내용 역할·구조 토큰처럼 원문 보존이 정당한 노드는 잔여 비용과 이 계수에서 빠진다. 사람의 의미 평가를 대체하는 완성도 점수는 아니다.
기본 가중치 정본에는 비용 키 23개와 threading 전용 가중치 2개가 있다. 초기값과 과거 튜닝 이력이 섞여 있으므로 값의 크기나 합계만으로 다른 알고리즘보다 우수하다고 말하지 않는다.
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/rank.rs
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/rank.rs
코드 근거 · packages/comp-frame-shared/search-defaults/weights.json
현재 화면과 제품 SDK는 공유 buildNodeTextMap을 쓴다. 순서는 binding → blank → preserve → 안쪽 잔여 → 바깥 잔여 → 제목 구제다. 이미 사용자 글을 받은 노드를 뒤 단계가 덮지 않는다.
| 조건 (위에서 먼저 적용) | 최종 처리 |
|---|---|
| Marker 또는 Decoration·Separator·Annotation | 원문 유지 |
| blank/preserve의 unit 필드 | 임시 문구 |
| vs, TAM/SAM/SOM, 숫자가 아닌 한 글자, 빈 글 등 구조 토큰 | 원문 유지 |
| 일반 숫자·글·원문 미상 | 임시 문구 |
문서 제목이 안쪽 title binding에 없으면 바깥 Title 후보를 우선해 한 곳을 고른다. Title이 없을 때도 Marker·비내용 역할은 후보에서 제외한다. 선택되지 않은 공통 부제·설명은 일반 글이면 임시 문구가 된다. 상세 대조와 실제 정책으로 다시 계산한 예시는 역할별 텍스트 대치에 있다.
이전 판은 TS 검색에서 F01~F09를 합성 재현하고 핵심 테스트 470개를 기록했다. 그 결과는 당시 커밋의 검증이다. 이후 Rust 이전, 첫 tier 전량 스캔, 정렬 비교, 내용 보존과 대치 정책 변경이 들어왔으므로 동일한 번호를 최신 결함으로 재선언하지 않는다.
| 옛 주장 | 이번 판의 처리 |
|---|---|
| 첫 tier도 ×4까지만 훑는다 | 현재 기본 전량 검사로 교체 |
| N1은 언제나 후보 0 | 코드는 검색을 실행하며 실제 풀 상태는 미측정 |
| preserve·경계 밖은 원문 유지 | 공통 노드 정책으로 교체 |
| threading은 두 종이고 제목 구제를 끈다 | 네 종 프로파일·제목 구제 유지로 교체 |
| 도형 글자는 양쪽 모두 Text와 같다 | aippt의 SVG 지원과 iui 벤더 Text 한정의 차이를 명시 |
현재 의심을 재현하려면 최신 Rust 함수와 같은 입력·풀·옵션을 고정하고 실행해야 한다. 이번 문서 갱신은 과거 테스트 수를 새로운 실행 결과로 재표시하지 않는다.
현재 나눠 담기 프로파일은 List·Steps·QnACard·TableOfContents다. 서버가 직접 배치 → 탐색용 질의 → 여러 장 계획 → 장별 검사·재정렬을 한다. 상위 binding은 첫 장이며 다음 장은 장별 데이터로 바꿔 그린다. 기본 장수 상한은 64다.
threading 및 original_size_verified 결과는 원본 크기를 기준으로 배치한다. 제목 구제는 유지되며, 임시 문구는 원래 셀의 용량과 요청에서 쓴 언어별 문구 표를 기준으로 고른다. 검색 때와 렌더 때 다른 문구 표를 쓰면 맞음 보장이 깨진다.
사용자가 generationTypes를 지정한 경우는 별도 0군·1군 검색이다. 지정 종류의 0군을 tier1_only로 먼저 찾고 부족할 때 추천 1군을 찾는다. 이 군 번호는 Tier 1~3이나 Stage 0~2가 아니다.
코드 근거 · rust/comp-pass/crates/comp-frame-core/src/threading/profile.rs
코드 근거 · rust/comp-pass/crates/comp-pass-logic/src/threading_search.rs
아니다. 첫 존재 tier의 기본 승인 상한은 0(무제한)이다. 전량 검사 후 tier 문턱을 보고 하위 tier 진행 여부를 정한다. 첫 tier 이후에는 min_candidates가 적용된다.
아니다. 일반 숫자+단위는 임시 문구 대상이다. Marker 역할이나 구조 토큰 등 먼저 적용되는 보존 조건과 실제 필드를 확인한다.
아니다. 규약 v0.5.6 인식 45종과 생성 허용 36종은 다른 집합이다. 그 위에 지정 종류·공급 버전 등 실행 설정이 얹힌다.
원본 입력 → projection → Query Frame → binding → nodeTextPolicy → 대치 페이로드 → 실제 렌더 순서로 처음 달라지는 곳을 찾는다. 서버 버전·componentVersion·threading 장 번호·언어별 임시 문구 표를 함께 남긴다.
iui.comp_frames의 한 행은 디자인 전체가 아니라 IIS 경계 노드 하나를 나타낼 수 있다. 검색용 컬럼은 Frame에서 파생한 카테고리·모양·용량·버전 등이며, Rust 서버는 추출한 스냅샷을 읽는다. frame_version=5와 제품 버전 3.0, 내부 발행분 2.6 같은 이름은 같은 축이 아니다.
2026-10-02 제공된 DB 측정(재측정하지 않음): 전체 226,952행, 발행분 2.5의 113,614행·96,538 DO, 도형 속 글자 8,418개·3,357 DO라는 숫자는 당시 기록이다. 지금의 행 수·커버리지나 최신 적재 완료를 뜻하지 않는다.
소스 차이가 남아 있다. aippt의 rlsc.ts:isTextBearingNode는 Text 또는 문자열 content가 있는 SVG를 읽는다. iui의 벤더 extractTextSlots와 적재 Frame 빌더는 Text를 기준으로 한다. 따라서 “aippt에서 도형 글자 대응”을 “comp-frame 모든 슬롯에 반영 완료”로 확대하지 않는다. 데이터 재적재도 별도 확인해야 한다.
코드 근거 · packages/comp-frame-shared/src/eregion/visual-summary/rlsc.ts
코드 근거 · packages/comp-frame-index/src/frame/component-frame.ts
갱신 2026-10-17. iui bcd1d0218766cbba3a174d1819ab218d613e626f, wiki a0f8b01961db9396206b1ddf097c66cb44bde137, aippt e6ffa4bdf65ec76f3d3031dc566f3fc7c19eade1의 origin/main 고정 파일을 읽었다. 모든 코드 줄 링크는 git archive 스냅샷에서 확인했다. 로컬 브랜치나 미커밋 변경을 구현 완료로 포함하지 않았다.
위키 spec·design·reference는 9월 학습판 이후 변경이 없지만 실행 구현은 크게 달라졌다. 규약의 alternatives·P8·중첩 정책과 코드의 실제 동작을 분리했다. 이번 작업에서 운영 DB·서비스 배포·실제 렌더 품질이나 전수 회귀 테스트를 새로 측정한 것은 아니다.
전체 개념 수업과 50문항은 학습 페이지, 생성 원본과 고정 코드 지도는 강의자료에 있다. 이전 판의 상세 F01~F09·실험 수치는 보관본에서 당시 근거로 읽는다.