# Changelog de divergência: BCP vs UCP

Registro consciente do fork. Atualizado a cada sync com o upstream.

## Baseline

- **BCP deriva do UCP `2026-04-08`** (spec vendorada em `schemas/` e `discovery/`).
- `discovery/profile_schema.json` (documento de well-known) vendorado; único ajuste
  foi `$id` `ucp.dev` → `bcp.dev.br`. Diferente do `ucp_sdk`, geramos o pydantic dele
  (`bcp_sdk.models.discovery.profile_schema`), porque o índice valida profiles em runtime.
- `services/` (OpenAPI/OpenRPC) ainda **não** vendorados (ver README); `handlers/`
  agora traz o primeiro handler original do BCP (`pix`), não um vendorado do UCP.

## O que seguimos do UCP

- JSON Schema draft 2020-12, reverse-domain naming, `extends`/`allOf`.
- Versionamento por data, open enums, `ucp_request` (omit/optional/required por op).
- Authority binding, serialização canônica (JCS) para assinatura.
- Anotação `ucp_request` mantida com o mesmo nome (convenção do validador, não namespace).

## O que renomeamos

- `dev.ucp.*` → `br.dev.bcp.*` (nomes de capability, `extends`, chaves de `$defs`).
- `https://ucp.dev/...` → `https://bcp.dev.br/...` (em `$id` e URLs).
- Mantidos como estão: nomes de arquivo (`ucp.json`), o campo de envelope `ucp`, e a
  palavra-chave `ucp_request` (renomear quebraria o validador sem ganho).

## O que divergimos de propósito

Extensões brasileiras (originais do BCP, sem linhagem UCP — Copyright 2026 BCP
Authors), todas por `allOf` sobre os recursos base, sem editar nenhum schema
vendorado. Requisitos e base legal em `docs/specification/*.md` e no documento
de requisitos das issues #6/#7/#8:

- `br.dev.bcp.shopping.fiscal_identity` (`schemas/shopping/fiscal_identity.json`):
  CPF/CNPJ do comprador no `buyer` + identidade do vendedor (CNPJ, razão social,
  endereço) obrigatória em toda resposta de checkout/order (CDC art. 31;
  Decreto 7.962/2013). Estende checkout e order.
- `br.dev.bcp.shopping.tax` (`schemas/shopping/tax.json`, NCM em `types/ncm.json`):
  detalhamento tributário por line item (tipo aberto: icms/iss/difal/ibs/cbs/is,
  alíquota, base, valor, nível federativo) + NCM (Lei 12.741/2012). O `authority`
  expõe o nível federativo ao consumidor (com `subnational` para o IBS) e serve
  de base ao split payment 2027+. Sem config de perfil: regime é atributo de
  AgentFacts e o cálculo roda atrás do port da RFB. Estende checkout e order.
  A obrigatoriedade da linha `tax` em `totals` é regra normativa da spec, não
  constraint de schema (`contains` quebra a geração de modelos, testado).
- `br.dev.bcp.shopping.nfe` (`schemas/shopping/nfe.json`): referência da NF-e no
  pedido (chave de acesso, DANFE/XML, data de emissão; modelo e protocolo já
  embutidos na chave). Só a referência, minimização LGPD. Opcional (dispensa do
  MEI, LC 123/2006 art. 26). Estende order.
- `br.dev.bcp.shopping.returns` (`schemas/shopping/returns.json` +
  `types/returns_config.json`): arrependimento art. 49 CDC e logística reversa —
  motivo, prazos legais (confirmação ≤5 dias, Decreto 7.962 art. 4º), código de
  postagem reversa; política declarável no `config` do profile. Estende order.
- `br.dev.bcp.pix` (`schemas/handlers/pix/pix.json`): payment handler de Pix
  Cobrança única (QR dinâmico, fluxo push), original do BCP. `allOf` sobre
  `payment_handler.json` e sobre os tipos base de instrumento/credencial
  (`payment_instrument`, `payment_credential`, `binding`). Escopo: cobrança
  única; Pix Automático/ITP fica para handler irmão futuro. Divergência de
  layout: o handler concreto vive em `schemas/handlers/` (não numa árvore
  `source/handlers/` separada como o UCP), porque o bcp-index é autoridade e
  implementação de referência e o handler alimenta a geração de modelos.

Validação (substitui o plano original de `validate_examples.py`, que **não existe
no upstream** — premissa corrigida): CLI oficial `ucp-schema` (crates.io).
Confirmado empiricamente na v1.3.0: o authority binding é genérico e aceita
`br.dev.bcp.*` ↔ `bcp.dev.br` sem fork nem config; `lint` valida os `examples`
embutidos (regra E008); fixtures de ponta a ponta em `fixtures/{valid,invalid}/`
rodam via `scripts/validate.sh`.

## O que decidimos NÃO puxar do upstream

- (nada ainda; registrar por release UCP futura, com a razão.)
