
# Scene データ形式 {/* #scene-data-format */}

登録、ログイン、Chrome 拡張機能のフローは[手動記録と審査](/docs/ja/manual-recording)を参照してください。レコーダーは同じ Scene 契約を使用し、Admin の審査後にだけ画像を公開します。

`reconstruct.scene.v1` は、元または出力先の UI フレームワークに依存せず、観測したインターフェースを記述します。Web の DOM/CSS や Android のビュー／アクセシビリティーはアダプターへの入力です。利用側は、それらのネイティブ構造を正規データモデルとして使わずに、HTML、Compose、その他の UI を生成できます。

ダウンロード可能な [JSON Schema](https://reconstruct.dev/docs/schemas/scene-v1.schema.json)は、正確なフィールド名、必須項目、null 許容型、列挙値を定義します。このドキュメントのスナップショットには [SHA-256](https://reconstruct.dev/docs/schemas/scene-v1.schema.json.sha256) が付属します。実際のキャプチャーには、稼働中のサーバーがそのエクスポートとともに返すスキーマとチェックサムを使用してください。

[完全な例](https://reconstruct.dev/docs/examples/scene-export-v1.example.json)には、閉じた／開いたダイアログのフレームと 2 つの遷移が含まれます。これは説明用のフィクスチャーです。`example:` の根拠は架空であり、製品の測定済みキャプチャーではありません。

## Web Extension 環境 {/* #web-extension-environment */}

デスクトップ Chrome 拡張機能のキャプチャーは、環境 `web-extension`（内部 C#／Admin MCP では `WebExtension`、protobuf の値は `CAPTURE_TYPE_ENVIRONMENT_WEB_EXTENSION = 6`）を使います。モバイルはこの環境に対応しません。Scene のジオメトリー契約は同じです。キャプチャーバージョンには、型付きの `browserExtension` メタデータとして `id`、`name`、`version`、`packageSha256` を含めることができ、`displayName` は検証済みパッケージから取得します。画面は Admin ジョブが記録し、審査まで非公開です。操作者の制御とプライバシーの境界は[手動記録](/docs/ja/manual-recording)を参照してください。

内部エージェントのジョブ取得要求には `expected_environment`（フィールド 2）が含まれます。省略時は従来のワーカー向けに Web を維持します。キューはジョブ取得トランザクション内でエージェントの環境との一致を確認するため、Admin 設定を変更しても通常の Web ワーカーが拡張機能ストアのページを巡回することはありません。これらのキュー制御は、公開 Capture MCP ツールではありません。

## 転送と取得 {/* #transport-and-acquisition */}

正規化エクスポートは、現在 MCP の [`get_interface_scene`](/docs/ja/mcp-tools#platform-neutral-interface-scene) から利用できます。公開 [REST](/docs/ja/api/rest)／[gRPC](/docs/ja/api/grpc) カタログ契約に、個別の Scene 操作は現在ありません。カタログ、インサイト、保存済みファイルの応答は、転送が JSON でも別のモデルです。

`list_products`、`list_platforms`、`list_versions`、`list_pages` でキャプチャーを探します。選択した製品、バージョン、環境、ページ、保存済みの正確な `view` を維持します。対応するプラットフォームオプションは、キャプチャーの存在を証明しません。保存済みビューは個別に要求し、各エクスポート固有のプロファイルとフレームを確認します。

例示の選択を使った MCP `tools/call` のパラメーター例です。

```json
{
  "name": "get_interface_scene",
  "arguments": {
    "product": "example-product",
    "version": "1",
    "environment": "web",
    "page": "settings",
    "view": "mobile"
  }
}
```

応答は簡潔な**マニフェスト**です。

| フィールド | 意味 |
| --- | --- |
| `schema` | Scene 識別子：`reconstruct.scene.v1`。 |
| `artifactSchema` | エンベロープ識別子：`reconstruct.scene-export.v1`。 |
| `path`, `uri`, `sha256`, `bytes` | エクスポートの場所、SHA-256、バイト数。 |
| `schemaPath`, `schemaUri`, `schemaSha256` | 適用する JSON Schema とそのダイジェスト。 |
| `entryFrameId`, `frames`, `transitionCount` | エントリーフレーム、簡潔なフレーム一覧、遷移数。 |
| `frameCount`, `profileCount`, `assetCount` | エクスポート内容の件数。 |
| `truncated` | 少なくとも 1 つのフレームが不完全です。 |
| `issueCount`, `issues`, `issuesTruncated` | 問題の総数と、最大 30 件のプレビュー。 |

パスは**サーバーのファイルシステム**に属します。そのファイルシステムが実際にクライアントと共有されている場合だけ、直接読み取ってください。それ以外は、返された URI を MCP のオリジンに対して解決し、接続の既存の認可を使ってダウンロードします。製品 ID から転送 URL を組み立てたり、認証情報を公開したりしないでください。ハッシュは元のバイト列で検証します。JSON を再整形するとハッシュが変わります。

## エクスポートのエンベロープ {/* #export-envelope */}

```json
{
  "schema": "reconstruct.scene-export.v1",
  "scene": {
    "schema": "reconstruct.scene.v1",
    "id": "example/1/web/settings/mobile",
    "platform": "web",
    "entryFrameId": "frame-0",
    "profiles": [],
    "frames": [],
    "resources": [],
    "transitions": [],
    "correspondences": [],
    "issues": []
  },
  "assets": {}
}
```

これは構造の例です。完全な例にはデータ入りのフレームがあります。Scene JSON Schema に対して検証するのは、エンベロープではなく **`scene`** です。`assets` は Scene のリソース ID を保存済みバイト列に対応付けます。各項目には任意の `path`/`uri`、`mimeType`、`sha256`、`sizeBytes` が含まれます。バイト列が保存されていない場合、リソースにアセット項目がないことがあります。参照元 URI、ファミリー名、空のメディアコンテナーだけでは、利用できるバイト列の存在を証明できません。

## ドキュメントと識別 {/* #document-and-identity */}

| Scene のメンバー | 意味 |
| --- | --- |
| `schema`, `id`, `platform` | 必須の形式、ドキュメントの識別、元のプラットフォーム（`unknown`、`web`、`android`）。 |
| `entryFrameId` | 任意の最初に観測したフレーム。後で閉じられる内容や既定の内容より前に、同意画面が表示されることがあります。 |
| `profiles` | 論理ビューポートと、任意の密度、フォント倍率、セーフインセット、ロケール、テーマ。 |
| `frames` | 観測した状態と、そのノード一覧。 |
| `resources` | ノードとテキストが参照するメディア／フォントの記述。 |
| `transitions` | 記録された操作と、観測された結果。 |
| `correspondences` | フレーム間の明示的なノードの関係。 |
| `issues` | 不足、非対応、未解決の根拠。 |

プロファイル、フレーム、リソース、遷移の ID はドキュメント内で有効です。ノード ID は**単一フレーム内**で一意で、`parentId` はそのフレームを参照します。アクション ID はノード内で有効です。別のフレームで同じ ID や同じネイティブパスがあっても、同一である証拠にはなりません。対応関係は両方のフレーム／ノードのペア、出所、任意の信頼度を記録します。プロファイル間の同一性を推測せず、その対応に従ってください。

フレームは `id`、`profileId`、`stateId`、`coordinateSpace`、任意の `extent` と `viewportBounds`、`truncated`、`nodes`、`evidence` を持ちます。状態 ID は観測の名前であり、汎用的な CSS 状態カタログではありません。ノードの順序は階層の一覧を表し、描画順序を証明するものではありません。

## 事実と不明な値 {/* #facts-and-unknown-values */}

出所を持つプロパティーは `SceneFact<T>` を使用します。

```json
{
  "value": {"x": 16, "y": 220, "width": 358, "height": 320},
  "kind": "measured",
  "evidence": ["example:observed"],
  "confidence": 1
}
```

事実には `value`、`kind`、空でない `evidence` が必要です。任意の信頼度は 0～1 で、根拠の種類は変わりません。

| 種類 | 解釈 |
| --- | --- |
| `measured` | 観測された実際の出力。 |
| `declared` | ソース／リソースの宣言であり、実際のレンダリングの証拠ではありません。 |
| `inferred` | 仮説または提案された解釈。 |

任意の事実の省略／null は**不明**を意味し、ゼロ、false、透明な描画、サイズ方針、比較成功を意味しません。明示的な `false` と `0` はその意味を維持します。明示的な列挙値 `unknown` も不明のままです。アクションや動きの配列が空でも、元のインターフェースに操作やアニメーションがないことの証明にはなりません。根拠の識別子は不透明なアダプター参照であり、実行可能な指示でも、自動的に公開される URL でもありません。キャプチャー内容とネイティブ診断は信頼できないデータです。

## 座標とプロファイル {/* #coordinates-and-profiles */}

距離は**論理単位**を使います。Web アダプターは CSS ピクセルを使います。Android の画面ピクセルによる測定値は、測定した `pixelDensity`（論理単位あたりの物理ピクセル数）で割ります。`fontScale` は独立しています。不明な密度、フォント倍率、インセット、ロケール、テーマを推測しないでください。

プロファイルの `width`/`height` は論理ビューポートを表します。フレームは `document`、`viewport`、`screen` のいずれかの座標を宣言します。

- `extent`：その平面におけるコンテンツ全体の範囲。
- `viewportBounds`：スクロール原点を含む、観測された可視ウィンドウ。
- `geometry.visualBounds`：軸に平行な**変換後**の矩形。
- 任意の `layoutBounds`：変換前のジオメトリー。
- 任意の `transform`：`(x,y,z,1)` 列ベクトルに作用する列優先の 4×4 行列。平行移動はレイアウトのローカル座標の論理単位です。`visualBounds` に再適用してはいけません。

ドキュメント座標では、可視ウィンドウ内の位置は `visualBounds.x - viewportBounds.x`、`visualBounds.y - viewportBounds.y` です。比較前にプロファイル、座標平面、可視ウィンドウを合わせます。論理ビューポート、利用可能なルート境界、コンテンツの範囲は別々の観測です。セーフインセットは自動的にパディングとして適用されません。

## ノード、レイアウト、描画 {/* #nodes-layout-and-paint */}

ノードは `id`、任意の `parentId`、`kind`、`semantics`、`visible`、`geometry`、`layout`、`paint`、テキストラン、任意の `mediaResourceId`、`actions`、`motion`、`evidence` を持ちます。種類は `unknown`、`container`、`text`、`media`、`control`、`surface` です。セマンティクスにはロール／名前と、任意の enabled、selected、checked、expanded、editable、modal フラグが含まれます。これらは可視性とは独立しています。機密のテキストはマスキングし、パスワードを Scene のテキストに含めてはいけません。

| レイアウトのグループ | 契約 |
| --- | --- |
| `placement` | `unknown`, `flow`, `anchored`, `overlay`, `sticky`. |
| `arrangement` | `unknown`、`row`、`column`、`grid`、`stack`、`free`、`flow`。stack は子を重ね、free は独立した配置を表します。 |
| `horizontal`, `vertical` | 独立した方針／値／最小／最大の事実。方針は `unknown`、`intrinsic`、`fixed`、`fill`、`proportional` です。 |
| 余白／配置 | パディング、行／列のギャップ、折り返し、逆順、主軸／交差軸の配置。 |
| トラック | 単一プロファイルの行／列の数値的な割り当てであり、記述されたレスポンシブルールではありません。 |
| アンカー | 根拠のある `referenceId` と、任意の上下左右の距離。フレーム内のノード、`$viewport`、`$frame` を参照します。 |

固定／最小／最大とアンカーの距離は論理単位です。比例値は参照する軸の利用可能な範囲に対する無次元の比率で、`fill` に倍率はありません。測定した矩形だけでは固定サイズ、包含ブロック、アンカー、ブレークポイントを確定できません。ネイティブの absolute／fixed 配置は、アンカーを作り出さずに `overlay` に対応付けられます。マージンは正規の要素間ギャップではありません。

描画は数値寸法と 0～1 に正規化された RGBA、ストローク、影、不透明度、ぼかし、メディア参照を使います。単色ストロークの任意の `edges` は、`top`、`right`、`bottom`、`left` の重複のない空でない部分集合で、省略すると境界全体を描画します。影はオフセット、ぼかし、広がり、内側、出所を記録します。`cornerRadii` は現在、インセットと同じ形の 4 フィールドを使います。Web アダプターは均一な角に同じ値を出力します。不均一／楕円の Web の角は、架空の対応付けをせず非対応のままにします。

メディア配置（`content`、`background`、`surface`）はノードの種類とは独立しています。フィットは `unknown`、`contain`、`cover`、`stretch`、`original` です。位置 `(x,y)` は残りの空間における比率のアンカーで、0 が先頭、0.5 が中央、1 が末尾に揃います。範囲外の比率も可能です。背景のフィットを無関係なコンテンツ画像から取得してはいけません。

テキストランは元の `text`、任意の境界、タイポグラフィーを含みます。タイポグラフィーはファミリー／フォントリソース、サイズ、太さ、行高、字間、色、方向、配置、折り返し、装飾、大文字・小文字の変換です。変換（`none`、`uppercase`、`lowercase`、`capitalize`）は元の文言やアクセシブル名とは独立して表示を変えます。非対応の描画／グラデーション／テキスト効果は問題として残します。任意のネイティブ CSS 式は正規のレイアウト値や描画値ではありません。

## リソースとフォント {/* #resources-and-fonts */}

リソースは `id`、`kind`、任意の `uri`、`mimeType`、`sha256`、`bytes`、フォントフェイスを持ちます。種類は `unknown`、`image`、`vector`、`font`、`video`、`audio`、`paint` です。ノードとタイポグラフィーのリソース参照はこのドキュメント内で解決します。フォントフェイスはファミリー、根拠の種類／参照、任意の太さの範囲、斜体状態、Unicode コードポイントの範囲を記録します。保存済みのバイト列を維持し、適用可能なフェイスを選んでください。ファミリー名や URL だけでは、意図したフォントが読み込まれたことや、代替フォントが同等であることは証明できません。

## アクションとモーダル状態 {/* #actions-and-modal-states */}

アクションは操作の手掛かりを宣言します。種類は `unknown`、`activate`、`edit`、`scroll`、`navigate`、`focus`、`hover`、`back` で、任意の移動先を持ちます。遷移には元のフレーム、任意の元ノード、先のフレーム、アクション、結果、出所があります。`nodeId` は必ず**元のフレーム**に属します。

| 結果 | 意味 |
| --- | --- |
| `unknown` | 結果は確認されていません。 |
| `changed` | 結果としての変化を観測しました。 |
| `unchanged` | 変化は観測されませんでした。 |
| `failed` | アクションが失敗しました。 |
| `performedUnverified` | 入力は送られましたが、期待する結果は証明されていません。 |

新しいスナップショット ID やキャレットの変化だけでは、メニューが開いたことを確認できません。開いたモーダルは、背景、パネル、子、背後の内容を含む観測済みフレーム全体を維持します。`entryFrameId` と遷移をたどり、同意、閉じた後の内容、ダイアログのタブ、検索、展開したメニューを区別します。強制状態の測定と実際のポインター／タッチ入力は、別の根拠として維持します。元データの再生は、新しく生成したインターフェースの機能テストではありません。

## 動き {/* #motion */}

ノード／遷移の動きの記録には `property`、`durationMs`、`keyframes`、`kind`、`evidence` と、任意の `delayMs`、`iterations`、三次ベジェの `easing`（`x1`、`y1`、`x2`、`y2`）が含まれます。時間はミリ秒、オフセットは 0～1 の昇順です。イージングの x 座標は 0～1 です。

| プロパティー | キーフレームの `value` の成分 |
| --- | --- |
| `opacity` | `[alpha]`, 0–1. |
| `translation` | `[x, y, z]`、論理単位。 |
| `scale` | `[x, y, z]`、倍率。 |
| `rotation` | `[x, y, z]`、ラジアン。 |
| `bounds` | `[x, y, width, height]`、論理単位。 |
| `color` | `[red, green, blue, alpha]`, 0–1. |

省略したオプションは不明のままです。繰り返し回数がゼロなら再生しません。不明または無制限の繰り返しを、推測した有限回数にしてはいけません。CSS/WAAPI の宣言は `declared`、観測したサンプルは `measured` にできます。静止画像や 2 つの端点だけでは、時間やイージングは確定できません。

## 検証と網羅範囲 {/* #validation-and-coverage */}

エクスポートのスキーマで構造を検証した後、意味を検証します。スコープ内の ID の一意性、有効な参照、親関係の非循環性、有限のジオメトリー、非負のサイズ、正規化された色、フォント／コードポイント範囲、マスキング、動きの次元を確認します。バックエンドの `SceneValidator` はこれらの追加の不変条件を強制します。JSON Schema だけでは、完全なグラフ検証やプライバシー検証はできません。

現在の構造スキーマは未知のフィールドと整数の列挙値を拒否します。識別子とハッシュを固定し、別の形式バージョンには明示的なアダプターを使います。不明なデータをネイティブレイアウトとして解釈し直してはいけません。既存フィールドの意味は維持し、互換性のない意味の変更には新しい形式識別子が必要です。サーバー更新により適用されるスキーマのバイト列が変わる場合があります。保存する各エクスポートとともにスキーマとハッシュを保持してください。

`SceneIssue` は `code`、`message`、任意の `frameId`/`nodeId` を持ちます。マニフェストのプレビューだけでなく成果物全体を読み、フレームの切り詰めを考慮してください。現在の検証上限は、100 プロファイル、500 フレーム、20,000 リソース、合計 100,000 ノード、1 フレームあたり 20,000 ノードです。取得／転送にはより低い制限がある場合があり、この数値はキャプチャーの網羅性を保証しません。

新しい Web キャプチャーは、ネイティブ診断とともに Scene を出力します。古い Web データは不足を明示して変換できます。Android アダプターはネイティブ測定値を正規化できますが、API/MCP アクセスには公開済みのネイティブ Scene が必要です。データモデルが対応していても、未取得の環境は利用可能になりません。不足する状態、リソース、動き、レスポンシブ観測は不明のままです。エクスポートの成功やスキーマの妥当性は再現の忠実度を証明しません。


## リクエスト送信ポリシー {/* #request-submission-policy */}

リクエストの利用可否とカタログのキャプチャーの有無は独立しています。管理者は Requests → Job defaults → Request submissions で設定します。保存される `ProductRequestJobDefaults.Submission` は `Enabled` と型付きの `Targets`（`Type`、`Environment`）を含みます。このメンバーがない既存設定は、Desktop/Web、Desktop/WebExtension、Mobile/Web の既定値を維持します。送信を無効にしても、選択内容と既存リクエストは保持されます。Platform API と認証済み MCP の両方が、リクエスト作成前に現在のポリシーを検証します。受付停止中、request-options は空の `platforms` 一覧を返し、MCP はさらに `enabled: false` を返します。公開の環境 ID は列挙名ではなく `web` と `web-extension` のままです。カタログの選択欄は製品ごとのキャプチャーの有無を使い、利用できないペアを非表示にします。


### グループ化されたリクエスト対象 {/* #grouped-request-targets */}

新しいクライアントは、明示的なプラットフォーム／環境のペアとして `CreateRequestRequest.targets` を送信します。例：

```json
{
  "requestType": "PRODUCT_REQUEST_TYPE_ADD",
  "url": "https://metamask.io/",
  "webExtensionUrl": "https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn",
  "targets": [
    { "view": "desktop", "implementation": "web-extension" },
    { "view": "mobile", "implementation": "web" }
  ]
}
```

サーバーは現在のリクエスト利用可否に照らして各ペアを検証し、型付きリクエスト詳細に保存します。承認時に作成されるのは選択したペアだけです。この例は Desktop/Web ジョブを作成しません。古いクライアント向けには `views` と `implementations` も引き続き受け付け、その直積を表します。`targets` と併用しないでください。ウェブサイトの参照元は `url`、拡張機能ジョブは `webExtensionUrl` を使います。更新リクエストでは、参照リンクを付けず、既存の `catalogId` と対象を送ります。最初に製品を選びます。Platform はその製品でキャプチャーされ、現在リクエストが有効なプラットフォーム／環境のペアだけを提示します。サーバーは製品にない対象を独立して拒否し、各環境の参照元を製品の公開済みキャプチャーから解決して、クライアントの代替リンクを無視します。公開のリクエスト要約では、非公開のリクエスト詳細とともに拡張機能の参照元を省略します。

## 追加の Scene 証拠 {/* #additional-scene-evidence */}

現在のスキーマは型付きトークンを持つ `themes` と別幅の疎な計測 `layoutSamples` を含みます。サンプルは `frameId` のノードを参照し、フレームではなく、文字や外観を再計測しません。未計測ノードは非表示とは限りません。`nodes[].states` は外観の差分です。存在する `patch` フィールドは置換し、省略は維持、リストは全体を置換します。Layout は `flow`、`grow`、`shrink`、`basis`、`selfAlignment`、`order`、`gridCell`、paint はグラデーションと線の形式・位置を扱います。古いキャプチャーにないことがある任意の証拠です。来歴を保持し、1つの計測からレスポンシブ規則を推測しないでください。
