# Recepção aceite → movimento único → consulta SGF Continuação delimitada: [Oficina → saída física conferida](WORKSHOP_STOCK_DELIVERY.md). A prova de recepção deste documento mantém o seu âmbito; a continuação usa outro cenário sintético e não representa um percurso integral instalado. 02/11/2026. `COMMON-RECEIPT-STOCK-SIM-v1`. **Primeiro fluxo de escrita ligado e comprovado:** o circuito real de recepção de Compras valida e confirma uma recepção sintética, delega a gravação física no núcleo comum e o SGF consulta o mesmo movimento no livro de origem. Não se copiou o saldo para outro livro nem se criou uma recepção fictícia no SGF. Continua a [consulta nas duas composições](STOCK_READ_COMPOSITION_DELIVERY.md) e o [plano entre módulos](SGF_MODULE_FLOW_PREPARATION.md). É um incremento delimitado: **a preparação/confirmação de recepções na interface SGF ainda não está entregue**; a autoridade de recepção exercitada é a implementação existente de Compras. O ensaio não equivale à instalação completa do módulo de Compras no ERP. ## Implementação e responsabilidades `packages/inventory-write/src/ReceiptMovementWriter.php` extrai a gravação antes feita directamente em `ReceiptWorkflow`. Há agora uma chamada única pelo adaptador nativo `ReceiptStockMovement`; não há fallback para outro escritor de recepções. O pacote é distribuído como artefacto local verificado em Compras, `packages/inventory-write/releases/0.1.0`. Manifesto SHA-256 **f0b99e591f9a4df135e685f64ceffad77bed259222debe0f34c20f95e3cad800**. A distribuição compara os dois ficheiros com a fonte e recusa substituir uma versão imutável com conteúdo diferente. Não depende da pasta SGF em runtime. O circuito nativo mantém: ordem emitida, recebedor autorizado distinto do emissor, conflito de interesses, quantidades cumulativas, qualidade/rejeição, unidade, mapeamento artigo/armazém, equipamento/peça quando aplicável, lotes, sinais existentes e auditoria. Não foram substituídos por regras sintéticas no motor. A fixture prepara as etapas anteriores como origem sintética; **não comprova novamente todo o procurement anterior à ordem**. O escritor comum exige a transacção do host e uma callback de autorização. Lê a linha/recepção no âmbito certo, confere quantidade física aceite e recebedor original, obtém o hash da origem, bloqueia e revalida esse hash antes de gravar. Usa a unicidade existente de `goods_receipt_item_id`; não precisa de migração de stock nova ou outra tabela de saldos. A fotografia do movimento conserva os campos anteriores e acrescenta referência documental e `inventory_source_hash`. O hash representa a versão dos factos da linha/recepção, não uma versão inventada da ordem. Número/estado final do pai ficam fora do hash porque a finalização ocorre depois na mesma transacção. Mesmo hash/origem recupera o movimento; hash antigo ou movimento histórico incompatível recusa, sem reescrever/adoptar o original. A repetição de recepções antigas pelo circuito existente conserva a sua resolução prévia; não houve importação/replay de histórico. O writer **não faz commit**: recepção, itens, entrada física, lotes, finalização e auditoria continuam na transacção nativa. Não confirma facturas, obrigações, pagamentos ou lançamentos por arrasto. Os restantes movimentos de `StockWorkflow` mantêm os seus serviços existentes; este incremento só extraiu entradas por recepção. ## Ligação ao SGF sem duplicar o efeito O adaptador de consulta SGF recebeu um binding de fonte exclusivamente QA. Para o ensaio, liga ao livro nativo local através de uma **role técnica nova com SELECT apenas em artigos, armazéns e movimentos**, sem leitura das recepções/auditoria, sem escrita, sem poderes de criação de bases/roles, replicação ou bypass. A role tem leitura por omissão e cada consulta usa READ ONLY / REPEATABLE READ. O teste também tentou uma escrita inócua (`DELETE ... WHERE false`) e confirmou recusa, sem alterar dados. Guardas conferem ambiente `testing`, identidade física do SGF, host loopback, porta 55439, nome da base nativa de regressão, role correspondente e cluster. O contexto SGF é mapeado explicitamente para tenant/armazém da origem. A referência cifrada é vinculada também à base/role/cluster efectivos, não só ao nome lógico da ligação. Não se inferem identidades ou empresas por igualdade de números. Parâmetro de armazém fora do binding é recusado. **Isto é uma ligação de observação do ensaio local, não um conector remoto obrigatório do produto.** Permite provar que o consumidor vê o movimento realmente produzido pela recepção, em vez de o simular noutra fixture. A composição final continua a exigir instalação/adaptadores locais do núcleo comum e namespace/contexto delimitados. Nenhuma configuração de origem operacional foi activada; os bindings por omissão permanecem vazios. Falha da ligação/fonte devolve 503 genérico sem SQL, credenciais ou stack trace; depois de reposta, a consulta recupera. A referência/hash da fonte anterior exige actualização quando o livro/contexto muda. A API continua somente de leitura e não tem comando de recepção ou saída física. ## Cenário, evidência e concorrência | Evento sintético na ordem de 10 unidades | Recebido | Aceite | Rejeitado | Efeito físico | | --- | ---: | ---: | ---: | --- | | Primeira recepção com reservas e fundamento | 6 | 4 | 2 | Um movimento de +4 | | Repetição idêntica | Mesmo evento | — | — | Mesmo comprovativo; nenhum movimento/auditoria adicional | | Segunda recepção, totalmente não conforme | 2 | 0 | 2 | Sem movimento | Saldo final desse âmbito: **4 unidades**, um movimento, duas confirmações de recepção auditadas (a aceite parcialmente e a totalmente rejeitada). O pós-check verificou autor/data nas duas auditorias e hash de origem no movimento. O SGF devolveu o ID/referência do **mesmo movimento** e 4 000 milésimos; os contadores do livro de origem e do livro QA SGF não mudaram pela consulta. Reservado, bloqueado e disponível não foram presumidos. Uma falha injectada imediatamente depois do INSERT comum desfez recepção, linhas, movimento e auditoria. A nova tentativa concluiu com um movimento. Num cenário separado, dois processos PHP reais confirmaram a mesma recepção/chave: observou-se a espera `transactionid` e o PID do bloqueador, libertou-se a primeira transacção com commit, e o segundo recuperou o mesmo ID; ficou uma recepção e um movimento. Não se fez confirmação real nem se decidiu qualquer associação protegida. Esta versão preserva a serialização por empresa da origem. Não a remove nem declara maior débito de escrita. Hash/locks/revalidação introduzem trabalho por linha confirmada; esse custo e a duração de locks em recepções grandes **ainda não foram medidos**. Não substituir essa evidência por tempos de listagem nem apresentar a ausência de N+1 na consulta como prova de escalabilidade das escritas. ## Testes e limites da prova | Verificação | Resultado | | --- | --- | | Fluxo nativo, hash/repetição, rollback/retoma e concorrência entre processos | **1 teste / 33 asserções** | | Regressão afectada de recepções/Stock | **31 testes / 193 asserções** | | Recortes de recepção sob controlo de lotes/política | **3 testes / 20 asserções** | | Repetição com o adaptador final sem segundo efeito | **1 teste / 8 asserções** | | Consulta SGF funcional afectada | **2 testes / 77 asserções** | | SGF sobre o livro realmente produzido, RO, falha da ligação e recuperação | **1 teste / 31 asserções** | Passaram também sintaxe e verificação de whitespace. Os casos de lotes cobrem quarentena, repetição exacta, vencimento com rollback e regra de recepção vigente para chegadas futuras. Não se repetiram as suites alheias, os 72 pedidos de carga anteriores, a matriz de associações ou o build: não houve alteração de interface nesta passagem. Foi preciso ajustar o launcher Pest para carregar o `Pest.php` da cópia QA, e não o do caminho de origem; a primeira tentativa falhou na inicialização do teste, antes da fixture. Retomou-se apenas essa prova afectada, na sua base QA. Os testes de recepção e lotes usam bases descartáveis novas próprias e as migrações existentes apenas nelas. Os cenários e a base de ligação foram conservados. O dispatch do adaptador explicita o driver; **a prova deste incremento é PostgreSQL**, sem afirmar validação noutros drivers. [Prova sanitizada, hashes, contadores e pós-checks](proofs/stock-receipt-link-20261102.json). Tokens, credenciais, inputs dos trabalhadores e referências completas da fixture ficam no directório privado. O núcleo de leitura não mudou, pelo que a prova de carga anterior conserva as suas condições/fontes; não mede este fluxo de escrita nem a ligação QA adicional. ## Preservação e próximo incremento Somente bases/roles novas QA e a regressão SGF foram usadas; não se consultaram bases de cliente/demos para este fluxo. O pós-check SGF confirmou zero `stock.view` temporários, restrição anterior reposta e bindings por omissão vazios. Os seis registos protegidos, a cache bloqueada, demonstrações e alterações alheias ficaram intactos; os hashes das provas válidas anteriores foram conferidos. Sem migração/concessão real, activação de candidata Purchasing, publicação, checkpoint ou aceitação presumidos. Próximo incremento: **oficina → consumo de material da empresa**, reutilizando autorização/origem verificada e o escritor de saídas existente, com stock suficiente, material do cliente separado, origem única e correcção por compensação. Permanecem também a preparação/confirmação de recepção na composição ERP SGF, a demonstração persistente própria e a extracção dos restantes movimentos. O ensaio de observação não encerra essas pendências. **Revisão visual e capacidade de implantação continuam pendentes e independentes.** A prova cobre API/kernel e serviços com actores sintéticos, não login/MFA/rede/servidor implantado ou experiência visual. Não se voltou à via de navegador bloqueada.