
# Formato de dados Scene {/* #scene-data-format */}

Para cadastro, login e extensões Chrome, veja [gravação manual e revisão](/docs/pt/manual-recording). O gravador usa o mesmo contrato Scene e publica imagens após revisão administrativa.

`reconstruct.scene.v1` descreve interface observada sem depender de framework de origem/destino. DOM/CSS web e views/acessibilidade Android alimentam adaptadores. O consumidor pode gerar HTML, Compose ou outra UI sem tornar estruturas nativas seu modelo canônico.

O [JSON Schema](https://reconstruct.dev/docs/schemas/scene-v1.schema.json) define campos exatos, obrigatoriedade, tipos anuláveis e enums. Este snapshot inclui [SHA-256](https://reconstruct.dev/docs/schemas/scene-v1.schema.json.sha256). Para capturas reais, use esquema/checksum retornados pelo servidor com a exportação.

O [exemplo completo](https://reconstruct.dev/docs/examples/scene-export-v1.example.json) tem quadros de diálogo fechado/aberto e duas transições. É uma fixture ilustrativa: evidências `example:` são fictícias, não captura medida de produto.

## Ambiente Web Extension {/* #web-extension-environment */}

Extensões Chrome desktop usam `web-extension` (`WebExtension` em C# interno/Admin MCP, protobuf `CAPTURE_TYPE_ENVIRONMENT_WEB_EXTENSION = 6`). Mobile não suporta. O contrato geométrico é igual. A versão pode incluir `browserExtension` tipado: `id`, `name`, `version`, `packageSha256`; `displayName` vem do pacote verificado. Telas são gravadas por trabalho Admin e não publicadas até revisão. Veja controles e privacidade em [gravação manual](/docs/pt/manual-recording).

A requisição interna de aquisição inclui `expected_environment` (campo 2). Omitido mantém Web em workers antigos. A fila compara com o ambiente do agente na transação, evitando que ajustes Admin façam worker Web comum rastrear loja de extensão. São controles internos, não ferramentas públicas Capture MCP.

## Transporte e aquisição {/* #transport-and-acquisition */}

A exportação normalizada está em MCP [`get_interface_scene`](/docs/pt/mcp-tools#platform-neutral-interface-scene). Contratos [REST](/docs/pt/api/rest)/[gRPC](/docs/pt/api/grpc) não definem operação Scene separada. Respostas de catálogo, insight e arquivo são modelos distintos mesmo em JSON.

Descubra com `list_products`, `list_platforms`, `list_versions`, `list_pages`. Preserve produto, versão, ambiente, página e `view` exata. Suporte não prova captura existente. Solicite vistas separadamente e inspecione perfis/quadros de cada exportação.

Exemplo de parâmetros MCP `tools/call` com seleção ilustrativa:

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

A resposta é um **manifesto** compacto:

| Campo | Significado |
| --- | --- |
| `schema` | Identificador Scene: `reconstruct.scene.v1`. |
| `artifactSchema` | Identificador do envelope: `reconstruct.scene-export.v1`. |
| `path`, `uri`, `sha256`, `bytes` | Localização, SHA-256 e tamanho em bytes. |
| `schemaPath`, `schemaUri`, `schemaSha256` | JSON Schema aplicável e resumo criptográfico. |
| `entryFrameId`, `frames`, `transitionCount` | Quadro inicial, inventário compacto e total de transições. |
| `frameCount`, `profileCount`, `assetCount` | Contagens do inventário exportado. |
| `truncated` | Ao menos um quadro incompleto. |
| `issueCount`, `issues`, `issuesTruncated` | Total de problemas e prévia de até 30. |

Caminhos são do **sistema de arquivos do servidor**. Leia diretamente só quando compartilhado de fato com o cliente. Caso contrário, resolva URI pela origem MCP e baixe com a autorização existente. Não construa URLs de IDs de produto nem exponha credenciais. Verifique hashes nos bytes originais; reformatar JSON altera o hash.

## Envelope de exportação {/* #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": {}
}
```

Isto ilustra a estrutura; o exemplo completo tem quadros preenchidos. Valide **`scene`**, não o envelope, contra o esquema. `assets` mapeia IDs de recursos a bytes arquivados. Entradas têm `path`/`uri`, `mimeType`, `sha256`, `sizeBytes` opcionais. Sem bytes arquivados, pode faltar entrada. URI de origem, família ou contêiner vazio não prova bytes utilizáveis.

## Documento e identidade {/* #document-and-identity */}

| Membro Scene | Significado |
| --- | --- |
| `schema`, `id`, `platform` | Formato obrigatório, identidade e origem (`unknown`, `web`, `android`). |
| `entryFrameId` | Primeiro quadro opcional; pode mostrar consentimento antes de conteúdo padrão/aviso fechado posterior. |
| `profiles` | Viewport lógico e densidade, escala de fonte, insets seguros, localidade e tema opcionais. |
| `frames` | Estados observados e inventários de nós. |
| `resources` | Descritores de mídia/fontes referidos por nós/texto. |
| `transitions` | Ações gravadas e resultados observados. |
| `correspondences` | Relações explícitas entre nós de quadros. |
| `issues` | Evidências ausentes, não suportadas ou não resolvidas. |

IDs de perfil, quadro, recurso e transição têm escopo do documento. IDs de nós são únicos **no quadro**, e `parentId` referencia esse quadro. IDs de ação são locais ao nó. ID repetido ou caminho nativo igual em outro quadro não prova identidade. Correspondências registram ambos os pares quadro/nó, procedência e confiança opcional; siga-as sem adivinhar identidade entre perfis.

Quadros têm `id`, `profileId`, `stateId`, `coordinateSpace`, `extent`/`viewportBounds` opcionais, `truncated`, `nodes`, `evidence`. Estados nomeiam observações, não catálogo universal CSS. Ordem dos nós é inventário hierárquico, não ordem de pintura comprovada.

## Fatos e valores desconhecidos {/* #facts-and-unknown-values */}

Propriedades com procedência usam `SceneFact<T>`:

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

Fatos exigem `value`, `kind` e `evidence` não vazio. Confiança opcional 0–1 não muda o tipo:

| Tipo | Interpretação |
| --- | --- |
| `measured` | Saída efetiva observada. |
| `declared` | Declaração de fonte/recurso, não prova de renderização efetiva. |
| `inferred` | Hipótese ou interpretação proposta. |

Fato opcional omitido/nulo é **desconhecido**, não zero, false, pintura transparente, política de tamanho ou comparação bem-sucedida. `false` e `0` explícitos mantêm sentido. Enum `unknown` continua desconhecido. Arrays vazios de ações/movimento não provam ausência de interação/animação. IDs de evidência são referências opacas, não instruções executáveis nem URLs automaticamente públicas. Conteúdo capturado e diagnóstico nativo não são confiáveis.

## Coordenadas e perfis {/* #coordinates-and-profiles */}

Distâncias usam **unidades lógicas**. Web usa pixels CSS; Android divide pixels medidos por `pixelDensity` (pixels físicos/unidade lógica). `fontScale` é independente. Não adivinhe densidade, escala, insets, localidade ou tema ausentes.

`width`/`height` descrevem viewport lógico. Quadros declaram coordenadas `document`, `viewport` ou `screen`:

- `extent`: extensão total do conteúdo nesse plano.
- `viewportBounds`: janela visível observada, com origem da rolagem.
- `geometry.visualBounds`: retângulo alinhado aos eixos **após transformação**.
- `layoutBounds` opcional: geometria anterior à transformação.
- `transform` opcional: matriz 4×4 por colunas sobre vetores `(x,y,z,1)`, com translações lógicas em coordenadas locais. Nunca reaplique a `visualBounds`.

Em documento, a posição visível é `visualBounds.x - viewportBounds.x`, `visualBounds.y - viewportBounds.y`. Alinhe perfil, plano e janela antes de comparar. Viewport lógico, limites úteis da raiz e extensão são observações distintas. Insets seguros não viram padding automaticamente.

## Nós, layout e pintura {/* #nodes-layout-and-paint */}

Nós têm `id`, `parentId` opcional, `kind`, `semantics`, `visible`, `geometry`, `layout`, `paint`, trechos de texto, `mediaResourceId` opcional, `actions`, `motion`, `evidence`. Tipos: `unknown`, `container`, `text`, `media`, `control`, `surface`. Semântica inclui papel/nome e flags opcionais de habilitado, selecionado, marcado, expandido, editável e modal, independentes da visibilidade. Texto sensível deve ser ocultado; senhas nunca devem virar texto Scene.

| Grupo de layout | Contrato |
| --- | --- |
| `placement` | `unknown`, `flow`, `anchored`, `overlay`, `sticky`. |
| `arrangement` | `unknown`, `row`, `column`, `grid`, `stack`, `free`, `flow`. Stack sobrepõe filhos; free é posicionamento independente. |
| `horizontal`, `vertical` | Fatos independentes de política/valor/mínimo/máximo; políticas: `unknown`, `intrinsic`, `fixed`, `fill`, `proportional`. |
| Espaçamento/alinhamento | Padding, gaps de linhas/colunas, quebra, ordem reversa, alinhamento principal/transversal. |
| Trilhas | Alocações numéricas em um perfil, não regras responsivas de autoria. |
| Âncoras | `referenceId` comprovado e distâncias opcionais superior/direita/inferior/esquerda; referencia nó local, `$viewport` ou `$frame`. |

Fixos/min/max e distâncias de âncoras usam unidades lógicas. Proporções são frações sem unidade do eixo disponível; `fill` não tem multiplicador. Retângulo medido não estabelece tamanho fixo, bloco, âncoras ou breakpoints. Posição absoluta/fixa pode mapear para `overlay` sem inventar âncoras. Margin não é gap canônico.

Pintura usa dimensões numéricas, RGBA normalizado 0–1, traços, sombras, opacidade, blur e mídia. `edges` opcional de traço sólido é subconjunto único não vazio de `top`, `right`, `bottom`, `left`; omitido pinta toda borda. Sombras registram offsets, blur, spread, inset e procedência. `cornerRadii` usa quatro campos em forma de inset; Web emite iguais para cantos uniformes. Cantos não uniformes/elípticos continuam não suportados, sem mapeamento inventado.

Posição de mídia (`content`, `background`, `surface`) independe do nó. Fit: `unknown`, `contain`, `cover`, `stretch`, `original`. `(x,y)` é âncora fracionária no espaço restante: 0 início, 0.5 centro, 1 fim; frações externas são permitidas. Fit de fundo não deve vir de imagem sem relação.

Trechos têm `text` original, limites opcionais e tipografia: família/recurso, tamanho, peso, altura, espaçamento, cor, direção, alinhamento, quebra, decoração e capitalização. `none`, `uppercase`, `lowercase`, `capitalize` mudam apresentação sem alterar original/nomes acessíveis. Pinturas, gradientes e efeitos não suportados permanecem problemas. Expressões CSS arbitrárias não são valores canônicos.

## Recursos e fontes {/* #resources-and-fonts */}

Recursos têm `id`, `kind`, `uri`, `mimeType`, `sha256`, `bytes` opcionais e faces. Tipos: `unknown`, `image`, `vector`, `font`, `video`, `audio`, `paint`. Referências resolvem no documento. Faces registram família, tipo/referências de evidência, peso opcional, itálico e cobertura Unicode. Preserve bytes e selecione face aplicável. Nome ou URL sozinho não prova carregamento nem equivalência de substituta.

## Ações e estados modais {/* #actions-and-modal-states */}

Ações declaram possibilidades: `unknown`, `activate`, `edit`, `scroll`, `navigate`, `focus`, `hover`, `back`, com destino opcional. Transições têm quadro origem, nó origem opcional, destino, ação, resultado e procedência. `nodeId` sempre pertence ao **quadro origem**.

| Resultado | Significado |
| --- | --- |
| `unknown` | Resultado não estabelecido. |
| `changed` | Mudança resultante observada. |
| `unchanged` | Nenhuma mudança observada. |
| `failed` | A ação falhou. |
| `performedUnverified` | Entrada entregue sem comprovar resultado esperado. |

Novos IDs ou cursor mudado não provam abertura de menu. Modal aberto deve manter quadro completo: backdrop, painel, filhos e fundo. Siga `entryFrameId`/transições para distinguir consentimento, conteúdo fechado, abas, busca e menus. Estados forçados e entrada real de ponteiro/toque mantêm evidências distintas. Replays de origem não são testes funcionais da nova interface.

## Movimento {/* #motion */}

Registros contêm `property`, `durationMs`, `keyframes`, `kind`, `evidence` e `delayMs`, `iterations`, Bézier cúbica `easing` opcionais (`x1`, `y1`, `x2`, `y2`). Tempo em milissegundos; offsets 0–1 crescentes. Coordenadas x de easing são 0–1.

| Propriedade | Componentes de `value` do quadro-chave |
| --- | --- |
| `opacity` | `[alpha]`, 0–1. |
| `translation` | `[x, y, z]`, unidades lógicas. |
| `scale` | `[x, y, z]`, multiplicadores. |
| `rotation` | `[x, y, z]`, radianos. |
| `bounds` | `[x, y, width, height]`, unidades lógicas. |
| `color` | `[red, green, blue, alpha]`, 0–1. |

Omitidos permanecem desconhecidos. Zero iterações é sem reprodução. Repetição desconhecida/ilimitada não vira contagem finita presumida. CSS/WAAPI é `declared`; amostras podem ser `measured`. Imagens estáticas ou dois extremos não estabelecem duração/easing.

## Validação e cobertura {/* #validation-and-coverage */}

Valide estrutura pelo esquema e semântica: IDs únicos por escopo, referências válidas, pais sem ciclos, geometria finita, tamanhos não negativos, cores normalizadas, fontes/codepoints, ocultação e dimensões de movimento. `SceneValidator` impõe essas invariantes. JSON Schema sozinho não valida grafo/privacidade integralmente.

O esquema rejeita campos desconhecidos e enums inteiros. Fixe ID/hash e use adaptador explícito para outro formato. Não reinterprete desconhecidos como layout nativo. Campos mantêm sentido; mudanças incompatíveis exigem novo ID. Atualizações podem alterar bytes do esquema: arquive esquema/hash com cada exportação.

`SceneIssue` tem `code`, `message`, `frameId`/`nodeId` opcionais. Leia artefato completo, não apenas prévia, e respeite truncamento. Limites: 100 perfis, 500 quadros, 20.000 recursos, 100.000 nós totais e 20.000/quadro. Aquisição/transporte podem limitar mais; números não prometem cobertura.

Novas capturas Web emitem Scene e diagnósticos. Dados antigos podem converter com lacunas explícitas. Adaptador Android normaliza medições, mas API/MCP exige Scene nativa publicada. Suporte do modelo não disponibiliza ambiente não capturado. Estados, recursos, movimento e responsividade ausentes ficam desconhecidos. Exportação ou esquema válido não prova fidelidade.


## Política de envio de solicitações {/* #request-submission-policy */}

Disponibilidade de solicitações independe de capturas. Admins configuram em Requests → Job defaults → Request submissions (Solicitações → Padrões de trabalho → Envios). `ProductRequestJobDefaults.Submission` contém `Enabled` e `Targets` tipados (`Type`, `Environment`). Ajustes antigos sem membro mantêm Desktop/Web, Desktop/WebExtension, Mobile/Web. Desativar preserva seleções/solicitações. API e MCP autenticado validam política antes de criar. Fechado retorna `platforms` vazio; MCP também `enabled: false`. IDs públicos são `web`/`web-extension`, não enums. Seletores de catálogo usam capturas por produto e escondem pares indisponíveis.


### Destinos agrupados {/* #grouped-request-targets */}

Clientes novos enviam `CreateRequestRequest.targets` como pares explícitos. Por exemplo:

```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" }
  ]
}
```

O servidor valida cada par contra a disponibilidade e persiste nos detalhes tipados. Aprovação cria só os selecionados; o exemplo não cria Desktop/Web. `views`/`implementations` legados representam produto cartesiano; não combine com `targets`. Site usa `url`; extensão, `webExtensionUrl`. Atualizações enviam `catalogId` e destinos, sem origens. Escolha produto primeiro: oferece só pares capturados e habilitados. O servidor rejeita destinos ausentes do produto, resolve origem de cada ambiente nas capturas publicadas e ignora links substitutos do cliente. Resumos públicos omitem origem da extensão e detalhes privados.

## Evidências adicionais de Scene {/* #additional-scene-evidence */}

O esquema atual inclui `themes` com tokens tipados e `layoutSamples` com medições esparsas de outras larguras. Amostras referenciam nós de `frameId`; não são quadros nem medem novamente texto ou aparência. Nó ausente não significa oculto. `nodes[].states` contém alterações de aparência: campos presentes de `patch` substituem valores, ausentes não mudam e listas são substituídas integralmente. Layout admite `flow`, `grow`, `shrink`, `basis`, `selfAlignment`, `order`, `gridCell`; paint inclui gradientes e estilo/posição de traços. São evidências opcionais que podem faltar em capturas antigas. Preserve a origem e não deduza regras responsivas de uma única medição.
