Referência · SOM 1.0

O envelope

Um único invólucro, compartilhado por todas as mensagens de todas as famílias. É um objeto fechado: campos de nível superior desconhecidos reprovam na validação, e os antigos campos source e signature são rejeitados de saída.

Anatomia

Cada campo, um de cada vez

Clique numa chave para ler o que ela carrega e onde ela costuma pegar as pessoas. Os valores de exemplo seguem o passo 6 do exemplo do furacão desenvolvido na especificação.

{
"som_version": "1.0.0",
"message_id": "0199a1c4-7a2e-7b31-8c55-4d2f9e6a1b07",
"correlation_id": "0199a1c4-0000-7000-8000-000000000911",
"causation_id": "0199a1c4-7a2e-7b31-8c55-4d2f9e6a1b06",
"message_type": "story.context",
"timestamp": "2026-09-11T16:41:00.000000Z",
"originating_system": { "system_id": "ncs-nyc-01", "system_type": "ncs", … },
"topic": "som.story.context.hurricane-2026-0911",
"modification_header": { "story_version": 7, "modified_by": "producer-7" },
"_actors": { … },
"@context": null,
"extensions": { "com.example.desk": "news" },
"payload": { "story_id": "hurricane-2026-0911", … }
}

som_version

obrigatóriostring (semver)

A versão do pacote de schemas à qual o payload está conforme — "1.0.0" para o SOM 1.0.

Apenas informativo: os consumidores NÃO DEVEM ramificar a lógica com base nele. "0.3.2" não é SOM 1.0 — três campos foram retirados antes da ratificação —, então um consumidor não pode tratá-lo como conforme.

Schema: https://storyobjectmodel.com/schema/1.0/envelope.schema.json ↗

Conformidade

A barra é mais baixa do que você pensa

Um sistema está conforme com o SOM 1.0 se toda mensagem que publica é um envelope válido, todo payload valida contra o schema do seu message_type declarado, e ele ignora o que não reconhece. Um sistema de pauta que só publica story.context e só lê avisos está plenamente conforme.

01

Emita "1.0.0", nunca ramifique com base nele

Produtores emitem a versão do pacote com a qual estão conformes; um futuro produtor 1.1 emite "1.1.0". Consumidores não podem mudar de comportamento com base em som_version — isso quebra na 1.1 por definição. E "0.3.2" não é SOM 1.0: o schema deixa o campo aberto, então um consumidor conforme precisa aplicar essa regra por conta própria.

02

message_type é o único discriminador

Escolha o schema do payload por ele. Não pelo topic, por um nome de arquivo, pela identidade do publicador ou pelo formato do payload.

03

Valide format

O JSON Schema trata format como anotação, então a maioria dos validadores aceita "message_id": "NOT-A-UUID" sem nenhum erro. A conformidade exige validação de uuid e date-time — em Node, ajv/dist/2020 mais ajv-formats; em Python, um format_checker e rfc3339-validator.

04

Ignore o que você não reconhece

Chaves desconhecidas em extensions são ignoradas, nunca motivo de rejeição. Um message_type que você não trata também é ignorado — e é isso que permite à 1.x acrescentar famílias sem quebrar ninguém.

05

correlation_id e topic são obrigatórios

correlation_id liga todas as mensagens sobre o ciclo de vida de uma história. topic deve começar com som. — fora isso, a organização dos topics é com você.

+

Diga o que você produz e consome

As implementações deveriam declarar quais famílias publicam e quais leem. É essa declaração, e não o tamanho da implementação, que um integrador precisa. spec/conformance.md ↗

Payload

skill.warning.raised

O que uma skill declarou sobre uma história, colocado na pipeline pelo executor na ferramenta que a acionou (recall). Doze campos obrigatórios, um objeto fechado e dois campos explicitamente proibidos.

{
"warning_id": "0190a000-0000-7000-8000-00000000000a",
"skill_id": "smart-stories/hold-while-flagged",
"skill_version": "0.2.2",
"story_id": "story-verdict-0412",
"scope": "story:story-verdict-0412",
"severity": "hold",
"rule_id": "house-reporting-restriction-hold",
"non_overridable": true,
"affected_fields": ["editorial_gates[].status"],
"detail": "Held off air. … Clears on a clearance at story scope by legal or above.",
"blocks": ["air:story-verdict-0412"],
"skill_warning_ref": "swr-0001",
"content_type": "sync.ai.banner",
"message_type": "skill.warning.raised"
}

warning_id

obrigatóriostring (UUIDv7)

Identidade deste aviso.

O escopo é o nível de disparo

link:{link_id} para uma skill específica de um destino, asset:{asset_id} para um asset, story:{story_id} para a história inteira.

Uma liberação só vale no escopo em que o hold foi declarado: uma liberação de link nunca derruba um hold de story.

Timestamps ficam no envelope

O payload do aviso rejeita tanto timestamp quanto o aposentado instance_ref. Quando o aviso foi levantado é o timestamp do envelope; o que o causou é o causation_id do envelope.

Migração

Vindo da v0.3.2

A 1.0 é uma ruptura limpa — e pequena: pare de emitir três campos retirados, emita som_version: "1.0.0" e ative a validação de formatos. Todos os outros campos, tipos, enums e restrições continuam iguais.

Retirado na 1.0O que era
assets[].voice_countUm inteiro opcional que carregava uma regra de classificação editorial que nunca chegou a ser definida.
assets[].status → FINALIZINGUm membro de enum proposto para uma saída derivada ainda em finalização; nunca ratificado.
transforms[].transform_idUm identificador opcional e estável de auditoria para uma única transformação; ainda em discussão.
Os identificadores mudaram

Todo $id de schema agora é uma URL resolvível que serve o arquivo, como https://storyobjectmodel.com/schema/1.0/story-context.schema.json, estável por toda a vida da 1.x. Os antigos identificadores som.spec/schema/v0.3… nunca foram resolvíveis.

A estrutura é plana

Os três diretórios de versão sumiram: um arquivo por família, sem versão no nome do arquivo. Tudo o que despachava por "v0.3.2" num caminho de schema deve passar a selecionar pela família. authenticity_credential, proposto na v0.3.2, entra na 1.0 como normativo.

spec/migration-from-v0.3.2.md ↗ · spec/compatibility-policy.md ↗

Renomeados e aposentados

Caminhos antigos que não validam mais

Se um produtor ou uma configuração é anterior ao congelamento do envelope na v0.3, estes itens mudaram de lugar — ou são rejeitados pelos schemas 1.0.

AntesAgora
source (envelope)originating_system — o campo antigo é rejeitado sem exceção
signature (envelope)Rejeitado sem exceção. Não existe campo de assinatura.
sources[]editorial_source[] — credibilidade TRUSTED | VERIFIED | ENDORSED | UNVERIFIED
skills_config.broadcasterskills_config.newsroom (a chave antiga é rejeitada)
broadcaster_idRejeitado sem exceção. newsroom_id é opcional na 1.0, derivado de skills_config.newsroom se ausente
collaboration.versioncollaboration.editing_version
content_ref (singular)content_refs[]
instances[]Rejeitado sem exceção. A distribuição é modelada por links e tellings
instance_ref (warning)Rejeitado sem exceção. As saídas definem o escopo via scope: link:, asset: ou story:
ai_enrichments[]Rejeitado sem exceção desde a v0.3.2. Saída generativa que é publicada é uma entrada em assets[] com provenance; afirmações sobre o conteúdo são assertions[]
media_refs[].flow_idsource (tams://store/id) + time_range, ou um locator
editorial_gates[].blocks como stringsObsoleto. Use { "kind": "ASSET" | "PHASE", "ref": … }

Extensions

O lugar definido para o que o padrão não carrega

O envelope, a história e todas as famílias de eventos aceitam um objeto extensions cujas chaves devem casar com com.{vendor}. — qualquer outra coisa reprova na validação. Os consumidores ignoram chaves que não reconhecem.

{
  "warning_id":  "0190a000-0000-7000-8000-00000000000a",
  "skill_id":    "nbcu/editorial-standards",
  "scope":       "link:l1",
  "severity":    "flag",
  "detail":      "Informal term 'cops' in headline.",
  "extensions": {
    "com.nbcu.rationale": "Style guide proscribes informal register in headlines."
  }
}
  • Valores de enum de fornecedores seguem outra convenção: x- mais um token em minúsculas — x-graphics_pack. Ela vale para os registros governados, mas extensíveis, como asset_type, source_type e transform_type.
  • As tags têm seu próprio esquema de fornecedor: com.{vendor}.{name} ao lado de newsroom e iptc-mediatopic.

A seguir: as sete famílias a que essas mensagens pertencem →