모든 figmascope 내보내기는 일곱 가지 아티팩트를 담은 .zip으로 시작됩니다. 그 중 CONTEXT.md는 설계에 의해 가장 먼저 읽히는 파일입니다. 이것은 README가 아니고, 자동 생성된 문서도 아닙니다. 디자인과 그것을 코드로 변환할 에이전트 사이의 컴파일러 스타일 계약입니다.

이 글에서는 CONTEXT.md에 무엇이 담겨 있는지, 왜 그런 구조를 갖는지, 그리고 이것을 건너뛸 때 어떤 문제가 발생하는지 살펴봅니다.

계약 방식과 문서 방식의 차이

문서는 존재하는 것을 설명합니다. 계약은 무엇이 반드시 사실이어야 하는지를 명시합니다. 이 차이는 독자가 더 나은 옵션이 없을 때 기꺼이 간격 값을 만들어 내거나, 레이아웃 계층을 평탄화하거나, 16진수 색상을 하드코딩하는 LLM일 때 매우 중요해집니다.

CONTEXT.md는 대상 선언으로 시작됩니다:

# CONTEXT.md — Jetpack Compose target

This file is the authoritative spec for generating UI code from this bundle.
Read it before reading any other file.

"Jetpack Compose target"은 장식이 아닙니다. 에이전트는 이것을 사용하여 컴포저블 기본 요소를 선택하고, dp와 sp 단위를 처리하며, Modifier.padding()이 간격에 적합한 추상화임을 알고, 오버레이 레이아웃에는 BoxAlignment를 사용해야 한다는 것을 이해합니다. React/Tailwind 대상은 서로 다른 기본 요소가 담긴 다른 CONTEXT.md를 생성합니다.

"이것을 먼저 읽어라"는 지시도 의도적입니다. 에이전트는 컨텍스트를 순차적으로 처리합니다. 토큰 규칙이 에이전트가 이미 컴포넌트에 대해 추론을 시작한 후에 나타나면, 제약 조건이 너무 늦게 도달합니다. 계약을 앞에 배치하면 첫 번째 생성 토큰부터 규칙이 활성화됩니다.

엄격한 제약 조건 섹션

CONTEXT.md에서 가장 중요한 부분은 제약 조건 블록입니다:

## Strict constraints (must follow)

- Never hardcode dp values if a token exists within ±2dp
- Never flatten layout hierarchy — preserve every stack/overlay/absolute node
- Use stringRef values from strings.json, never inline literal text
- Treat missing fields as absent, not zero
- Do not invent component names not present in components/inventory.json

각 제약 조건은 에이전트가 이를 위반하는 것을 목격했기 때문에 존재합니다. ±2dp 토큰 규칙이 가장 명확한 예시입니다. 이 규칙이 없으면 스택 노드에서 gap: 14를 만난 에이전트는 Arrangement.spacedBy(14.dp)를 작성합니다. 규칙이 있으면 spacing.16이나 spacing.12가 2dp 이내에 있는지 확인하고 대신 토큰을 사용합니다. 출력이 달라집니다 — 토큰 값이 변경될 때 일관성을 유지하는 출력과 그렇지 않은 출력의 차이입니다.

계층 구조 규칙은 Compose가 레이아웃 트리이기 때문에 존재합니다. 에이전트가 중첩된 스택을 위치가 지정된 요소들의 평면 목록으로 평탄화하면, 원래 구조가 암시하는 반응형 동작이 파괴됩니다. IR은 이유가 있어서 모든 수준의 중첩을 보존합니다 — 그 중첩이 레이아웃 의도를 어떻게 인코딩하는지는 화면별 IR — Stack, Overlay, Absolute, Leaf를 참고하십시오.

제약 조건은 "원하면 토큰을 사용하라"가 아닙니다. "토큰이 존재하면 절대 하드코딩하지 말라"입니다. 이것은 제안이 아닌 금지입니다. LLM은 제안과 금지에 다르게 반응합니다.

stringRef 규칙은 i18n에 중요합니다. 에이전트가 리소스 키를 참조하는 대신 "Speed Test"를 인라인으로 삽입하면 지역화 누락이 발생합니다. 제약 조건은 에이전트를 명시적으로 strings.json으로 안내합니다.

에이전트가 CONTEXT.md를 순차적으로 읽는 방법

LLM 컨텍스트 창은 토큰을 왼쪽에서 오른쪽으로 처리합니다. CONTEXT.md의 구조는 이를 활용합니다. 순서는 다음과 같습니다:

  1. 대상 선언 (전체 생성 프레임 설정)
  2. 엄격한 제약 조건 (모든 결정에 적용되는 금지 사항)
  3. 번들 맵 (어떤 파일이 존재하고 각각 무엇을 포함하는지)
  4. 토큰 사용 규칙 (간격, 색상, 반경, 타이포그래피 해결 방법)
  5. 범위 노트 (이 번들이 다루는 것과 다루지 않는 것에 대한 솔직한 설명)

번들 맵 섹션은 에이전트에게 어떤 파일을 어떤 순서로 읽어야 하는지 알려줍니다:

## Bundle contents

- tokens.json — design tokens (spacing, radius, color, typography)
- screens/*.json — per-screen IR in stack/overlay/absolute/leaf format
- components/inventory.json — component identity list
- strings.json — i18n resource keys
- _meta.json — generation metadata and warnings

이 맵이 없으면 에이전트는 components/inventory.json이 존재하는지 모르거나, _meta.json을 주요 명세서로 취급할 수 있습니다. 명시적인 열거는 읽기 순서를 안내합니다.

범위 노트 — v0.4가 솔직히 다루지 않는 것

범위 노트 섹션은 figmascope가 자체 한계를 문서화하는 곳입니다. 이것은 의도적이며 협상 불가합니다. 명세가 불완전하다는 것을 모르는 에이전트는 자신 있게 빈 공간을 발명으로 채웁니다. 그것은 빈 공간이 존재한다는 것을 아는 것보다 더 나쁩니다.

## Scope notes (v0.4)

- Gradient fills are not supported. Nodes with gradient fills emit a warning
  in _meta.json under warnings. Treat as a solid fill approximation or TODO.
- Typography tokens require Figma Variables to be populated. If tokensSource
  is "inferred-from-frequency" or "none", typography coverage may be partial.
- This bundle covers UI structure only. Navigation, state management,
  and network calls are outside scope.
- Component instances are identified by componentId. Full component
  source props are not included — the inventory gives identity, not implementation.

그라데이션 경고는 특히 중요합니다. Figma는 사용자 정의 드로잉 없이는 직접적인 Compose 대응이 없는 복잡한 그라데이션 채우기를 지원합니다. 그라데이션을 조용히 삭제하거나 잘못된 코드를 생성하는 대신, figmascope는 _meta.jsonbackground-gradient-not-supported:<name> 경고를 내보내고 여기에 기록하여 에이전트가 영향받는 노드를 자체 출력의 버그가 아닌 알려진 공백으로 처리하도록 합니다.

타이포그래피 노트는 _meta.jsontokensSource 필드와 연결됩니다. Figma 파일에 변수가 없으면 figmascope는 빈도에서 토큰을 추론합니다 — 일반적인 값은 토큰이 되고, 드문 값은 되지 않습니다. 범위 노트는 에이전트에게 이 추론이 불완전하고 완전한 타이포그래피 커버리지를 가정하지 말아야 한다고 알립니다. 추론 폴백 작동 방식은 tokens.json 설명을 참고하십시오.

잘못된 예 / 올바른 예

구체적으로 살펴보겠습니다. gap: 16이 있는 스택 노드와 spacing.16: 16이 담긴 토큰 파일이 주어진 경우:

CONTEXT.md 제약 조건 없음 (잘못된 예):

Column(
    modifier = Modifier.padding(horizontal = 24.dp),
    verticalArrangement = Arrangement.spacedBy(16.dp)
) {

CONTEXT.md 제약 조건 있음 (올바른 예):

Column(
    modifier = Modifier.padding(horizontal = Spacing.spacing24),
    verticalArrangement = Arrangement.spacedBy(Spacing.spacing16)
) {

올바른 예의 출력은 토큰을 참조합니다. 디자인 시스템이 spacing.16을 16dp에서 14dp로 변경하면, 코드베이스 전체 검색과 교체 없이 코드가 올바른 상태를 유지합니다.

또 다른 예 — 문자열 처리. text: "Speed Test"stringRef: "speed.test"가 있는 리프 노드의 경우:

잘못된 예:

Text(text = "Speed Test")

올바른 예:

Text(text = stringResource(R.string.speed_test))

제약 조건은 strings.json을 가리키고, 키는 speed.test이며, 에이전트는 점 표기법을 Android 리소스 ID로 매핑하는 방법을 알고 있습니다. 에이전트가 컴포넌트를 생성하기 전에 제약 조건을 읽은 경우에만 가능한 일입니다.

에이전트에게 직접 프롬프트하면 안 되나요?

프롬프트에 이 지침을 직접 작성할 수 있습니다. figmascope가 이것을 파일로 외부화하는 이유는:

목표는 에이전트의 기본값 주변에서 프롬프트 엔지니어링하는 것이 아닙니다. 기본값을 무관하게 만드는 명세서를 제공하는 것입니다.

대안과의 구조 비교

Figma의 Dev Mode는 측정값, 변수, 코드 스니펫을 출력합니다. 명세서를 만들지는 않습니다. Dev Mode 출력을 사용하는 에이전트는 예시에서 규칙을 추론해야 합니다 — 즉, 엣지 케이스에 대해 잘못된 규칙을 추론하게 됩니다.

Locofy 및 유사한 도구는 직접 코드를 생성합니다. 에이전트가 명세서를 읽을 것을 기대하지 않기 때문에 CONTEXT.md에 해당하는 것이 없습니다 — 그들 자체가 에이전트가 되기를 기대합니다. 도구의 코드 생성이 스택과 정확히 일치할 때는 작동합니다. 프로젝트 특정 명명 규칙, 커스텀 컴포넌트 라이브러리, 또는 도구가 알지 못하는 토큰이 있는 디자인 시스템이 있을 때는 작동하지 않습니다.

CONTEXT.md는 기계가 읽을 수 있는 디자인 브리핑입니다. 모든 LLM 이전 디자인 핸드오프에서 Confluence 페이지나 Notion 문서로 존재했던 것인데, 실제로 규칙을 따르는 독자를 위해 구조화된 것입니다.

어떻게 사용하나요

Cursor나 Claude Code에서 figmascope 내보내기를 열면:

  1. 디자인에 관한 프롬프트 전에 컨텍스트에 @CONTEXT.md를 추가합니다.
  2. 작업 중인 화면 JSON을 참조합니다: @screens/home.json.
  3. 토큰을 다루는 경우 @tokens.json을 추가합니다.
  4. 문자열을 다루는 경우 @strings.json을 추가합니다.

CONTEXT.md 제약 조건은 한 번 로드되면 전체 세션에 걸쳐 적용됩니다. 프롬프트마다 다시 추가할 필요 없이 — 처음에 한 번 추가하면 이후 모든 생성의 프레임을 설정합니다.

번들의 다른 아티팩트는 이 시리즈의 나머지 글에서 다룹니다. 토큰 시스템이 Figma 변수가 있는 파일과 없는 파일을 처리하는 방법은 tokens.json 설명부터 시작하거나, Figma 레이아웃이 stack/overlay/absolute/leaf 노드에 매핑되는 방법은 화면별 IR을 참고하십시오. 직접 사용해 보고 싶으신가요? figmascope.dev에서 Figma URL을 붙여넣어 첫 번째 번들을 내보내십시오.