# storefront — 구성 축

## 이 전시물이 다른 이유

앞선 여섯은 도메인이 다르거나(dashboard·inventory·form-survey·landing-page·contacts)
크기가 달랐다(ops-console). 이 전시물은 **아티팩트가 둘**이다.

| | 앞선 여섯 | storefront |
| --- | --- | --- |
| 아티팩트 | **1** | **2** — `storefront-catalog` · `storefront-cart` |
| 턴의 범위 | 화면 하나 | **두 화면에 걸친다** |

시드는 일부러 작다. **잃히기 위해 존재하지 예쁘기 위해 존재하지 않는다.**

## 착수 전 실측이 이 전시물의 물음을 바꿨다

세운 물음은 *"이 패밀리가 다중 화면 앱을 다룰 수 있는가"* 였다. 답은 **이미 다룬다**다:

- 한 문서의 UI 패치 **둘**이 검증을 통과하고 preview 에 **둘 다** 오른다.
- 승인 하나로 apply 하면 **두 화면이 함께** 바뀐다.
- rollback 이 **둘 다** 바이트 복귀한다.
- 월드가 아티팩트마다 **facet fingerprint** 를 따로 갖는다.

즉 계약도 라이브러리도 아티팩트 N개를 전제하고 있다. 못 하는 것은 **이 샘플 호스트**다.

## 못 하는 방식이 요점이다 — 실패가 아니라 침묵

둘째 화면(`storefront-cart`)은 **서고, 바뀌고, 되돌아온다.** 그런데:

- **아무도 그리지 않는다** — 캔버스·프리뷰가 `primaryArtifactId` 하나만 렌더한다.
- **아무도 판정하지 않는다** — 전시물의 `render` 선언에 **아티팩트 축이 없어서**,
  그 화면의 자리·기대 invoke 를 **선언할 자리 자체가 없다**.
- **아무도 보관하지 않는다** — 아카이브의 자립형 뷰어가 하나만 담고, 그 선택은
  `artifacts[primaryArtifactId] ?? Object.values(artifacts)[0]` 라 **지목이 빗나가면
  조용히 다른 것**을 담는다.

그래서 이 화면을 통째로 죽여도 게이트가 전부 초록이다. `smoke-compose` 단언 5·6 이
그것을 *통과가 곧 결함* 어법으로 고정한다.

## 턴

### ① 두 화면에 같은 배송 안내를 넣는다 (scripted)

화면이 하나뿐이면 **저작할 수조차 없는** 종류의 변경이다. `uiEdits` 는 편집마다
`artifactId` 를 지목하므로, 이 턴은 항목을 **둘** 낸다.

**완주 기준**: 두 화면에 문구가 함께 착지하고(단언 3), 롤백이 둘 다 되돌리며(4),
그럼에도 **화면과 판정에는 하나만 나타난다**(5·6).

## 이 전시물이 열어 두는 것

수리는 여기서 하지 않는다. 아티팩트마다 샌드박스를 세우는 일이고, 선택·편집 맥락이
샌드박스를 건너야 하며, 선언 어휘에 아티팩트 축이 생겨야 한다. 자기 RED 를 가진
사이클의 몫이고 — **그 RED 가 지금 이 게이트다.**
