Compare commits

...
Author SHA1 Message Date
nala a2de725901 feat(irpc): prepare compatible L6 schedules and scoped form mappings in QA
tests / ci (push) Canceled after 0s
2026-10-25 22:29:06 +02:00
nala 82d0d05887 Record installed normal colecta and concrete L6 remainder separate from L7 L8 2026-10-25 22:11:55 +02:00
nala 2f684e5984 Calculate scoped normal IRPC colecta and preserve annual settlement boundary
tests / ci (push) Canceled after 0s
2026-10-25 21:58:59 +02:00
nala b8d45796dd Determine scoped IRPC taxable base from documented own loss balances 2026-10-25 21:46:59 +02:00
nala 5e02c23af8 Complete scoped IRPC taxable profit with explicit evidence states
tests / ci (push) Canceled after 0s
2026-10-25 21:33:51 +02:00
nala 664c88c8f7 Start scoped normal IRPC adjustments and record operational L5 installation 2026-10-25 21:22:42 +02:00
nala 7a11c4ef8f Specify AT interest and CER questions and label simulation assumptions
tests / ci (push) Canceled after 0s
2026-10-25 21:04:53 +02:00
nala acf8ec3cb5 Prepare documented interest calculations and separate MRFTA working cases 2026-10-25 20:52:21 +02:00
nala 5fa64bc0f4 Preserve exact original BM source bytes in the QA archive
tests / ci (push) Canceled after 0s
2026-10-25 20:19:53 +02:00
nala 85e3cd5c7b Prepare scoped MRFTA and documented compensatory interest with QA recovery 2026-10-25 20:19:08 +02:00
nala ce746d889d Implement scoped IRPC reliefs and PT-MZ royalties with QA recovery evidence
tests / ci (push) Canceled after 0s
2026-10-25 19:56:32 +02:00
nala 2b33a1c343 Identify IRPC income category and retention nature in Portuguese
tests / ci (push) Canceled after 0s
2026-10-25 19:20:44 +02:00
nala 4d6f828230 Group compatible IRPC withholding rates and reuse delivered FX selection 2026-10-25 19:14:46 +02:00
nala da0d8abb47 Start scoped IRPC L5 withholding workflow with document and payment reuse 2026-10-25 18:45:04 +02:00
nala 5c0cb25cea Preserve documented liberatory settlement when changing ISPC route
tests / ci (push) Canceled after 0s
2026-10-25 18:18:03 +02:00
nala 3dda7130ee Group ISPC occasional operations, excess acquisition treatment and 2026 formal preparation in QA 2026-10-25 18:12:34 +02:00
nala 6af7092e83 Reconcile installed L3 receipt and preserve current balance in compatible ISPC QA
tests / ci (push) Canceled after 0s
2026-10-25 17:15:52 +02:00
nala 49b448eb47 Prepare compatible ISPC quarterly QA on L3 baseline without experimental P001 changes 2026-10-25 17:11:58 +02:00
119 changed files with 12677 additions and 9 deletions
+3
View File
@@ -12,3 +12,6 @@ database/data/economic-references-lot-01.json text eol=crlf
CHANGELOG.md export-ignore
README.md export-ignore
.github/workflows/browser-tests.yml export-ignore
# Preserve the original archived BM HTML bytes and whitespace.
docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html -text -diff
@@ -353,3 +353,208 @@ Fecho do delta privado na homologação: candidata `fb4e7d89` integrada em `65ed
Actualização do mesmo requisito: os 28 rascunhos têm edição, leitura privada, prévia sem guardar, recuperação e publicação/retirada pela interface em QA, preservando originais, origem e revisões. Seis testes/1.000 asserções, TypeScript e build passaram; publicação positiva apenas em transacções revertidas. Pacote privado v2 preparado com 28 originais e proveniência; não transportado nem publicado na homologação. Guia, permissões existentes, lacunas de imagens, dependências da entrega e reversão na secção «Legado — edição e leitura dos 28 rascunhos em QA» do manual. Pedido funcional expresso da Tempo; hash de âmbito, prévia e controlo de versão são escolhas técnicas, sem novo papel/aprovador. Conserva o saldo de 20 públicos aceites e dois originais incompletos, sem repetir provas ou fechar a integração integral.
Referência do acervo legado, 22/10/2026: a lista única `v2/auditoria-portal/legado-correspondencia-integral.md` e o CSV existente reconciliam 50 identidades (20 publicados, 28 por integrar no destino, um vazio, um sem título). 20/20 páginas conferidas por HTTP anónimo/identidade/origem; cartões de Turismo observados no destino. Os 28 restantes avançaram para rascunhos internos QA, com ClamAV real e repetição idempotente, sem publicação. Recibo e limites no manual, secção «Legado — correspondência integral e avanço privado QA». As duas lacunas editoriais foram confirmadas no original. Não fecha a integração integral nem substitui revisão editorial por prova HTTP; nenhuma alteração activa nesta passagem.
## 25/10/2026 — L5: dispensas e convenção demonstradas em QA
Base de código `2b33a1c3`, ramo `codex/irpc-l5-reliefs-qa-20261025`. O último relatório de instalação mantém o portal nessa entrega; este candidato não executa instalação. O inventário anterior de L3, ISPC, câmbio, fontes e provas aceites é reutilizado. Comparação do delta: sem alteração nesses módulos, em schema/migrações, configuração ou permissões; sem escrita na base activa. As correcções de codificação que tinham atingido trechos históricos durante a preparação foram retiradas do delta; os registos anteriores são conservados.
**Executável:** dispensa 68(d) para serviços/uso de equipamento 67(1)b/g com natureza por conta, titular sujeito a IRPC relativamente ao rendimento; dispensa 68(f) para rendas de sociedade de gestão de imóveis próprios fora da transparência fiscal 6(1)c; limite convencional de 10% sobre royalties/uso de equipamento qualificados PT–MZ, não digitais, titular residente convencional em Portugal, beneficiário efectivo, sem EP em Moçambique, devedor residente em Moçambique e montante sem excesso por relações especiais. As condições são dados documentados do caso, sem aprovador adicional. A selecção de regra não é substituída por texto livre ou taxa manual. Outros ramos continuam separados.
Reutilizados contraparte, residência/EP, documento, qualificação, montante e conversão da linha. Diploma, artigo, período, documentos e condições ficam no mesmo livro e no histórico. Alterar a prova invalida apenas a correspondência do resultado afectado. A dispensa produz retenção zero justificada, apresentada como dispensa, sem isentar o rendimento nem gerar crédito anual. Informação insuficiente, negativa, período incompatível ou artigo divergente fica indeterminada, sem zero/taxa reduzida presumidos. A existência de prova de entrega numa linha dispensada pede reconciliação sem apagar o pagamento.
**Demonstração:** Wayfinder `wayfinder:generate --with-form`, pelo wrapper QA guardado `tools/irpc-reliefs-qa.php routes`; TypeScript passou; compilação completa QA passou. Nove testes novos e cinco verificações dirigidas de compatibilidade IRPC passaram. API privada: um teste/17 verificações, base `simulator_fiscal_delta_20261021_test`, loopback55441, transacção com rollback. Resultados 68(d),68(f), convenção e informação insuficiente recuperados com documentos/histórico. Relatório de retenções, exportação de preparação e dossier financeiro conferidos a partir da recuperação da API. Corrigida a associação da secção «IRPC — retenções» à secção financeira do dossier: a linha existia, mas era omitida nessa apresentação. UI sintética do componente real demonstra cálculo, gravação/recuperação local e relatório; esta prova local é distinta da API privada.
**Reprodução:** gerar routes/actions com `php tools/irpc-reliefs-qa.php routes`; executar `node --test tests/frontend/irpc-reliefs.test.mjs` (produz a amostra sintética); executar `php tools/irpc-reliefs-qa.php test`. Usar PHP8.5/Node24 e dependências existentes. `tsc --noEmit`; compilação `INVESTMOZ_QA_BUILD=1 vp build` no ramo QA. Os módulos gerados são artefactos locais, sem edição manual ou commit.
**Saldo na mesma matriz:** restantes alíneas68, categorias digitais/residentes não correspondidas, outras convenções/Estados e casos com EP, dividendos/juros ou excesso por relações especiais mantêm correspondência própria. Juros de mora, rectificações, agregação, rubricas/CER e preenchimento do MRFTA permanecem discriminados. O cálculo convencional não declara cumpridas as formalidades de accionamento, recepção ou aceitação AT. Não são transportados formulários portugueses21-RFI para obrigações moçambicanas. Pendências condicionam apenas os casos dependentes. L5, IRPC e IRPS não estão integralmente concluídos. L3/ISPC/câmbio não foram retestados; as suas provas são reutilizadas. Entrega conjunta preparada apenas para os recortes demonstrados. Instalação futura segue o procedimento Git e os controlos de destino/backup/restauro já existentes.
Recibo: `docs/investmoz/simulations/irpc-l5-reliefs-qa-20261025.json`; provas locais em `outputs/irpc-reliefs/`.
## 25/10/2026 — dispensas IRPC e convenção PT–MZ instaladas pelo Git
Instalada `ce746d88`, com `2b33a1c3` preservada como release anterior. Backup fresco2026-10-25T18:00:39Z:174 tabelas e369 ficheiros/configuração;restauro isolado em contentor sem rede/55441 passou. Quatro ficheiros de execução conferidos,28 protegidos L3/ISPC/câmbio e29 originais preservados. Schema,permissões e configuração iguais;zero migrações/importações. As172 tabelas de negócio mantêm checksums;apenas cache operacional e sessões anónimas das verificações foram reconciliadas. O mínimo de espaço do instalador foi reposto pelo arquivo e verificação de dependências de5 releases antigas,sem tocar na actual/anterior nem apagar dados/backups.
Manifesto público/revisão servida,8marcadores compilados e simuladorHTTP200 conferidos. Provas QA aceites reutilizadas;CI habitual do procedimento Git passou. Sem ampliar a cobertura:68(d/f) e royalties/uso de equipamento PT–MZ nos casos efectivamente demonstrados. Juros,MRFTA e restantes casos continuam na mesma matriz;L5 permanece parcial. Seguimento em QA separado,sem instalar novos cálculos. Recibo:`irpc-l5-reliefs-delivery-20261025.json`.
## 25/10/2026 — juros e preenchimento MRFTA: incremento QA após ce746d88
O portal mantém a entrega instalada `ce746d88`, com `2b33a1c3` preservada;recibo de instalação `irpc-l5-reliefs-delivery-20261025.json`. Seguimento isolado em `codex/irpc-juros-mrfta-qa-20261025`,sem nova instalação. Reutilizadas as provas aceites;29 originais e29 ficheiros protegidos conferidos por hash. Sem delta de schema,configuração ou permissões.
**Preenchimento:** quadros1–7 do MRFTA de preparação,um mês/ano;identidade fiscal reutilizável entre livros sem sobrescrever edições nem misturar NUIT distintos. Base,taxa,imposto,documentos e entregas vêm do cálculo IRPC guardado. Agrupamento apenas da mesma rubrica/taxa/CER. Retenções sofridas,dispensas e outros períodos ficam separados. CER requer referência aplicável;os números de campos do M/39 antigo não são convertidos em códigos de receita. Rubricas digitais/especiais desconhecidas e múltiplas taxas na mesma rubrica permanecem discriminadas. Quadros8/9 não são assinados/preenchidos pelo portal. Exportação HTML de preparação,não alteração do PDF oficial nem declaração submetida.
**Juros:** Decreto9/2008,25/35,PDF6/8,p121/123 identifica MAIBOR12meses+2p.p.;BM documenta a descontinuidade da publicação. Não foi obtido parâmetro fiscal sucessor aplicável2026;MIMO/Prime não o substituem. Implementada transcrição de juros compensatórios de liquidação documentada,com período,data,montante e referência;ou ausência de atraso quando entrega integral e datas/prazo documentados coincidem. Informação insuficiente não vira zero. Juros de mora continuam por implementar. O subtotal do principal permanece disponível;total do formulário fica indeterminado enquanto faltarem juros,CER,completude ou situação de outras rubricas (IRPS/autónoma),sem isenções ou créditos presumidos. A completude é um dado da preparação,não novo aprovador organizacional.
**Prova do delta:**12 testes novos+1 de apresentação IRPC;TypeScript e compilação QA passaram. API privada1teste/14verificações com rollback no55441;preparação→gravação→recuperação→relatório/dossier. UI real em exemplo sintético:preparação,gravação/recuperação local,informação insuficiente e download HTML;prova API separada. CER999 é fictício de teste,não taxa/código oficial activado. Exemplo:principal20000MZN,entrega3000,juros documentados500,total17500;alterar provas conserva histórico e desactualiza a preparação. Não foram repetidas manualmente suites L3/ISPC/câmbio.
**Saldo:**cálculo automático dos juros e taxa aplicável2026,juros de mora,catálogo CER integral,rubricas digitais/especiais,mistura de taxas e obrigações IRPS/autónomas fora do recorte. Limita apenas as parcelas dependentes;L5/IRPC/IRPS continuam parciais. Recibo `irpc-juros-mrfta-qa-20261025.json`;provas locais `outputs/irpc-mrfta/`.
Reprodução QA: `php tools/irpc-mrfta-qa.php routes`; `node --test tests/frontend/irpc-mrfta.test.mjs`; `php tools/irpc-mrfta-qa.php test`. PHP8.5,Node24,dependências existentes;alvo e identidadeQA guardados antes de fornecedores/testes.
## 25/10/2026 — entrega5fa64bc0 instalada;seguimento restrito a juros/CER em QA
Instalada pelo Git a revisão exacta `5fa64bc0`,com `ce746d88` preservada como release anterior. Backup fresco2026-10-25T18:28:38Z;174tabelas e369ficheiros/configuração;restauro isolado sem rede/55441 passou. Quatro ficheiros de execução,29protegidos e30originais conferidos. Schema,permissões e configuração iguais;zero migrações/importações. As172tabelas de negócio mantêm checksums;apenas cache operacional e sessões anónimas da instalação/verificação foram reconciliadas. Revisão/manifesto públicos,8marcadores compilados e simuladorHTTP200 passaram. Provas aceites reutilizadas,sem nova ronda manual;CI habitual do instalador passou.
Cobertura instalada:preparação por período,registo de juros documentados e relatório/exportação MRFTA. Registar não significa calcular automaticamente;CER/rubricas desconhecidos continuam identificados sem preenchimento presumido. Não houve submissão ou aceitação AT. Seguimento isolado apenas de juros automáticos eCER/rubricas;L5continua parcial,L3/ISPC/câmbio preservados. Recibo:`irpc-mrfta-delivery-20261025.json`.
## 25/10/2026 — seguimento QA restrito: juros automáticos e casos CER/rubricas
Portal instalado em `5fa64bc0`,com `ce746d88` preservada;recibo `irpc-mrfta-delivery-20261025.json`. Novo ramo `codex/irpc-interest-cer-qa-20261025`,sem instalação. Não foram reabertos outros saldos L5.
**Juros:** nova aritmética racional diária por parâmetros documentados do caso:taxa anual final,fonte/fundamento fiscal,vigência na data de liquidação,base anual,arredondamento do total e ocorrência. Nenhum valor vem pré-definido. Intervalos começam no dia posterior ao prazo documentado;entregas reduzem a base após o seu dia e o pagamento integral pára encargos. Contagem por ano/base365/366 e arredondamento só conforme convenção preenchida com referência. Definitiva e por conta retida cobertas neste recorte;por conta não retida e mora mantêm regra própria. Sem perfil completo,juros indeterminados e principal preservado. A taxa10%,base365 e convenções dos testes são fictícias,sem activação de parâmetro fiscal2026. O registo de liquidação documentada da entrega instalada mantém significado e histórico.
**CER/rubricas:** separação estável por período,rubrica,taxa e CER,com documentos e referências. Fichas de trabalhoHTML independentes conservam as pendências globais;não são declarações autónomas,anexos oficiais nem uma taxa média. Teste integrado distingue retenções20%/10% e CERfictícios999/998;juros por perfil permanecem demonstráveis,mas o total do formulário continua indeterminado pela transposição de rubricas distintas. Ausência de código ou referência continua identificada,sem preenchimento presumido. Nenhum catálogo CER oficial foi acrescentado.
**Compatibilidade/provas:** campos novos adicionais conservam os modos conhecidos pelo leitor5fa64bc0. Prova só de leitura/gravação exacta do novo payload nesse leitor:retenções actuais e nova preparação histórica,sem executar novamente cálculos antigos. Preservados31ficheiros de execução e30originais por hash. TypeScript,buildQA e13testes novos passaram;API1teste/19verificações com rollback em55441. UI:parâmetro fictício explícito,sem taxa→indeterminado,gravação/recuperação,relatório e download de casos20%/999 e10%/998. Relatório do dossier a partir da recuperação API. Provas aceites L3/ISPC/câmbio e5fa64bc0 reutilizadas;sem nova ronda manual das suites antigas.
**Saldo,apenas os mesmos dois pontos:** (1)corresponder fonte/parâmetro fiscal vigente2026 e convenções aplicáveis,além dos ramos mora/por conta não retida fora desta aritmética;(2)corresponder catálogo CER/rubricas ainda pendentes e procedimento oficial para taxas/códigos distintos. O inventário oficial AT189documentos foi consultado por metadados,não relido integralmente;nenhuma taxa/código foi inferido de rascunho,número de campo,agregado orçamental,MIMO ouPrime. L5 continua parcial. Recibo `irpc-interest-cer-qa-20261025.json`;provas em`outputs/irpc-interest-cer/`.
Reprodução do delta em QA: `php tools/irpc-interest-cer-qa.php routes`;`node --test tests/frontend/irpc-interest-cer.test.mjs`;`php tools/irpc-interest-cer-qa.php test`. Dependências existentes,PHP8.5/Node24;alvo QA guardado antes dos fornecedores/testes.
## 25/10/2026 — esclarecimentos concretos para a AT (AUD-SIM-INT02, L5 parcial)
Esta discriminação desenvolve os mesmos dois pontos; não cria outra matriz nem reabre provas aceites. Base instalada: `5fa64bc0`; funcionalidade demonstrada em QA: `acf8ec3c`. Os exemplos abaixo são perguntas de aplicação, não parâmetros ou códigos oficiais. Não foram enviados à AT por este registo.
| Dúvida na mesma matriz | Parâmetro ou correspondência exacta em falta / esclarecimento a obter | Exemplo para acompanhar o esclarecimento | Comportamento enquanto falta |
|---|---|---|---|
| J1 — taxa e vigência | Valor anual final aplicável na data de liquidação em 2026, incluindo eventual acréscimo; série/diploma sucessor da referência MAIBOR 12 meses + 2 p.p., fonte, início e fim de vigência (`annualRate`, `rateSource`, `fiscalBasis`, `validFrom`, `validTo`). | Retenção definitiva de 7 300 MZN, prazo documentado 20/11/2026 e liquidação em 30/11/2026: qual taxa anual final usar? Os 10% do ensaio são fictícios. | Sem taxa predefinida; não substituir por MIMO/Prime. Perfil completo permite apenas simulação pelos dados introduzidos. |
| J2 — contagem diária | Base anual aplicável: 365, 366 ou dias efectivos por ano (`dayBasis`, `dayBasisRef`); incidência do dia da entrega parcial e divisão de períodos entre anos. | Mesmo principal de 7 300 MZN, entrega de 3 650 em 25/11 e liquidação em 30/11: a redução começa em 26/11? Num intervalo 31/12/2027–02/01/2028, qual denominador em cada ano? | Motor demonstra dia posterior ao prazo, dia da entrega incluído e redução no dia seguinte; só usar como pressuposto de simulação até esclarecer a aplicação. |
| J3 — arredondamento | Método e momento oficiais: total ou parcela/dia, cêntimos, metade por excesso ou outra convenção (`rounding`, `roundingRef`). | 7 300 MZN × taxa fictícia 10,0025% × 10/365 = 20,005 MZN: declarar 20,00 ou 20,01? Arredondar só o total ou cada segmento? | As duas opções do motor são convenções explícitas de simulação; outra convenção mantém o caso por implementar. |
| J4 — retenção por conta não efectuada | Regra e datas específicas dependentes da declaração/liquidação anual, base e limite temporal; não equiparar a retenção efectuada ou definitiva (`retention`, `occurrenceRef`). | Retenção por conta de 7 300 MZN não efectuada em Novembro/2026: até que evento anual se contam juros e sobre que montante? | Ramo indeterminado; não herda a fórmula do ramo demonstrado. |
| J5 — mora | Taxa, fundamento, início/fim, base após pagamentos e articulação com juros compensatórios, evitando duplicação. | Liquidação documentada de compensatórios, com saldo de imposto de 3 650 MZN ainda não pago após o prazo: quando começa a mora e sobre que parcelas? | Mora não calculada; registo de liquidação documentada mantém-se independente. |
| C1 — CER de capitais e prediais por conta | Código CER exacto e referência/versão para cada rubrica “Taxa normal — Rendimentos de capitais e mais valias” e “Taxa normal — Rendimentos prediais”. | Dois pagamentos no mesmo mês: juros de financiamento e renda de imóvel, ambos com retenção por conta: quais CER respectivos? São códigos distintos? | CER por identificar; nome da rubrica já correspondido não prova o código. |
| C2 — CER das quatro rubricas liberatórias | Código CER exacto e referência/versão por rubrica: actividade intelectual/industrial e informações; uso de equipamento; aplicação de capitais e rendimentos prediais; comissões/intermediação/prestação de serviços. | No mesmo período, royalties, aluguer de equipamento, juros e comissão a não residentes: indicar o CER de cada natureza e eventual distinção adicional. | Cada natureza permanece separada; não reutilizar números de campos do M/39 como CER. |
| C3 — rendimentos digitais/especiais | Rubrica MRFTA e CER exactos para cada categoria não correspondida, conforme qualificação fiscal documentada; distinguir de serviços comuns. | Pagamento a não residente por serviço digital já qualificado no livro IRPC: em que rubrica/CER deve ser transcrito? Um serviço comum tem a mesma correspondência? | Categoria sem correspondência continua pendente; não copiar para serviços comuns por aproximação. |
| C4 — taxas diferentes na mesma rubrica | Forma oficial de transcrever várias taxas: linhas adicionais, anexo ou outro procedimento, com indicação dos campos; confirmar se o CER varia com regime/convenção. | Royalties de base 10 000 MZN à taxa interna de 20% e outros de 10 000 à taxa convencional demonstrada de 10%, no mesmo mês: como apresentar bases/impostos sem taxa média? | Duas fichas de trabalho; total oficial permanece indeterminado enquanto depender dessa transposição. |
| C5 — códigos diferentes na mesma rubrica | Forma oficial de conservar códigos distintos no mesmo período/rubrica e regra de totalização/entregas; obter os códigos reais antes de preencher. | Duas parcelas agrupáveis por rubrica mas com CER distintos segundo documentos do caso: uma ou várias linhas/guias? Nos ensaios, 999/998 são apenas marcadores fictícios. | Separar período/rubrica/taxa/CER; não inventar declarações autónomas nem reconhecer marcadores como oficiais. |
**Entrega funcional independente:** aritmética pelos pressupostos explicitados, reconciliação de entregas, gravação/recuperação/relatório e fichas separadas podem acompanhar a entrega. Interface e exportações identificam simulação e CER introduzido sem validação por catálogo; referência digitada não equivale a confirmação fiscal. Não activar taxa ou catálogo global por esta entrega. A ausência de dados conserva indeterminação e principal. As respostas da AT poderão completar apenas as células correspondentes, com fonte e vigência, sem outra pesquisa genérica ou nova aprovação inventada.
**Preservação:** L3, ISPC, câmbio, `ce746d88` e `5fa64bc0` conservam provas aceites; nenhum caso aceite foi reaberto. L5 permanece parcial. O presente delta de apresentação/documentação não altera schema, API, permissões, originais ou regras de retenção.
## 25/10/2026 — L5 operacional no âmbito demonstrado; entrega 7a11c4ef
Instalado pelo Git `7a11c4ef8f06ef149eb0488be3cd0749dc609bd0`, sobre `5fa64bc0`, sem força, migrações ou importações. Backup fresco em 25/10/2026 19:14:23 UTC, restaurado em PostgreSQL isolado (rede nenhuma/porta55441):174 tabelas por contagem/checksum. Conferidos4ficheiros do delta,31protegidos,30originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões conservados.172tabelas de negócio iguais;cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação. Versão5fa64bc0 conservada como anterior;L3,ISPC,câmbio e provas aceites preservados. Arquivadas e verificadas dependências de8versões antigas para respeitar espaço mínimo,sem eliminar fontes,dados ou backups nem modificar versões actual/anterior.
Revisão/manifest públicos,8marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,872testesfrontend,tipo/build;sem outra ronda manual das provas aceites. Recibo:`irpc-interest-cer-delivery-20261025.json`.
**L5 fica operacional apenas no âmbito demonstrado**, incluindo preparação por período,registo de juros documentados,simulação por pressupostos explícitos e fichas separadas porCER/rubrica/taxa. Não confirma fiscalmente juros nem converte códigos provisórios em correspondências oficiais. As dez dúvidas J1–J5/C1–C5 da secção anterior acompanham a reunião com a AT;permanecem pendentes e não foram enviadas por esta operação. Sem informação nova,não reabrir a pesquisa desses pontos. Não declararL5 integralmente concluído.
**Sequência autorizada:**L6—IRPC normal,começando pela ponte do resultado financeiro aos ajustamentos documentados. Retenções/créditos anuais,amortizações,perdas e colecta conservam desenvolvimento próprio;nenhuma pendênciaL5 bloqueia o primeiro recorte independenteL6.
## 25/10/2026 — L6 iniciado em QA: primeiros ajustamentos ao resultado financeiro
Base instalada7a11c4ef;L5 operacional apenas no âmbito demonstrado. Primeiro recorteL6 reutiliza a ponte financeira reconciliada por oportunidade,receitas/custos discriminados e resultado antes de imposto. Corresponde explicitamente12meses aJan–Dez2026,MZN,sujeito residente no regime geral fora de transparência/regimes especiais. Projecção com pressupostos,não demonstração contabilística confirmada. Art17(1)é enquadramento da ponte,não equivalência automática do resultado antes de imposto ao lucro tributável.
Implementados acréscimos integrais36(1)c de multas/encargos por infracções sem origem contratual e juros compensatórios já incluídos no custo de origem. Documento/linha,qualificação,montante e inclusão têm suporte/pressuposto expresso. Não classifica juros comerciais nem multas contratuais por aproximação,não importa juros simuladosL5 como despesa efectiva. Limites por custo da origem e duplicação documental previnem dupla contagem. Encargo já excluído não é acrescentado de novo. Lacuna limita a respectiva parcela;acréscimos independentes continuam disponíveis,resultado parcial agregado indeterminado se houver parcela não resolvida.
Exemplo sintético:resultado financeiro6480MZN,multa100 e juros compensatórios20 incluídos;acréscimos120,resultado parcial6600. Sem suporte da multa:apenas20 demonstrados,resultado parcial indeterminado. Lucro tributável,matéria colectável e imposto permanecem indeterminados em todos os casos. Outros ajustamentos,custos/variações patrimoniais,amortizações,perdas,deduções/colecta,créditos anuais eM20/M22 seguem por recortes próprios;EP/regimes especiais,outra moeda/exercício/horizonte não abrangidos.
Prova do delta:7testes novos;APIprivada1teste/19asserções comrollback naQA55441;routes/actions gerados pelo procedimentoWayfinder;TypeScript/buildQA passaram. UI real:cálculo,gravação/recuperação local,relatório,informação insuficiente e download;API demonstrada separadamente,dossier gerado da recuperaçãoAPI. LivroL6 separado mantém payloadL5 e restante histórico;alterar plano/entradas torna resultado histórico sem o apagar.32ficheiros anteriores protegidos e30originais sem alteração;integração mínima emsimulation-form/project-dossier/project-dossier-report. Provas aceites não repetidas. Recibo:`irpc-l6-adjustments-qa-20261025.json`;QA isolada,sem instalaçãoL6.
Fonte adicional necessária apenas paraL6:exemplar oficialAT intitulado19/2009 contém tambémLei20/2009;PDF4/p272(16),36(1)a–i mantidas ealíneasj–n aditadas,conferido visualmente. Lei4/2012PDF2/3 e19/2013PDF1/2 mantêm36(1)c. Não reabre as dez dúvidasL5,que ficam paraAT até informação nova. L5 eL6 não integralmente concluídos.
## 25/10/2026 — L6: percurso delimitado até ao lucro tributável demonstrado em QA
Base instalada `7a11c4ef`; primeiro recorte QA `664c88c8` preservado. A continuação reutiliza o plano reconciliado, o exercício, a oportunidade e os ajustamentos existentes. Não obriga a reintroduzir os montantes financeiros. Âmbito: projecção de Janeiro a Dezembro de 2026, MZN, sujeito residente no regime geral, com referência expressa de que o cenário cobre o sujeito passivo/exercício completo. Uma oportunidade parcial não se transforma automaticamente no total da empresa.
Cada linha do resultado exige qualificação ordinária e suporte: proveitos do exercício (18/20), custos remanescentes indispensáveis e documentados (22), sem outras exclusões/limites declarados. Os acréscimos 36(1)c reutilizam documentos e parcelas já registados. Seis grupos conservam a situação das variações patrimoniais positivas/negativas fora do resultado, outras correcções de rendimentos/custos, diferenças de periodização e operações especiais. **Valor conhecido (incluindo zero), ausência declarada com suporte e informação em falta são estados distintos.** Ausência não pode apagar uma origem financeira positiva ou descartar um montante já preenchido. Um valor conhecido não zero sem tratamento implementado permanece visível e impede apenas o fecho dependente, sem ser aplicado por presunção.
No caso ordinário delimitado, resultado financeiro + acréscimos fundamentados = lucro tributável simulado quando a conferência anual está completa e os outros efeitos são expressamente ausentes ou de valor conhecido zero. Exemplo sintético: 6480 + multa100 + juros compensatórios120 = 6700 MZN. Os 120 são um custo/pressuposto qualificado já incluído na origem; não são juros automaticamente calculados ou fiscalmente confirmados por L5. Falta de prova da variação patrimonial negativa mantém o lucro indeterminado, conservando resultado6480 e acréscimos220. Variação conhecida500, depreciação positiva ou juros financeiros remanescentes mantêm correspondência específica pendente. Sem acréscimos, uma conferência completa pode conservar o resultado financeiro; resultados negativos não são convertidos em zero nem em crédito/perda reportável.
Prova do delta: 9 testes novos; API privada 1 teste/38 verificações, criação → alteração com If-Match → recuperação, com rollback na QA isolada55441. Wayfinder gerou routes/actions; TypeScript e buildQA passaram. UI real: cálculo, gravação/recuperação local, valor conhecido zero, ausência, informação em falta, contradição e exportação HTML. Relatórios/dossiers dos casos conhecido e incompleto gerados a partir da recuperação efectiva da API. Versão2 adicional mantém o snapshot/resultado1 de664c88c8 legível e actual sem o recalcular; mudanças nas entradas desactualizam apenas o novo resultado e conservam histórico. Preservados33ficheiros anteriores de execução e31originais por hash;integrações anteriores de formulário/dossier não alteradas neste delta. Provas aceites L3/ISPC/câmbio/L5 reutilizadas, sem nova ronda manual.
**Preparação conjunta para entrega pelo Git:** primeiro recorte664c88c8 e continuação até lucro tributável, sobre7a11c4ef, com pacote/manifest e delta conferido. Não instalado nem integrado em main por esta preparação. Backup/restauro fresco e conferência do destino fazem parte da instalação posterior; não reutilizar como fresco o backup da entregaL5. Recibo `irpc-l6-taxable-profit-qa-20261025.json`; provas `outputs/irpc-l6-profit/` na QA isolada.
Matéria colectável, perdas reportadas, deduções, colecta, créditos de retenção e M20/M22 continuam fora deste percurso; L6 não está integralmente concluído. L5 permanece operacional no âmbito demonstrado; J1–J5/C1–C5 ficam para a AT e só limitam os casos efectivamente dependentes. Nenhuma nova pesquisa de taxas/CER de L5 foi feita.
## 25/10/2026 — entrega conjunta L6 até lucro tributável instalada:5e02c23a
Instalado pelo Git `5e02c23af863485f6881e409c8704ec7e7573cc9`, sobre `7a11c4ef`, incluindo o primeiro recorte664c88c8. Backup fresco de25/10/2026 19:38:10UTC,restauro isolado sem rede na porta55441:174tabelas conferidas por contagem/checksum. Conferidos6ficheiros do delta,33protegidos,31originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões iguais.172tabelas de negócio preservadas;cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação.7a11c4ef conservado como versão anterior. Arquivadas/verificadas dependências de4versões antigas para margem de espaço,sem eliminar fontes,dados ou backups nem modificar as versões actual/anterior.
Revisão/manifest servidos,10marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,888testesfrontend,tipo/build;sem outra ronda manual das provas aceites. Recibo:`irpc-l6-profit-delivery-20261025.json`.
**Disponível no âmbito demonstrado:**resultado financeiro6480+acréscimos220=lucro tributável simulado6700MZN;estados conhecidos,ausência declarada e informação em falta preservados. **6700MZN não é imposto a pagar.** Matéria colectável,deduções/perdas e colecta não são concluídas por esta instalação. L6 permanece parcial;dúvidasL5J1–J5/C1–C5 só limitam casos efectivamente dependentes. Continuação independente emQA para matéria colectável,sem repetir pesquisa ou provas aceitesL5/L3/ISPC/câmbio.
## 25/10/2026 — L6 matéria colectável: perdas próprias e deduções delimitadas em QA
Base instalada `5e02c23a`, com lucro tributável simulado6700MZN; não é imposto a pagar. A continuação reutiliza esse resultado e a identidade fiscal já disponível na mesma oportunidade, mediante acção expressa que conserva edições. Recorte: sujeito residente no regime geral,2026,método declarativo/directo,perdas fiscais próprias em exercícios anuais ordinários. CIRPC15(1)a/15(2–4) e41(1–7),PDF5/p768(59) ePDF12/p768(66),conferidos nos originais aceites;cadeia de alterações existente reutilizada. Sem novos originais ou pesquisa dos pontosL5.
Livro de perdas por exercício e sujeito:montante fiscal apurado/corrigido,utilizações anteriores,saldo disponível e utilização proposta deste ano,com documentos e completude. Não usa perda contabilística como fiscal. Confere cinco exercícios ordinários posteriores,manutenção/alteração da actividade/objecto no termo do exercício,regime geral e saldo corrigido. Métodos indirectos,períodos especiais/curtos,transparência/isenção parcial,transferências/fusão41-A e correcções pendentes ficam fora do recorte. Expiração/exclusão conhecidas não são apagadas;pedido positivo contra perda excluída exige reconciliação. Utilização proposta é expressa,sem FIFO obrigatório,percentagem inventada ou saldo negativo;excesso sobre saldo/lucro mantém base indeterminada. Simular/gravar não consome o saldo oficial nem actualiza utilizações anteriores.
Exemplo sintético:lucro6700;perda2021apurada1000/utilizada200/saldo800/proposta800;perda2024apurada3000/utilizada500/saldo2500/proposta1500. Dedução2300,**matéria colectável simulada4400MZN**,saldos aritméticos0/1000. **Imposto a pagar permanece indeterminado.** Perda ordinária2020 expira após2025;2021pode ser usada em2026 no recorte demonstrado. Sem perdas/benefícios,ausência expressa e suportada pode conservar base6700;informação em falta não ézero. Benefício conhecido positivo é conservado com referência,mas não subtraído sem regra/condições/limite específicos. Deduções à base15(4) são distintas de efeitos já conferidos no lucro e de créditos à colecta/retenções. Resultado actual negativo permanece conhecido,sem basezero ou reporte automático neste recorte.
Prova do delta:10testes novos;APIprivada1teste/42verificações,criação→alteração comIf-Match→recuperação,rollback naQA55441. Routes/actions peloWayfinder,tipo/buildQA passaram. UI:cálculo4400,gravação/recuperação local,alteração expressa de utilização para700→base4500,repetição sem consumo,sobreutilização recusada,download,informação em falta e benefício positivo conservado sem subtracção. Dossier/HTML gerados da recuperação efectiva daAPI. Versão3 opcional conserva resultado2 actual e históricos1/2;alteração de entradas desactualiza apenas o novo resultado.37ficheiros anteriores de execução e31originais preservados por hash. Provas aceites reutilizadas,sem nova ronda manual. Recibo:`irpc-l6-taxable-base-qa-20261025.json`;QA isolada,sem instalação deste incremento.
L6 continua parcial. Colecta/imposto,créditos anuais,M20/M22,benefícios positivos e casos fora do recorte mantêm desenvolvimento próprio. As dúvidasL5J1–J5/C1–C5 só limitam casos efectivamente dependentes;nenhuma taxa de juros ou CER provisório foi promovido a confirmação fiscal.
## 25/10/2026 — L6 colecta normal demonstrada em QA; entrega conjunta com a matéria colectável
Portal mantém `5e02c23a`. A continuação parte da QA `b8d45796` e reutiliza a matéria colectável actual, sem reintroduzir montantes. No recorte de sujeito residente em regime normal/MZN, exercício anual de01/01/2026 a31/12/2026, o enquadramento explícito do artigo61(1) aplica a taxa geral32%. A fonte/versão, período, classificação e suporte/pressuposto do caso são guardados. Campo por identificar ou caso especial não recebe taxa geral por aproximação; a matéria colectável conhecida permanece disponível.
**Sequência demonstrada:**lucro tributável simulado6700 → matéria colectável simulada4400 → colecta simulada4400×32%=1408MZN → **saldo final a pagar ou recuperar indeterminado, âmbitoL8**. Retenções, pagamentos e créditos do fecho anual não são abatidos nem reconciliados nesta etapa. Colecta não é saldo final. O campo legado `tax` continua nulo e o novo modelo guarda `colecta` separadamente; `finalBalance` mantém pagar/recuperar nulos, não zero.
Taxa32% conferida no CIRPC Lei34/2007,PDF17/p768(71). Lei4/2012 altera61(2); Lei20/2022PDF1/p2731 mantém61(1) e delimita medidas temporárias61(2) até31/12/2025; Lei12/2025PDF18/20 não altera61(1) e distingue61-A. Taxas reduzidas, benefícios, tributação autónoma e mais-valias continuam com tratamento próprio, mesmo se uma percentagem coincidir. Nenhuma extensão temporal/benefício foi inferida. A aritmética é racional exacta; eventual fracção de cêntimo é conservada sem arredondamento fiscal inventado. Não preenche/submeteM20/M22.
Prova do delta:8testes novos;APIprivada1teste/40verificações com criação→alteraçãoIf-Match→recuperação e rollback naQA55441. Wayfinder gerou routes/actions;TypeScript e buildQA passaram. UI real:base reutilizada,colecta1408,taxa/período/enquadramento visíveis,sequência ordenada,gravação/recuperação local,download e casos especiais/informação em falta sem taxa presumida. Dossier/HTML dos casos conhecido e incompleto gerados da recuperação efectiva daAPI. Versão4 opcional conserva versões1/2/3 e o resultado3 actual sem recálculo;mudanças nas entradas desactualizam só o novo resultado e conservam histórico.39ficheiros anteriores daQA e37do portal preservados,31originais sem alteração. Provas aceites reutilizadas,sem outra ronda manual. Recibo:`irpc-l6-colecta-qa-20261025.json`.
**Preparação conjunta compatível:**matéria colectávelb8d45796 e colecta normal neste candidato,base5e02c23a,6ficheiros de execução no delta conjunto. PacoteGit/provas/manifest conferidos apóscommit;sem integração emmain ou instalação nesta preparação. Instalação futura mantém procedimento de destino autenticado,backup/restauro fresco e conferência do delta. L6 continua parcial. Benefícios e casos especiais permanecem explícitos;L8 conserva o fecho anual e as dúvidasL5 só limitam os casos efectivamente dependentes.
## 25/10/2026 — entrega conjunta matéria colectável/colecta instalada:2f684e59
Instalado pelo Git `2f684e59846187f3fb8a338d9d6f6a08cadb4d0d`, incluindo a matéria colectávelb8d45796, sobre `5e02c23a`, sem força, migrações ou importações. Backup fresco de25/10/2026 20:05:19UTC;restauro em base isolada sem rede/porta55441:174tabelas conferidas por contagem/checksum. Conferidos6ficheiros do delta,37protegidos,31originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões iguais;172tabelas de negócio preservadas. Cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação.5e02c23a permanece disponível como versão anterior. Arquivadas/verificadas dependências de4versões antigas para margem de espaço,sem eliminar fontes,dados ou backups nem modificar as versões actual/anterior.
Revisão/manifest públicos,11marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,906testesfrontend,tipo/build. Provas aceites reutilizadas,sem outra ronda manual. Recibo:`irpc-l6-colecta-delivery-20261025.json`.
**Disponível no âmbito demonstrado:**lucro tributável simulado6700→matéria colectável4400→colecta normal32%/2026=1408MZN. **1408MZN não é saldo final a pagar.** A pagar/a recuperar continuam indeterminados emL8. Benefícios/casos especiais anuais sãoL7. O saldo concreto deL6 que justifica «parcial» fica discriminado na secção seguinte;esta actualização substitui,para o estado actual,as pendências genéricas de lucro/base/colecta anteriores já entregues,preservando-as apenas como histórico.
## 25/10/2026 — saldo concreto de L6 após a entrega 2f684e59
Esta discriminação actualiza **AUD-SIM-INT02 na mesma matriz**, com o âmbito L6/L7/L8 já registado no plano consolidado e a leitura do código de `2f684e59`. Não cria outro lote, matriz ou backlog. O estado «L6 parcial» decorre das lacunas funcionais abaixo; **não decorre de faltar o saldo anual de L8 ou os tratamentos de L7**. Os exemplos são casos de fronteira para desenvolvimento, não novos cálculos fiscais confirmados.
**Concluído no âmbito demonstrado e a preservar:** plano financeiro reconciliado → acréscimos36(1)c → lucro tributável6700 → perdas próprias ordinárias2300 → matéria colectável4400 → colecta normal32%/2026=1408MZN. Inclui conhecido/zero/ausência/falta de informação, limites de utilização, gravação/recuperação, histórico, relatório/exportação e indeterminação dos casos dependentes. Não repetir estas provas para fechar os pontos seguintes, excepto se o delta os afectar.
| Saldo que continua em L6 | Evidência concreta no código entregue | Exemplo do caso ainda não coberto | Critério concreto de fecho |
|---|---|---|---|
| Outros ajustamentos ordinários: admissibilidade de custos e correcções aos proveitos | `irpc-normal.ts`, `NormalAdjustment.rule` e `calculateNormal`: apenas multas não contratuais e juros compensatórios36(1)c; `other` fica fora do recorte. `irpc-normal-profit.ts` não aplica `incomeCorrections`/`expenseCorrections` conhecidos não zero. | Encargo de terceiro de250MZN com qualificação36(1)b, ou despesa não documentada36(1)g, incluído no resultado; a correcção não tem regra executável neste livro. A eventual tributação autónoma é outra operação, emL7. | Corresponder a regra geral e condições de cada categoria incluída, calcular acréscimo/dedução/exclusão com sinal e origem, evitar dupla contagem e demonstrar reflexo no lucro, base e colecta. A tributação autónoma que possa coexistir pertence aL7. |
| Dedutibilidade dos juros financeiros ordinários | `irpc-normal-profit.ts`, `closeNormalProfit`: qualquer remanescente não zero de `interest_expense` mantém pendência; só os compensatórios integralmente acrescidos estão cobertos. | Juros de financiamento comercial de120MZN, distintos de juros compensatórios, com finalidade/custo documentados. | Qualificar a parcela ordinária, dedutibilidade e correcção aplicável, conservar os montantes reconhecidos/pagos separados e fechar o lucro sem a equiparar a infracção. Relações especiais/benefícios e regras especiais seguemL7; taxa de juros compensatóriosL5 só é dependência se esse cálculo for efectivamente usado. |
| Reintegrações/amortizações fiscais e diferença face à contabilidade | `irpc-normal-profit.ts`: `depreciation` positivo bloqueia o fecho; não existe mapa fiscal de activos/quotas nesta família de módulos. | Depreciação contabilística120MZN com quota fiscal do activo ainda por corresponder. | Reutilizar activo, base e datas; corresponder método/taxa/limites e afectação ordinários, calcular quota fiscal e diferença para o resultado; manter mapas por activo/exercício e histórico. Incentivos, majorações e regimes especiais de activos seguemL7. |
| Variações patrimoniais e periodização ordinárias de montante não zero | `irpc-normal-profit.ts`, `profitTopics`/`closeNormalProfit`: `positivePatrimonial`, `negativePatrimonial` e `timing` conhecidos não zero conservam valor e impedem o fecho; ausência/zero suportados são o caminho demonstrado. | Variação500MZN fora do resultado, ou diferença temporal300MZN entre reconhecimento contabilístico e exercício fiscal, com natureza concreta documentada. | Corresponder natureza/ano/regra ordinária e decidir inclusão, exclusão ou ajustamento com sinal; impedir reaplicação em dois exercícios; demonstrar cálculo→gravação→recuperação→relatório. Operações especiais/benefícios do tópico `special` não são saldo deL6. |
| Resultado fiscal negativo do próprio exercício | `irpc-normal-base.ts`, `calculateNormalBase`: lucro negativo é conservado, mas a base fica indeterminada; o livro de perdas só admite exercícios anteriores ao de utilização. | Resultado fiscal actual−500MZN conhecido; não é uma perda anterior dedutível a si própria. | Tratar a situação da base/colecta nesse exercício e preparar a perda fiscal própria com origem/ano para utilização futura, conforme regra aplicável, sem confundir ausência de lucro, falta de informação, crédito ou consumo do saldo oficial. Perdas anteriores ordinárias já demonstradas continuam aceites. |
| Extensões do âmbito normal previstas no L6 original | `irpc-normal.ts` fixa12meses/ano civil2026/residente/MZN; `irpc-normal-base.ts` exige exercícios anuais ordinários; a entrada deL6 no plano original inclui exercício fiscal e residência/EP. | Caso de estabelecimento estável sob regime geral, ou período fiscal normal diferente do calendário/horizonte do plano; plano noutra moeda ainda sem reconciliação fiscal anualMZN. | Delimitar os casos normais a admitir, imputação de resultados ao sujeito/EP, datas/períodos e reconciliaçãoMZN usando o câmbio já entregue; demonstrar o percurso dependente. Não reimplementar câmbio, exigir pesquisa de todos os anos históricos ou aplicar automaticamente32% fora do período correspondido. Benefícios/convenções/regimes específicos pertencem aos lotes próprios. |
| Representação fiscal da colecta com fracção de cêntimo | `irpc-normal-assessment.ts` conserva o racional e assinala `centExact:false`; não aplica regra fiscal de arredondamento/transcrição. | Base0,01MZN×32%=0,0032MZN exactos; o caso1408MZN não tem esta ambiguidade e continua válido. | Identificar e executar a convenção aplicável à colecta/representação do formulário, mantendo o exacto e a rastreabilidade do valor transcrito. Não importar por analogia arredondamento de prestações/pagamentosL8 nem criar uma regra por defeito. |
| Correspondência dos dados de L6 aos exemplares M/20/M/22 | A família `irpc-normal*` produz mapaHTML/dossier e exclui expressamente correspondência/transcrição oficial; o âmbito original deL6 inclui M/20/M/22 e diferenças de ediçãoPDF/XLSX. | Resultado, correcções, perdas, base4400 e colecta1408 existem no mapa de trabalho; os respectivos campos/anexos aplicáveis dos exemplares não estão correspondidos no motor. | Cotejar os exemplares já inventariados e mapear apenas os dados deL6 aos campos/versões efectivamente aplicáveis, com prova de preenchimento/recuperação. Os campos de retenções,pagamentos,créditos e saldo final sãoL8. Submissão electrónica/aceitaçãoAT não são presumidas como parte desta correspondência. |
**Encaminhado a L7, sem manter L6 parcial por essa razão:** benefícios/isenções da determinação anual do IRPC, taxas reduzidas/cooperativas, tributação autónoma de despesas e mais-valias61-A, operações especiais, perdas transmitidas/fusão41-A e segregação de regimes especiais. Uma dedução positiva de benefício à base continua sem aplicação no recorte entregue, mas o trabalho substantivo desse benefício éL7, não uma dedução livre nem um novo saldo genérico deL6. A integração posterior usa as interfaces/versionamento já existentes e afecta só os casos dependentes.
**Encaminhado a L8, sem manter L6 parcial por essa razão:** retenções sofridas a imputar ao fecho anual, PPC/PEC e outros pagamentos, créditos/deduções à colecta, dupla tributação quando aplicável, limites/transportes respectivos, reconciliação e saldo final a pagar ou recuperar/calendário. **1408MZN é colecta; pagar e recuperar continuam indeterminados.** Não abater parcelas L5 nem promover os seus códigos/taxas provisórios ao fecho anual nesta entrega.
**Informação do caso, distinta de desenvolvimento em falta:** falta de documento, NUIT, completude anual, montante, prova de saldo ou qualificação dentro de uma regra já implementada mantém o caso indeterminado, mas não constitui por si só outra tarefa deL6. O mesmo vale para a ausência de uma nova prova de uma funcionalidade já aceite. Não exigir nova aprovação genérica das fontes oficiais, novo aprovador ou repetição deL3/ISPC/câmbio/L5. Anos não incluídos no recorte temporal não se tornam automaticamente um projecto de cobertura histórica integral.
**Ordem de continuação delimitada:** ajustamentos ordinários/juros financeiros e amortizações; depois variações/periodização e resultado negativo; ampliar apenas os casos normais concretamente abrangidos e concluir a representação/correspondência dos dados deL6. Cada fecho deve demonstrar o delta e substituir a pendência correspondente nesta mesma linha/nota. Não há estimativa nova nem declaração deL6 integralmente concluído nesta revisão documental.
## 25/10/2026 — L6: três conjuntos compatíveis em QA sobre 2f684e59
Actualização de **AUD-SIM-INT02**, na matriz existente. O percurso instalado em `2f684e59` permanece aceite: lucro6700 → perdas2300 → matéria colectável4400 → colecta1408MZN; saldo anual continua indeterminado emL8. Este incremento é **QA, sem instalação**. Não repete as provas de L3, ISPC, câmbio ou L5; conserva a fotografia4 e o histórico sem recalcular a aceitação anterior.
| Conjunto | Delta executável demonstrado | Efeito e prova nova | Pendência concreta que subsiste |
|---|---|---|---|
| 1 — ajustamentos, juros, variações e periodização | Acréscimos36(1)a/b/g com parcela incluída e origem reconciliada; juros financeiros22c de exploração documentados, sem capitalização/relações/limites especiais; entradas de capital21a e distribuições24c externas ao resultado sem efeito fiscal; variações positivas21 e negativas22/24 ordinárias; especialização18(1) de custo/proveito entre exercício corrente e seguinte. Documento/linha únicos entre mapas, sinal e soma bruta por tema conferidos. | Resultado financeiro6240 + acréscimos anteriores220 + imposto de terceiro250 + variação positiva200 − negativa50 + custo de2027 contabilizado em2026 de100 + diferença de amortização20 = lucro6980. Juros reconhecidos240, compensatórios acrescidos120, remanescente ordinário120; pagamentos continuam separados. Informação insuficiente mantém os efeitos independentes visíveis e impede somente os totais dependentes. | Correcções ordinárias ainda sem regra: encargos e limites36(1)e/f/h/i/n, provisões28/29, operações plurianuais19 e componentes de exercícios anteriores18(2). Juros capitalizáveis/relações especiais e limites exigem o tratamento próprio; não são aceites por simples selecção de juros ordinários. A tributação autónoma que possa coexistir pertence aL7. |
| 2 — amortizações e perda corrente | Decreto72/2013: quotas anuais constantes, custo/residual/acumulado, limite do saldo e vida útil; tabelaII/grupo3/item9 computadores25% e9.1 servidores20%, sem taxa específica da tabelaI prevalecente. Soma da depreciação contabilística por activo reconciliada com o plano; nenhum efeito de mapa incompleto aplicado. Perda corrente separada das perdas anteriores, sem auto-reporte. | Servidor500 ×20%=100 fiscal, depreciação contabilística120 → acréscimo20. Alterar quota/categoria, exceder vida útil ou não reconciliar a origem mantém o lucro dependente indeterminado. Outro exemplo: resultado fiscal−3820 → perda corrente3820 → base0/colecta0 apenas com suporte e conferência completos, sem dedução de perdas anteriores a si própria nem criação de saldo oficial. | Restante catálogo sectorial/genérico de activos, taxas reduzidas dentro dos limites, duodécimos, quotas decrescentes, bens usados/reavaliados, activos intangíveis e recuperação de quotas contabilizadas em anos anteriores. Não declarar toda a amortização fiscal concluída por estes dois itens. |
| 3 — âmbitos, representação e M20/M22 | EP no regime geral, resultado completo exclusivamente imputável ao estabelecimento; ano civil ou período anual diferente autorizado7(2)/comunicado7(3), correspondência dos12 meses e termo em2026/MZN. Valores racionais exactos, sem arredondamento fiscal inventado. M22 campos259/260,269/270,276/277/278 e300 conforme aplicação; M20A.1 quadro4 contas6.1.1/6.2/6.5/6.9 com valores contabilísticos próprios. |6980 − perdas2300 = base4680; ×32%=colecta1497,60MZN, não saldo a pagar. EP com período01/07/2025–30/06/2026 demonstrado; período curto incompatível fica pendente. API privada recupera os quatro casos calculado/falta/perda/EP e os relatórios respectivos. M20 inteiro e M22 ao cêntimo apenas quando a representação é exacta; fracções conservadas e marcadas sem transcrição pronta. | Períodos curtos/transição/liquidação e reconciliação fiscal anual de planos noutra moeda (motor cambial aceite preservado). Representação fiscal de fracções de unidade/cêntimo por corresponder. No M20 faltam discriminação vendas/serviços, fornecimentos/outros gastos, imposto e resultado líquido; no M22 faltam a reconciliação do campo200 e detalhe dos restantes ajustamentos. Divergência delimitada de edições: folha M20A.1 do XLSX remete ao campo201/quadro8 do M22; PDF inventariado utiliza200/quadro10. Bloqueia esse transporte, não os outros campos. |
**Provas apenas do delta:** 14 testes frontend; API privada1 teste/78 asserções com transacção revertida na base QA127.0.0.1:55441; geração de routes/actions pelo procedimento existente, TypeScript e build; interface real com edição, taxa/categoria incompatível, falta de juros, gravação/recuperação, download e perda corrente; relatórios/dossier construídos a partir dos dados recuperados. Recibo `docs/investmoz/simulations/irpc-l6-compatible-sets-qa-20261025.json`; pacote/bundle em `outputs/irpc-l6-sets`. Sem alteração de schema, API, configuração, permissões ou dependências.
**Âmbitos próprios preservados:** L7 conserva benefícios, isenções, taxas reduzidas, tributações autónomas e operações especiais; L8 conserva retenções, pagamentos, créditos e saldo final. M22 campo302 não é preenchido só com a parcela normal300, nem os campos309–316 são preenchidos com zeros presumidos. As dez dúvidas deL5 continuam na mesma matriz, sem nova pesquisa e bloqueando apenas dependências efectivas. L6 continua parcial exclusivamente pelas pendências concretas da tabela; nenhum desses pontos reabre o percurso instalado.
@@ -74,3 +74,30 @@ Novas execucoes identificam-se como `portal-arithmetic-v1`, para nao sugerir que
- Snapshot `business-plan-v17`: adds `openingPayablesInstallments`, an optional schedule with month and percent of the original opening payable balance. Declared percentages sum to at most 100%; cent rounding is capped at the unpaid balance. Scheduled settlements reduce cash and opening payables, not profit or period expenses. Any unpaid amount remains a closing payable; an absent schedule assumes no settlement and leaves the full opening amount outstanding. Snapshots v1-v16 remain readable with an empty schedule; explicit resave produces v17.
- Execuções API concluídas só são aceites pelo consumidor se `result_snapshot` for um envelope `contract_version: 1` válido (incluindo consistência entre `result.value` e `indicative_total`) ou um snapshot legado legível com montante decimal. Estados concluídos sem snapshot, com snapshot malformado ou com versão v1 inválida são rejeitados na fronteira da API; estados não concluídos podem manter snapshot ausente/nulo. Snapshots históricos legíveis continuam compatíveis.
## IRPC normal — conferência anual opcional, versão de cálculo 2
O envelope de livros mantém `version:1`; `irpcNormal[opportunity]` aceita `profit` opcional (`version:1`, `completenessReference`, `lines`, `topics`). As linhas mantêm o código/origem financeira, estado `known|absent|''` e referência; os tópicos conservam separadamente estado, montante original e referência. `known` com montante zero não se torna `absent`; `''` não se torna zero. Tópicos de valor conhecido não zero sem regra implementada não são aplicados. Uma ausência incompatível com a origem ou com montante preenchido mantém pendência.
Sem `profit`, o cálculo/leitor/histórico `IRPC-normal-adjustments/1` mantém significado e chave anterior. Com conferência adicional, `IRPC-normal-adjustments/2` acrescenta `model.profit` congelado e pode produzir `taxableProfit` racional com sinal. `taxableBase` e `tax` continuam nulos. O cálculo só fecha no recorte anual/residente/MZN documentado, sujeito-exercício completo, receitas/custos ordinários qualificados, acréscimos resolvidos e demais efeitos expressamente ausentes ou zero conhecidos. A origem continua `projected`; não é demonstração contabilística nem confirmação AT. Depreciação positiva e juros financeiros remanescentes exigem tratamento próprio.
O fingerprint inclui os novos factos apenas quando presentes; alterações do plano ou da conferência desactualizam o resultado sem eliminar histórico. Os demais livros permanecem intactos no snapshot. Gravação e recuperação usam a API privada existente com ETag/If-Match; sem novo endpoint, schema, permissões ou activação de parâmetros. Matéria colectável/colecta/créditos anuais e M20/M22 não são inferidos de um lucro conhecido.
## IRPC normal — matéria colectável opcional, versão de cálculo3
O envelope de livros e entradas mantém `version:1`; `irpcNormal[opportunity].base` é opcional e versionado1. Conserva NUIT/suporte,método,situação/completude das perdas,manutenção da actividade,linhas anuais de perdas e estado/montante/referência dos benefícios à base. Os montantes apurados,utilizados anteriormente e propostos são stringsMZN,não negativos,até dois decimais;campos ausentes não recebem zero. Um saldo por sujeito/exercício;sem fusão de livros ou origens.
Sem `base`,as versões1/2 mantêm chaves e significado. Com `base`,`IRPC-normal-adjustments/3` acrescenta modelo congelado de elegibilidade/propostas/deduções/saldos e pode produzir `taxableBase` racional no recorte documentado;`tax` permanece nulo. O fingerprint inclui apenas as novas entradas quando presentes. Repetir cálculo não altera `previouslyUsed`;`remaining` é saldo aritmético desta simulação,não reporte/consumo oficial. Uma edição preserva os resultados anteriores no histórico e exige novo cálculo antes de exportar.
Estado conhecido zero,ausência suportada e informação em falta permanecem distintos. Benefício positivo,perda transmitida ou saldo/regime não correspondido não se convertem em dedução livre. Dados e resultado usam a APIprivada existente/ETag,sem schema,endpoints,permissões ou parâmetros novos. A matéria colectável simulada não é colecta nem imposto a pagar.
## IRPC normal — colecta opcional, versão de cálculo4
O envelope e o livro mantêm `version:1`; `irpcNormal[opportunity].assessment` opcional guarda `version:1`, `treatment:''|general_61_1|other` e referência do enquadramento. Sem esta entrada,versões/chaves1–3 mantêm o significado anterior. Com ela,o cálculo `IRPC-normal-adjustments/4` acrescenta modelo congelado `assessment` e `colecta` racional,sem reutilizar o campo legado `tax` como colecta ou saldo final.
A colecta corresponde à matéria colectável actual×32/100 no recorte2026/MZN/residente geral,após classificação e suporte expressos. O modelo identifica taxa32,art61(1),versão da regra e período anual. Informação em falta,período fora do recorte,moeda/âmbito distintos ou caso especial mantêm colecta nula;zero exige base conhecida zero. A fracção racional é conservada exactamente;`centExact:false` não autoriza arredondamento fiscal nem transcrição oficial.
`assessment.finalBalance` é sempre `scope:L8,status:not_calculated,payable:null,recoverable:null` nesta versão. Retenções,pagamentos e créditos anuais não entram na fórmula da colecta nem são subtraídos automaticamente. UI,HTML e dossier apresentam lucro tributável→matéria colectável→colecta→saldo final com esse limite. APIprivada/ETag existente conserva todo o snapshot e histórico,sem novos endpoints,schema,permissões ou migração dos resultados anteriores.
@@ -27258,5 +27258,274 @@
},
"P084_P085": "closed",
"positive_field06_case": "not demonstrated;see receipt"
},
"l3_additional_prepared_20261025": {
"status": "prepared_compatible_not_installed",
"candidate": "0f4df8a4d1cfd0d7b788e58d7f6af8d385384d82",
"source_QA": "b189d0fa",
"baseline": "7ad187f9",
"report": "docs/investmoz/simulations/l3-additional-delivery-20261025.json",
"fresh_authenticated_backup_restore": "required at execution;not yet performed",
"next": "L4ISPCaccordingtoexistingplan;L3remainingvisible",
"superseded_by": "l3_additional_delivered_20261025",
"installed_followup": "fa32a2b9"
},
"ispc_l4a_eligibility_qa_20261025": {
"status": "QA_partial_eligibility_and_separate_option_not_installed",
"report": "docs/investmoz/simulations/ispc-l4a-eligibility-qa-20261025.json",
"tests": "12 new frontend passed;types/build exit0",
"remaining": [
"Apuramento trimestral e aplicação dos escalões3/4/5%,serviços12%,liberal15%,excesso20% e actividades mistas8; identificar correspondência exacta anual/trimestral antes do cálculo.",
"Mínimo trimestral500 e obrigação declarativa; retenção5% nas aquisições ocasionais próprias,limite2.500.000 e modelo; sem reutilizar taxa deIVA.",
"Percurso ocasional3(3–4),formalidades,modelos e prazos do regulamento aplicável; conferir apenas correspondências concretas necessárias,sem nova validação genérica.",
"Demonstração visual integrada e gravação privada deste incremento antes de propor entregaL4."
],
"active_changes": false
},
"ispc_l4_quarterly_qa_20261025": {
"status": "QA_demonstrated_eligibility_option_quarter_calculation_private_recovery_and_report_not_installed",
"report": "docs/investmoz/simulations/ispc-l4-quarterly-qa-20261025.json",
"example": {
"context": "opportunity:375;SYNTHETIC QA",
"option": "documentada2026-01-01",
"quarter": "2026/T2",
"prior_turnover_MZN": "100000",
"quarter_base_MZN": "200000",
"rate_percent": 12,
"tax_MZN": "24000",
"payment_MZN": "24000",
"declaration": "mantida",
"other_fiscal_books": "exactamente preservados"
},
"remaining_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
],
"active_changes": false
},
"l3_additional_delivered_20261025": {
"status": "installed_and_delta_verified",
"requested": "0f4df8a4",
"installed": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"test_only_descendant": true,
"backup_tables": 174,
"backup_files": 369,
"restore_verified": true,
"runtime_files_verified": 12,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "8ba41882cd8a7068c45619b3234af395"
},
"after": {
"rows": 106,
"checksum": "e2140cc9610defc5e64743159fb4df57"
}
},
"sessions": {
"before": {
"rows": 153,
"checksum": "66a8c21d1167a5c4ef27e205006736d4"
},
"after": {
"rows": 154,
"checksum": "6bd8d1311dcc20736dacc02873316399"
}
}
},
"report": "docs/investmoz/simulations/l3-additional-delivery-20261025.json",
"L3": "open_specific_balance_preserved",
"L4": "QA only;habitualquarterlypathdemonstrated"
},
"ispc_l4_prepared_delivery_20261025": {
"status": "prepared_for_Git_delivery_not_installed",
"candidate": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"baseline": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"feature_ref": "refs/heads/codex/ispc-l4-quarterly-qa-20261025",
"runtime_files": 9,
"compiled_markers": 12,
"QA_proofs": "reused;no new functional round",
"backup_restore": "fresh execution still required",
"main_or_active_changed": false,
"report": "docs/investmoz/simulations/ispc-l4-prepared-delivery-20261025.json",
"remaining_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
],
"superseded_by": "ispc_l4_delivered_20261025"
},
"ispc_l4_delivered_20261025": {
"status": "installed_scoped_habitual_quarterly_ISPC_and_delta_verified",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"previous": "fa32a2b9",
"report": "docs/investmoz/simulations/ispc-l4-delivery-20261025.json",
"restore_verified": true,
"tables": 174,
"files": 369,
"L3_preserved": true,
"ISPC_integrally_completed": false,
"remaining_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
]
},
"ispc_residuals_grouped_QA_20261025": {
"status": "QA_grouped_compatible_delta_not_installed",
"report": "docs/investmoz/simulations/ispc-residuals-qa-20261025.json",
"new_tests": 19,
"API": "1/22",
"active_changes": false,
"remaining_calculations": [
{
"item": "Juros compensatórios",
"state": "montante documentado pode ser conservado;fórmula ainda não implementada",
"needed": "regra/taxa/base/período/dias efectivamente aplicáveis,no documento/instrução correspondente;sem zero ou taxa presumidos"
},
{
"item": "Outros enquadramentos da parcela excedente",
"state": "sem fórmula genérica;casos diferentes do acto isolado qualificado não recebem taxa automática",
"needed": "natureza,regime do fornecedor,opção aplicável,base e suporte concretos;encaminhar para o cálculo próprio quando for outro regime,não bloquear o caso positivo implementado"
}
],
"external_formal_dependencies": [
{
"item": "Quadro2doB–Geral",
"needed": "correspondência concreta do mês/ano a inscrever para o trimestre;comunicado fornece meses de pagamento,que não são copiados automaticamente para período"
},
{
"item": "Dispensa inferior500MZN noB–Geral",
"needed": "Representação declarativa do imposto apurado com prestação dispensada10-A;sem preencher montanteapurado comozero porpresunção. O cálculo imposto/prestação jáestá implementado."
},
{
"item": "Entrega de retenções",
"needed": "modelo/código/instrução próprios12(3)ISPCe57(2k)IRPS;B–Geraldeapoio nãoéapresentadocomocorrespondênciacompletadestasretenções"
},
{
"item": "Regulamentação2026/instruções de envio de facturas",
"needed": "texto/exemplar/instrução concreta quando disponibilizado;comunicado transitório já implementado,não se mantém pesquisa genérica como aprovação adicional"
},
{
"item": "Submissão e pagamento",
"needed": "actos externos e comprovativos reais;nenhuma operaçãoATfoiexecutadaemQA"
}
],
"installation_followup": "ispc_residuals_delivered_20261025"
},
"ispc_residuals_delivered_20261025": {
"status": "installed_grouped_ISPC_residual_delta_verified",
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"receipt": "ispc-residual-delivery-20261025.json",
"backup_restore_verified": true,
"ISPC_integrally_completed": false,
"IRPS_integrally_completed": false
},
"irpc_l5_first_scoped_QA_20261025": {
"status": "QA_first_scoped_increment_not_installed",
"receipt": "irpc-l5-withholdings-qa-20261025.json",
"verification": {
"new_frontend_distinct": 17,
"frontend": "frontend.txt:16pass;directed-cross-context.txt:1pass",
"API": "1test/23assertions;guardedloopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;allpreviousL3/ISPCmapsidentical",
"types": "types-final.txt:exit0",
"build": "build-final.txt:exit0",
"UI": "Actualcomponent calculation/save/recover/report andexport;localfileharness distinguishedfromprivateAPI;reuse existingacquisition at373 demonstrated",
"previous_functional_suites_repeated": false
},
"remaining": [
{
"item": "Taxas normais e especiais dos demais rendimentos",
"needed": "Corresponder62(1–4)/67 por rendimento e período,com alterações20/2009,4/2012,19/2013 e20/2022. Ficheiro local BR252/2022 contém apenas3.ºsuplemento/Decreto74/2022,semLei20/2022;INM identifica esta na p2731. Texto exacto em falta não é revalidação de autenticidade.",
"resolution": "Implementar ramo dirigido após correspondência do texto aplicável;não usar2002 ou taxa genérica."
},
{
"item": "Residentes/EP e dispensa68",
"needed": "Corresponder62(5) novo com dispensas68,em especial68(d),titular/rendimento imputável aEP e factos de cada dispensa;sem confundir taxa com obrigação de reter.",
"resolution": "Ramo próprio por natureza/dispensa;sem presumirretenção10%ouzero."
},
{
"item": "Convenções/benefícios",
"needed": "Convenção invocada,artigo,residência,beneficiário,condições,período e documento aplicável",
"resolution": "Só o caso dependente permanece indeterminado;nenhuma taxa reduzida sem esses elementos."
},
{
"item": "Conversão cambial",
"needed": "Moeda,montante,data,taxa efonte aplicáveis à operação",
"resolution": "Conversão rastreável;sem taxa actual nem relabelagemMZN."
},
{
"item": "Juros/regularizações/guia agregada",
"needed": "Regra/taxa/base/período próprios;guias/declarações anteriores e pagamentos para substituições",
"resolution": "Não substituir juros porzero;preparação actual não é declaração rectificativa nem liquidação anualIRPC."
}
],
"external": [
{
"item": "MRFTA19/39:rubricas eCER digitais/moeda electrónica",
"needed": "Correspondência da nova categoria62(5)a/b às rubricas/CERdo quadro7;remissão67(7)para62(6)existe no original,masnova taxa aparece62(5).",
"resolution": "Preservar divergência e original;não renumerar,adivinharCERou bloquear cálculo positivo independente."
},
{
"item": "GuiaM39 anterior eMRFTAactual",
"needed": "Manter exemplares;instruçõesMRFTAidentificamperíodoúnico e prazonominaldia20mêsseguinte àdedução;calendário/prorrogação eprocedimento2026específico nãoinferidos",
"resolution": "Mapa de preparação/exportação;sem preenchimentofinalCER,assinaturaouusodosserviços."
},
{
"item": "ActosAT",
"needed": "Submissão,recepção,aceitação eeventualcomprovativo externo",
"resolution": "Externos aoportal;exportar nãoexecuta nemcertifica estes actos."
}
],
"active_changes": false
},
"irpc_l5_grouped_QA_20261025": {
"status": "QA_grouped_compatible_L5_prepared_not_installed",
"receipt": "irpc-l5-grouped-qa-20261025.json",
"new_frontend_tests": 19,
"API": "1/34",
"FX": "Existingselectorandconversionunchanged",
"remaining": [
{
"item": "Dispensas68 e casos residentes/EP dependentes",
"data_needed": "Titular/operação e condições de68(a/b/c/d/f/g),incluindo gestão de imóveis próprios/transparência,participações e tipos de juros;casos digitais residentes/EP confrontados com62(5)/68(d).",
"resolution": "Ramo específico por dispensa/factos;não bloquear royalties comuns,retenções definitivas ou especiais independentes."
},
{
"item": "Convenções/benefícios invocados",
"data_needed": "País/convenção/artigo,beneficiário,residência,condições/período e prova invocados",
"resolution": "Só esse caso fica indeterminado;sem taxa reduzida presumida."
},
{
"item": "Outros rendimentos/devedores/períodos",
"data_needed": "Artigo próprio para categorias fora dos ramos agrupados,via devedorIRPS,anos fora2026,EP de categorias especiais62(4)quando não cabe62(2)",
"resolution": "Não aplicar20%ou10%genéricos;avançar os casos compatíveis."
},
{
"item": "Juros,rectificações e arredondamento de entrega",
"data_needed": "Regra/taxa/base/período dejuros,declaração/guia anterior,documentos de correcção e regra de arredondamento legal da entrega se aplicável",
"resolution": "Aritmética exacta preservada;aproximação assinalada;sem zero dejuros ou crédito anual automático."
},
{
"item": "EntregaAT com comprovativo em moeda estrangeira",
"data_needed": "MontanteMZN efectivamente entregue no comprovativo;conversão do pagamento ao beneficiário não prova entregaIRPC",
"resolution": "Base e comprovativo de retenção sofrida já convertem pelo mecanismo entregue;esta limitação não reabre o câmbio geral."
}
],
"external": [
{
"item": "MRFTA/CER e remissão67(7)",
"data_needed": "Correspondência concreta de rubricas/CER para novos casos;67(7)refere62(6),nova taxaestá62(5);manteroriginal",
"resolution": "Preparação/exportação disponível;sem adivinhar código,assinatura ou submissão."
},
{
"item": "ActosAT",
"data_needed": "Submissão,recepção,aceitação e eventuais comprovativos externos",
"resolution": "Externos;exportar não executa nem certifica esses actos."
}
],
"active_changes": false
}
}
@@ -0,0 +1,25 @@
{
"status": "prepared_for_Git_delivery_not_installed",
"installed": "5fa64bc0",
"previous_QA": "acf8ec3c",
"date": "2026-10-25",
"scope": "Existing AUD-SIM-INT02 only; J1-J5 and C1-C5 each with example in existing matrix/manual; not sent to AT",
"presentation": "Automatic interest is a simulation with supplied assumptions, not fiscally confirmed. Entered CER is not validated by official catalogue. Fictional999/998 and10% remain fictional.",
"pending": "Exact annual rate/source/validity, day basis, rounding, on-account not-withheld/mora; official CER by nature/digital-special and official transcription of mixed rates/codes.",
"verification": {
"new_delta_tests": 13,
"typescript": "passed",
"QA_build": "passed exit0",
"accepted_API_UI_L3_ISPC_FX": "reused; no new round",
"protected_runtime": 31
},
"runtime_sha256_LF": {
"resources/js/lib/irpc-interest.ts": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd",
"resources/js/lib/irpc-mrfta.ts": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c",
"resources/js/lib/irpc-mrfta-cases.ts": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862",
"resources/js/components/simulation-irpc-mrfta.tsx": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
"previous_receipt": "irpc-interest-cer-qa-20261025.json remains historical proof for acf8ec3c; current presentation hashes in this receipt",
"schema_API_permissions_originals_changed": false,
"L5_complete": false
}
@@ -0,0 +1,579 @@
{
"status": "installed_operational_L5_demonstrated_scope_only",
"installed": {
"status": "installed",
"commit": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"release": "/var/www/investmoz-homologacao/releases/7a11c4ef8f06ef149eb0488be3cd0749dc609bd0-68c76bdc",
"previous_release": "/var/www/investmoz-homologacao/releases/5fa64bc0f4b067e81d8728b344eb8697415ebedf-b08a592f",
"database_migrations": 0,
"content_imports": 0
},
"previous_baseline": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"backup": {
"stage": "/var/backups/investmoz-irpc-interest-delivery-20261025/backup",
"created_at": "2026-10-25T19:14:23Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "ae9ba280390f9ca676845fdced1193642102658ea1274669c81387b26e38c8ba",
"files_sha256": "45b492019ca2f7cc93388f54b776754e5e045e15916f824d257928bb45e324f4",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l5_restore_20261025",
"port": 55441,
"source_dump_sha256": "ae9ba280390f9ca676845fdced1193642102658ea1274669c81387b26e38c8ba",
"active_database_writes": 0
},
"preservation": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/5fa64bc0f4b067e81d8728b344eb8697415ebedf-b08a592f",
"installed": {
"status": "installed",
"commit": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"release": "/var/www/investmoz-homologacao/releases/7a11c4ef8f06ef149eb0488be3cd0749dc609bd0-68c76bdc",
"previous_release": "/var/www/investmoz-homologacao/releases/5fa64bc0f4b067e81d8728b344eb8697415ebedf-b08a592f",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 4,
"preserved_L3_ISPC_FX_runtime_files_verified": 31,
"documentary_files_verified": 30,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "e4bcbac53e96b6fef0b4bf512aeb9470"
},
"after": {
"rows": 106,
"checksum": "58c1c37e3152c0e387a19b3bcf057bb0"
}
},
"sessions": {
"before": {
"rows": 21,
"checksum": "887634a88e9462f38305ff7623c4c508"
},
"after": {
"rows": 22,
"checksum": "6a080a3d85940d192748fa272fe94f15"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"schema_permissions": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 21,
"after_rows": 24,
"changes": [
{
"key_sha256": "f72f988e8b92b60a9a4c888ad2e0a275af4dd678ca1c3f59765808df2385706b",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "c1d4a5d1f3f22112b617003a45e285538c6afbfc16502fe76476528808c5a62f",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "fb07fca164c39ae39fbf4002fe20469826c1c6050f2e6af7ce54926bffe87a87",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public_verification": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"branch": "main",
"built_at": "2026-10-25T19:18:14.226356+00:00",
"manifest_sha256": "d78df5e7caee48690641143c8e8633b850db421468c837ec37992ee9cfa21aaa"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Simulação pelos pressupostos introduzidos, sem confirmação fiscal dos juros.": [
"assets/services-xTyGW6qB.js"
],
"Códigos provisórios ou de simulação não são correspondências oficiais.": [
"assets/project-dossier-CxbkzdT3.js"
],
"Casos de trabalho separados por período, rubrica, taxa e CER": [
"assets/services-xTyGW6qB.js"
],
"Não são juros calculados pelo portal.": [
"assets/project-dossier-CxbkzdT3.js"
],
"Dispensa de retenção": [
"assets/project-dossier-CxbkzdT3.js",
"assets/services-xTyGW6qB.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-xTyGW6qB.js"
],
"Calcular e guardar restituição E": [
"assets/services-xTyGW6qB.js"
],
"Reutilizar selecção cambial": [
"assets/services-xTyGW6qB.js"
]
},
"assets": [
{
"file": "assets/project-dossier-CxbkzdT3.js",
"status": 200,
"sha256": "be74df50d3dbed2fcf9873c70e9afd8b7e5403f74c4dfe3805ad96ab21f85440"
},
{
"file": "assets/services-xTyGW6qB.js",
"status": 200,
"sha256": "7a127267891fe3b05112ee7d749027d4c290e70539652d797345f9f6e059ffae"
},
{
"file": "assets/project-dossier-document-BjM1GMjD.js",
"status": 200,
"sha256": "b745b5faea379ce38afd77a90c4e391caf446513059727d1fcb75917a85b2429"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-D3TVl0n5.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
}
],
"originals": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"pipeline_checks": [
"OK (1 test, 3106 assertions)",
"built in 30.04s",
"OK (59 tests, 317 assertions)",
"# tests 872",
"# pass 872",
"# fail 0"
],
"accepted_proofs_reused": true,
"manually_repeated_accepted_functional_suites": false,
"limitations": "Simulation with explicit supplied parameters is not fiscal confirmation of interest; provisional CER not official correspondence. Ten exact AT questions J1-J5/C1-C5 retained in existing matrix. L5 operational within demonstrated scope,not fully completed.",
"L5_complete": false,
"next": "L6 normal IRPC:adjustments to financial result;no repeated L5 source research without new information",
"proof_files": {
"backup.txt": "f321c1f1f595c3a056b41b6fe0dfe68941461d8efa686de7e76905946af180c9",
"compact-dependencies.txt": "6c66d80adb889a470b2500dfbbd6f984bef3a2ce9967f11ea21ac1bafe5af745",
"installed-protected.txt": "60564bfd4ee8d7158ebd5247b1321c0c1a4cfb69eb2401b8d7e4ec1b71f8e560",
"installed-public-delta.json": "9f121ebaff22a17942d2ba3ca98feaf3e5f9735c1eb25f1dcc47c0d07ba95804",
"installed-public.txt": "da646d8f4adfc9f6314bd5201675ea35c7bf9d247a15612bbcb0370dda1672c2",
"integration.txt": "dcdc8f4540117e2d87c44fbe99c92028700dc998b8d051cbebc9fe8638ef25f0",
"manifest-served.json": "d78df5e7caee48690641143c8e8633b850db421468c837ec37992ee9cfa21aaa",
"operational-delta.txt": "264946621bdd67789d3d6b2c4589fc77e2337e606f90e90a5baec812a2368940",
"preflight.txt": "fbf315297e990f29224c110982d02dbae88da98c2819f001af914f7f8a23c73e",
"preparation.json": "e4b83c40a692adc864650391515f29e97b59da6ddfee3f19840ff07e7e8771ec",
"progress.txt": "2f9ccb94847d399d18b4e76e1f283ae00376791d428cf138c750d5075fba1ce0",
"restore.txt": "e51ada3301c3c18af3dfda10a537275b55f183bb6ac1e9bb1d2ea10ec1d4ecff",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status1.txt": "b6da9d8d0b2a31b94bed039b7806400193bcbf9c386faae848d7ea7512e6da71",
"status2.txt": "b6da9d8d0b2a31b94bed039b7806400193bcbf9c386faae848d7ea7512e6da71",
"status3.txt": "998b40a5ebef08ac85ee0cdf80a8f8b07da159565f0f7a62e8c02613d9859c8d",
"status4.txt": "f2580fba78230810b2bd95885494d76c86a2e5ee7f3705e3d300eca2f06e5109",
"status5.txt": "f2580fba78230810b2bd95885494d76c86a2e5ee7f3705e3d300eca2f06e5109",
"status6.txt": "f2580fba78230810b2bd95885494d76c86a2e5ee7f3705e3d300eca2f06e5109",
"status7.txt": "1248021d6ed7f0651a4d19b0d9985eb19cb285cb73927ed6c02a3e195881aabc"
}
}
@@ -0,0 +1,391 @@
{
"status": "QA_two_point_delta_demonstrated_not_installed",
"installed_baseline": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"branch": "codex/irpc-interest-cer-qa-20261025",
"scope_only": [
"juros automáticos por parâmetros documentados",
"separação CER/rubrica/taxa por casos de trabalho"
],
"implemented": {
"juros": "Aritmética racional diária com taxa anual final/base anual/arredondamento/fontes/versão do caso;principal após entregas parciais,paragem no pagamento integral,contagem por anos quando documentada,versão própria apenas da nova aritmética. Definitiva e por conta efectivamente retida neste recorte.",
"CER_rubricas": "Chaves estáveis por período/rubrica/taxa/CER;origens,documentos e referências conservados;fichaHTML por caso,mantendo pendências do período e sem declarar anexo/declaração autónoma.",
"compatibility": "Campos adicionais;modo legado preservado. Leitor5fa64bc0 conserva o payload exacto e o cálculo fiscal actual;novo resultado de juros é histórico nessa versão,sem recálculo."
},
"not_claimed": [
"Taxa fiscal2026 global cadastrada/activada ou substituição automática daMAIBOR",
"Convenção fiscal de base anual/arredondamento inferida sem fonte do caso",
"Juros de mora ou regra completa de imposto por conta não retido",
"CatálogoCER integral e novas correspondências oficiais digitais/especiais",
"Autorização para fundir taxas/CER ou criar declarações/anexos oficiais",
"Instalação deste novo incremento ou conclusão deL5"
],
"remaining_only_two_points": {
"juros": "Ligar parâmetro/fonte fiscal aplicáveis2026 e as convenções documentadas do caso;regra de mora e retenção por conta não efectuada continuam separadas. Sem perfil completo,a aritmética fica indeterminada;não reutilizar taxa de exemplo.",
"CER_rubricas": "Obter/corresponder os códigos/rubricas ainda pendentes e a transposição oficial de múltiplas taxas/CER;as fichas separam trabalho,mas não resolvem o catálogo ou o procedimento oficial."
},
"verification": {
"new_frontend": "13 tests passed;no old functional suites manually repeated",
"types": "tsc --noEmit exit0",
"build": "complete QA build exit0",
"private_api": "1test/19assertions;DatabaseTransactions rollback;loopback55441/simulator_fiscal_delta_20261021_test",
"dossier": "generated from actual API recovery;parameters/day segments/report preserved",
"UI": {
"documentedParameterCalculation": true,
"fictionalRateExplicit": true,
"missingRateIndeterminate": true,
"principalPreserved": true,
"localSaveRecovery": true,
"caseDownload": true,
"notOfficialDeclaration": true,
"differentRatesCodesSeparated": true,
"periodTotalIndeterminate": true,
"privateApi": "IrpcInterestCerDraftTest,separate",
"errors": []
},
"installed_reader_new_payload": {
"readerRevision": "5fa64bc0",
"readNewPayload": true,
"taxResultCurrent": true,
"newPreparationHistorical": true,
"roundTripExact": true,
"oldCalculationsReexecuted": false
},
"accepted_proofs": "Existing5fa64bc0,L3,ISPC,FX proofs reused;onlynewdelta andnew-payload-reader compatibility checked"
},
"examples": "Annual10%,365days,rounding conventions andCER999/998 are explicitly fictional QA parameters/codes,not official2026 fiscal data. Principal7300,paid3650,interest15 on5+5days,total3665 in onecase;20%/10%withholding and999/998 separate cases keepperiodtotalindeterminate.",
"runtime_delta": [
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "65133d0005051e0e5c9fbc8346478cca5198717e283e153094132a16d384a620"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "c3132e6c1cdecff6a2d6d369ef5d8118aa6d58b59bca51516a1a3e0cb42f058e"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "27a93e14eecfb002fe2f264e1854ec5bf852997535d61db1a8d3373a8e8470eb"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234",
"sha256_LF": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2",
"sha256_LF": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4",
"sha256_LF": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
}
],
"originals_unchanged": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"source_review": {
"reuse": "AcceptedDecreto9/2008,25/35 andMRFTA/BM original sources. No new rate/CER activated from research.",
"AT_inventory": {
"url": "https://www.at.gov.mz/api/documents?root=LEGISLACAO",
"path": "outputs/irpc-interest-cer/at-legislation-inventory.json",
"sha256": "d74e764224d97fdea2e6e6e3496614c9b0f94941e8f8757eed8e7847bda9508c",
"documents": 189,
"read_scope": "Metadata/title inventory;not a fresh integral reading of189PDFs. No identified title supplies the required successor fiscal parameter or MRFTA CER crosswalk."
},
"CER_search": "Decreto68/2014 and subsequent disaggregation references identified;no applicable detailed CER crosswalk recovered for automatic mapping. Unnumbered drafts,field numbers and budget aggregates not used as revenue codes.",
"rate_search": "No applicable2026 fiscal replacement parameter obtained in this scoped check;current banking reference rates were not substituted."
},
"implementation_choices": [
"Complete parameter references are case data,not a new organizational approver. No default tax rate/day basis/rounding or source publication activates a calculation.",
"Working-case export retains period gaps;it does not decide official declaration splitting."
],
"active_changes": false,
"schema_backend_api_config_permissions_dependencies_delta": false,
"L5_integrally_completed": false,
"proofs": {
"outputs/irpc-interest-cer/api.txt": "e647e9d8daf16cfa4359e35edd373cfdbc7e35ef684b5fb8cdb1107eeb158ee7",
"outputs/irpc-interest-cer/at-legislation-inventory.json": "d74e764224d97fdea2e6e6e3496614c9b0f94941e8f8757eed8e7847bda9508c",
"outputs/irpc-interest-cer/build.txt": "3841d26e7f52f6468a337f1fd786dc7c04be122bc639bf3755842c39e1a837ad",
"outputs/irpc-interest-cer/calculated.json": "ff2d649ba269e7618a9cb9208f5e47baff5bbbc45c65176ba163cea5e69ad390",
"outputs/irpc-interest-cer/case-10-998.html": "bcfe6a84e07d3b411e28e231c797daf7c013041856dbb0aa05ba605309e8370a",
"outputs/irpc-interest-cer/case.html": "24ee8874acb770769bbe4e807af05e9d42646257142717c55c621d34259a6dc8",
"outputs/irpc-interest-cer/dossier.html": "5f69bd87ff0bcaa52c20eaa1c9feafeb6ae263d667aa4c53df15bd2abce8752d",
"outputs/irpc-interest-cer/dossier.json": "61c194509f6c2feb432819ff6f5d72647acf3ec2ff068bb299fe4c6be6a294da",
"outputs/irpc-interest-cer/dossier.txt": "a0473de355821758c4d320eea8e7af76a0d196a9cee652c71af723d6f69832f0",
"outputs/irpc-interest-cer/frontend.txt": "686362609c03b88d3f0d90951be11d0a3c65be8d79a3c50aa24c0249ab545da2",
"outputs/irpc-interest-cer/index.html": "6bb76e37ac20a73cb9ffcda14f1ac9db701aa01bc2ef2f62fc5adaaffb640ca8",
"outputs/irpc-interest-cer/installed-reader-compatibility.json": "dcac8cb281bac3d3ccace6c73087632c53dec1c27c5e4967b631a822dcb7da14",
"outputs/irpc-interest-cer/mixed.json": "82fec05e50261f4eb13160de93c78d76a6a58c79644ed2ca97fc27ae3ce41c3e",
"outputs/irpc-interest-cer/preparation.html": "8f210407ab61ed7a1f0bd3b8bce7c247bcecfc4ce2fe932924957fd3af1ff990",
"outputs/irpc-interest-cer/recovered.json": "ac9d7c1338c99190616d62f0ad5c7d11403af65d73ff6f7726a871c1693596e1",
"outputs/irpc-interest-cer/types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"outputs/irpc-interest-cer/ui-proof.json": "366a3aa989f40ea195b4d334bdc666d255ed88125eca9533a669eb0721e0267d",
"outputs/irpc-interest-cer/ui.png": "cac3bab6a576d5394b97d349903ead7ad12f3270a9c8a9f16ec2880822420d41",
"outputs/irpc-interest-cer/ui.txt": "98b34de11dd5b993510b997413d537320f291c447c6a1a9244817df99cc7cc72"
}
}
@@ -0,0 +1,360 @@
{
"status": "QA_juros_MRFTA_demonstrated_not_installed",
"installed_baseline": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"branch": "codex/irpc-juros-mrfta-qa-20261025",
"implemented": [
"MRFTA preparation fields1–7 by single month;reserved8/9;HTML preparation export",
"Rubric/base/rate/tax and reconciled payments reused from frozen IRPC result;separate suffered/dispensed/other-month rows",
"Documented CER transcription with reference;no inferred CER from old guide field numbers",
"Documented compensatory-interest assessment amount or zero only after full timely remittance with documented deadline",
"Unknown rates/interest,digital/special rubrics,unknown CER,multiple rates or other taxes keep final total indeterminate while principal rows remain available",
"Private draft persistence,recovery,history;standalone MRFTA and full dossier reports;old IRPC inputs/calculations retained"
],
"not_implemented": [
"Automatic compensatory-interest arithmetic for2026:applicable successor/parameter for discontinuedMAIBOR12months not obtained",
"Juros de mora;autonomous tax;IRPS beyond prior delivered case",
"Digital/e-money and unqualified special rubrics;MRFTA CER catalogue not supplied by this increment",
"Mixed rate/CER same official rubric remains separate pending correspondence",
"No official PDF changed/filled;HTML preparation reflects fields and retains sourcePDF original;no submission/signatures/ATacceptance"
],
"verification": {
"frontend": "12 new tests+1 directed existing IRPC presentation test passed",
"types": "tsc --noEmit exit0",
"build": "complete QA build exit0",
"private_api": "1test/14assertions;DatabaseTransactions rollback;127.0.0.1:55441/simulator_fiscal_delta_20261021_test",
"dossier": "generated from actual private API recovered model",
"UI": {
"calculation": true,
"localSaveRecovery": true,
"privateApiProof": "IrpcMrftaDraftTest, separate",
"report": true,
"documentedInterest": true,
"insufficientInformation": true,
"download": true,
"errors": []
},
"CER_example": "999 is explicitly fictional QA data,not an official recipe-code mapping",
"unchanged_proofs": "AcceptedL3/ISPC/FX and ce746d88 calculation proofs reused;no manual repeat suites"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "1ff1725724dbdaaa9a3857941d03e312c6a7da573d369ee86015edc90cd2d0d1"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "9cf7d5e447e1a9ed37d1bd24b4ac5104b1adec3790ff8db4356c3b68b339d89a"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234",
"sha256_LF": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2",
"sha256_LF": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
}
],
"accepted_originals_inventory": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"new_official_source": {
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
"url": "https://bancomoc.mz/pt/areas-de-actuacao/mercados/mercado-monetario/",
"review": "Official page expressly documentsdiscontinuedMAIBOR publication;MIMO/Prime not transported into fiscalrule",
"publication_import_activation": "Private source archive only;no library publication or fiscal activation;no scan claimed"
},
"source_mapping": [
"AT MRFTA19/39PDF1–2,visuallyreviewed;fields1–7,reserved8/9,singleperiod",
"Decreto9/2008 arts25/35 PDF6/8,p121/123;reusedacceptedofficialoriginal,notoldrevoked2002code"
],
"implementation_choices": [
"Completeness and absence of other tax rubrics are recorded facts to avoid treating this context subtotal as the entire declaration;not new approvers or organizational permissions",
"Manual CER/assessment references record applicable documents;no generic legal authenticity revalidation"
],
"active_changes": false,
"schema_migrations_configuration_permissions_changed": false,
"L5_integrally_completed": false,
"proofs": {
"outputs/irpc-mrfta/api.txt": "63e401f6422cdea294b4ae58bf1ff5c25e7c5dd87eccf81c249319bffbb06dd3",
"outputs/irpc-mrfta/AT-MRFTA-19-39.pdf1.png": "d0f4118a696ab940d2fd9a9cb792656dcba860b9b3a300c78334445d43d46a72",
"outputs/irpc-mrfta/AT-MRFTA-19-39.pdf2.png": "449ce541e08d886e7851e04c6b53ee44694d89508143da3c497d16db1a3f6a59",
"outputs/irpc-mrfta/build.txt": "ede4498073edeeadcbda9b1868b4be5574ad31a36d78664a1ebf8fb27ee89c86",
"outputs/irpc-mrfta/calculated.json": "b41a7dec0802a573d67f8e9b0ba42e54c4a20e935e844febd538752605d3446f",
"outputs/irpc-mrfta/Decreto-9-2008-BR16.pdf6.png": "ae8f0d02c2c01fafd1f390492ecf442defa094edd5612923c5f34b458f6c6392",
"outputs/irpc-mrfta/Decreto-9-2008-BR16.pdf8.png": "6097b3137f22a59c55cf1017643e0be4c0d6ba571e1d3c84331940988a4967b7",
"outputs/irpc-mrfta/dossier.html": "743a1960b2b70dfd4e5231f37bbf0799184f8f9d39c58c7569f66852ad1e3db5",
"outputs/irpc-mrfta/dossier.json": "864a2c9da690b086a2aa7c10ae18549d7d462f43a6f87826e6b1f57d8751e5c0",
"outputs/irpc-mrfta/dossier.txt": "a0473de355821758c4d320eea8e7af76a0d196a9cee652c71af723d6f69832f0",
"outputs/irpc-mrfta/frontend.txt": "707ef1a9c37fbeb53997027c1aff5c3a85c3358e40b3ed63512ddf93ded74b7a",
"outputs/irpc-mrfta/index.html": "6bb76e37ac20a73cb9ffcda14f1ac9db701aa01bc2ef2f62fc5adaaffb640ca8",
"outputs/irpc-mrfta/preparation.html": "c8855ab0bcbaa85e95149ca36d1b035b59a21760d3336c088b552c147eafc330",
"outputs/irpc-mrfta/recovered.json": "f7ef8221ad1ffba237f683eb2333e4bde8b076e00a459c131f8c81c96c3048f5",
"outputs/irpc-mrfta/types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"outputs/irpc-mrfta/ui-export.html": "c8855ab0bcbaa85e95149ca36d1b035b59a21760d3336c088b552c147eafc330",
"outputs/irpc-mrfta/ui-proof.json": "9d41f8a7f48e0a1f611bd0916e58e9dc6ffaa9760b281f056edbe2ccde115777",
"outputs/irpc-mrfta/ui.png": "ee9e6f5240d1f0b58569609bdb6c0c38a3cd11373db7b6ad0008b15fb229afad",
"outputs/irpc-mrfta/ui.txt": "59df712c7a7873532c4eab94fb582fd1e470803a5da1bfd68c884f8e8ad2386b"
}
}
@@ -0,0 +1,193 @@
{
"status": "QA_grouped_compatible_L5_prepared_not_installed",
"installed_baseline": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"previous_QA": "da0d8abb4775a7a68142f84129e312b86dadfe23",
"branch": "codex/irpc-l5-withholdings-qa-20261025",
"authorization": "Tempo:agrupar restantes enquadramentos compatíveis,reutilizar contrapartes/documentos/pagamentos e câmbio entregue;preparar entrega conjunta;manterportal5c/L3/ISPC;sem instalar este incremento.",
"implemented": [
"Firstda0d8abb scope preserved;MZN10%digital/nonresident resultscurrentandunchanged without forcedrecalculation.",
"Ordinary20% qualifiedroyalties/equipment/services/nonlistedcapital;rentstandard20%onaccount;residentroyalties20%onaccount;onlydependentdispensascaseslimited.",
"62(3):20%definitivelisteddebt/Treasuryinterestandbankliquidityswaps with exactnationalheadquarters/effectivemanagementfacts.",
"62(4):10%qualifiedtelecom/internationaltransport/connectedinstallation/aircraftmaintenancecharter/publicruralelectricity/maritimefishingcabotage/otherBMlistedsecurities;notgeneral10%.",
"Expiredagriculturalmeasures31/12/2025 not carriedto2026;source2022gapresolved.",
"ExistingFXselector/selectFx/fxSelectionKey/convertCents reused unchanged through IRPCadapter;originalcurrency/amount,bulletin,column,direction,date andhistory retained.",
"Foreignwithholdingproofcapacityconvertedonce;MZNallocations,sharedpaymentlimits andsourcechangeschecked;ATremittance/beneficiarypaymentnotconfused.",
"Private draft persistence/recovery/report/preparationexport;annualcredits/ATactsnotautomaticallygenerated."
],
"new_source": {
"url": "https://www.cipmoz.org/wp-content/uploads/2023/financas/17F%29%20Lei%2029_2022%20Plano%20Economico%20Social%20Or%C3%A7amento%20do%20Estado%202023.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
"pages": 268,
"bytes": 17966640,
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"citation": "BR252/I,30/12/2022,p2731/PDF1,Lei20/2022 arts1/2",
"read_scope": "Full268pages preserved/inventoried;first3pages textread;page1 visuallyreviewed;budgetpages not usedforwithholding",
"provenance": "Original officialBR hostedCIP;acceptance ofofficialsource preserved,no second authenticityvalidation",
"scan": "Not claimed performed;private source archive,not librarypublication/import"
},
"source_mapping_reused": [
"Lei34/2007,62(1)/67/68,PDF17–19",
"Lei19/2013,62(3/4),PDF2/p682(22),visuallyreviewed",
"Lei20/2022,62(1–5),PDF1/p2731,visuallyreviewed",
"Lei12/2025,62(5)/67(5/7),previouslyacceptedBR248/2025PDF19"
],
"runtime_delta": [
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "f10d82f1bf353b1a92c37790b213fad9e769ed39139a99577747ee703be63b49"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "5cffcc26c72ed736e88386589710cf7929ec9bc25f78910648ba676fb1cf4b08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
}
],
"additional_runtime_since_da0d8abb": [
"resources/js/lib/irpc-withholdings.ts",
"resources/js/components/simulation-irpc-withholdings.tsx",
"resources/js/lib/irpc-fx.ts"
],
"existing_FX_files_unchanged": {
"resources/js/lib/iva-fx-selection.ts": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998",
"resources/js/components/simulation-fx-selection.tsx": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf",
"resources/js/lib/business-financial-plan.ts": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb",
"resources/js/lib/iva-currency-events.ts": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
"previous_resources_unchanged_except_manifest": 438,
"old_original_PDFs_preserved": 26,
"total_source_original_PDFs": 27,
"previous_QA_proofs_reused": {
"new_frontend_distinct": 17,
"frontend": "frontend.txt:16pass;directed-cross-context.txt:1pass",
"API": "1test/23assertions;guardedloopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;allpreviousL3/ISPCmapsidentical",
"types": "types-final.txt:exit0",
"build": "build-final.txt:exit0",
"UI": "Actualcomponent calculation/save/recover/report andexport;localfileharness distinguishedfromprivateAPI;reuse existingacquisition at373 demonstrated;UI proof reused for unchanged positive route after final shared-payment-key refinement;directed test proves only that delta",
"previous_functional_suites_repeated": false
},
"previous_QA_proof_hashes_reconciled": true,
"verification": {
"new_frontend_distinct": 19,
"frontend_proofs": [
"frontend.txt:17pass;listedcapitalcase superseded bydirectedcapital",
"directed-capital.txt:updatedcapitalcase+1newcasepass",
"directed-report.txt:3affectedreportcasespass",
"directed-fx-origin.txt:1newcasepass"
],
"API": "1test/34assertions;loopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;acceptedhistory/oldmaps preserved",
"types": "types-final.txt:exit0",
"build": "build-final.txt:exit0",
"UI": "ActualexistingFXpreview/confirmationinsideIRPC,calculation/save/recover/report/export;localfileharness distinguishedfromprivateAPI",
"unaffected_old_functional_suites_repeated": false
},
"example": {
"foreign_royalty": "1000USD×64=64000MZN;20%=12800;ATreceipt5000MZN;balance7800MZN;FXdate20Oct vs costevent2Oct",
"special_telecom": "100000MZN;qualified62(4)a10%=10000;notdigital62(5)",
"resident_royalty": "50000MZN;20%=10000;onaccount,notannualcredit",
"foreign_withholding_proof": "100USDbase→6400MZN;tax1280;10USDproof→640MZN;difference640MZN"
},
"remaining_calculations_and_specific_mapping": [
{
"item": "Dispensas68 e casos residentes/EP dependentes",
"data_needed": "Titular/operação e condições de68(a/b/c/d/f/g),incluindo gestão de imóveis próprios/transparência,participações e tipos de juros;casos digitais residentes/EP confrontados com62(5)/68(d).",
"resolution": "Ramo específico por dispensa/factos;não bloquear royalties comuns,retenções definitivas ou especiais independentes."
},
{
"item": "Convenções/benefícios invocados",
"data_needed": "País/convenção/artigo,beneficiário,residência,condições/período e prova invocados",
"resolution": "Só esse caso fica indeterminado;sem taxa reduzida presumida."
},
{
"item": "Outros rendimentos/devedores/períodos",
"data_needed": "Artigo próprio para categorias fora dos ramos agrupados,via devedorIRPS,anos fora2026,EP de categorias especiais62(4)quando não cabe62(2)",
"resolution": "Não aplicar20%ou10%genéricos;avançar os casos compatíveis."
},
{
"item": "Juros,rectificações e arredondamento de entrega",
"data_needed": "Regra/taxa/base/período dejuros,declaração/guia anterior,documentos de correcção e regra de arredondamento legal da entrega se aplicável",
"resolution": "Aritmética exacta preservada;aproximação assinalada;sem zero dejuros ou crédito anual automático."
},
{
"item": "EntregaAT com comprovativo em moeda estrangeira",
"data_needed": "MontanteMZN efectivamente entregue no comprovativo;conversão do pagamento ao beneficiário não prova entregaIRPC",
"resolution": "Base e comprovativo de retenção sofrida já convertem pelo mecanismo entregue;esta limitação não reabre o câmbio geral."
}
],
"external_formalities": [
{
"item": "MRFTA/CER e remissão67(7)",
"data_needed": "Correspondência concreta de rubricas/CER para novos casos;67(7)refere62(6),nova taxaestá62(5);manteroriginal",
"resolution": "Preparação/exportação disponível;sem adivinhar código,assinatura ou submissão."
},
{
"item": "ActosAT",
"data_needed": "Submissão,recepção,aceitação e eventuais comprovativos externos",
"resolution": "Externos;exportar não executa nem certifica esses actos."
}
],
"currency_gap_previous": "Resolvedforbaseandforeignwithholdingproofbyexistingoperationalmechanism;no newselector ormeanformula. ATremittanceamount remainsactualdocumentedMZN.",
"new_organizational_restrictions": false,
"restriction_origin": "Tempoexpressedreuse;legalrates/conditionsfromacceptedBR;optionaltypedlinks/fingerprints aretechnicalchoices,notnewapprovers.",
"L3_ISPC": "Preserved;ISPCinterest/otherexcess/instructionsinexistingmatrix;IRPSstillonlypreviousdemonstratedcase;P001/P058nonblocking;P084/P085closed;statistics/AIdeferred.",
"L5_integrally_completed": false,
"IRPC_integrally_completed": false,
"IRPS_integrally_completed": false,
"schema_backend_config_dependency_changes": false,
"active_changes": false,
"execution_remaining": [
"Authenticatedfreshdestinationcomparison,backupandisolatedrestorebeforeinstallation.",
"FastforwarddeliverybyexistingGitprocessafterfreshguards;nevermergerootP001experimentalruntime.",
"Verifyinstalledruntime/compiledmarkers/persistentfiles/configuration/schema/permissions/dataunder equivalentidentity;reuseacceptedfunctionalproofs."
],
"compiled_markers": {
"Calcular e guardar retenções IRPC": [
"assets/services-Es7_7t9u.js"
],
"Base do rendimento/conversão por resolver:": [
"assets/project-dossier-DZQJzKcc.js"
],
"Retenção liberatória20%62(3)a/b": [
"assets/project-dossier-DZQJzKcc.js"
],
"Reutilizar selecção cambial": [
"assets/services-Es7_7t9u.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-Es7_7t9u.js"
],
"Calcular e guardar restituição E": [
"assets/services-Es7_7t9u.js"
]
},
"active_readonly_revision": {
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"branch": "main",
"built_at": "2026-10-25T16:24:27.707113+00:00",
"manifest_sha256": "385a289f9ba26a632aa0164fbba3913cc8dc2fb891641881fc8d2dcda1951626"
},
"proof_hashes": {
"outputs/irpc-l5-grouped-20261025/preservation-before-tests.json": "ab8a892a14cd7cac916cbda51c1904eae87f3008d5f2e41d65494abb09e25dd8",
"outputs/irpc-l5-grouped-20261025/frontend.txt": "1939704865fc1f963adf4616837b615aeb5dfb7d5fa1567b8dc9d978bd39299a",
"outputs/irpc-l5-grouped-20261025/directed-capital.txt": "ba5dbd9d0047decb36e646f6152258552f0a36e34141b60070e0c36e41b4d610",
"outputs/irpc-l5-grouped-20261025/directed-report.txt": "2bc8ac7c9e5bfdfe18a59eb3e0eb7e2450c9ae0cb211efb4e07752851c5250a7",
"outputs/irpc-l5-grouped-20261025/directed-fx-origin.txt": "121c998e6d95820b8d6dda8fc09dc9d190416d3f64e5fc8dfed6df78dd18e523",
"outputs/irpc-l5-grouped-20261025/api.txt": "58365c069bb4c5d7bc91c24834575c19e1458049b73f5b42e9b1e543cd2b4944",
"outputs/irpc-l5-grouped-20261025/types-final.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"outputs/irpc-l5-grouped-20261025/build-final.txt": "db910282d69133fbdaee6c5d22b0397d377ed0b652072094be0a165884d97fba",
"outputs/irpc-l5-grouped-20261025/ui-fx-preview.txt": "a5ddc73db4cf9a8424ce0a8fcec9da55d8828f2cb13faf9f8715c0bcd6074523",
"outputs/irpc-l5-grouped-20261025/ui-report.txt": "0561e14566e4b9b4ab333c5c2a13b03f055c4ae413d3f9d211e663f2da38a7b5",
"outputs/irpc-l5-grouped-20261025/preparation.html": "c3c3e8df77e3f22e34e0cfbd2a8cc04a7d3cdc2e7080a0a70415f8f1c661818b",
"outputs/irpc-l5-grouped-20261025/active-baseline.json": "2f2d1a9d3e311f12099d2372d0c1a01eb5ff3918a39218c73b668dfbe51c66f8"
}
}
@@ -0,0 +1,22 @@
{
"status": "directed_presentation_delta_passed",
"base": "4d6f8282302c7646bd7350b8d67695d005feab9a",
"authorization": "Tempo:each calculation identifiesincomeclassification,rateanddefinitive/onaccountnature.",
"changed_runtime": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "919a6b7427fcbf67976797358dde0d02a3aba1121bb827b17280b13c0ddc3bd4",
"arithmetic_input_persistence_logic_changed": false,
"verification": {
"presentation": "1newdirectedtest;all6savedcases showcategory/rate/nature inPortuguese;frozendataunchanged",
"affected_export": "1existingexportcase;obsoleteEnglishlabelassertionupdated",
"types": "exit0",
"build": "exit0"
},
"proof_hashes": {
"presentation.txt": "7b348f1e6d64ac0e5cab732175e69fa32154db504e7781c028ced14ec703aaf8",
"export-presentation.txt": "54ada0166f309a216fdbc294bcee98283392b09a2d20a6b2718f2584fb78a133",
"types.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"build.txt": "2291bfc0b02957632c92a3a39215c35931a469eba4548473db4de26135468eed"
},
"other_accepted_proofs": "Reused;no new calculationround.",
"active_changes": false
}
@@ -0,0 +1,521 @@
{
"status": "installed_scoped_IRPC_reliefs_delta_verified",
"candidate_installed": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"previous_installed": "2b33a1c343d192f80fb24aac2a27b2d375af5601",
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"authorization": "Tempo: disponibilizar entrega conjunta via Git,backup/restauro fresco e conferência do delta;preservar2b33a1c3,L3,ISPC,câmbio;L5 parcial.",
"fresh_backup": {
"stage": "/var/backups/investmoz-irpc-reliefs-delivery-20261025/backup",
"created_at": "2026-10-25T18:00:39Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "3dc0eeea326beff9a7780f3a11ef1ed23a58dbaab8382db975ddfb356d6206c8",
"files_sha256": "d0dc27540dd41131c0fbf923b15b05fefc81760d80bfb0bd8ce04bf80ec9eb50",
"restore_verified": false
},
"isolated_restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l5_restore_20261025",
"port": 55441,
"source_dump_sha256": "3dc0eeea326beff9a7780f3a11ef1ed23a58dbaab8382db975ddfb356d6206c8",
"active_database_writes": 0
},
"preflight": {
"free_bytes": 6596661248,
"existing_pipeline_minimum_bytes": 5368709120,
"space_guard_satisfied": true,
"installed": {
"status": "installed",
"commit": "2b33a1c343d192f80fb24aac2a27b2d375af5601",
"release": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"previous_release": "/var/www/investmoz-homologacao/releases/5c0cb25cea7826811c389b55a64bcdf5e43b937f-32c4fd00",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"release_revision": {
"commit": "2b33a1c343d192f80fb24aac2a27b2d375af5601",
"branch": "main",
"built_at": "2026-10-25T17:27:10.176918+00:00",
"manifest_sha256": "75b06330161a813a10e3eb3a044e2ba4a924537dae381f97d0c8d4ee7295295a"
},
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"configuration_keys": [
"repository",
"branch",
"target_url",
"legacy_root",
"state_root",
"release_root",
"current_link",
"shared_assets",
"php",
"schema_contract",
"ci_environment",
"postgis_image",
"test_database",
"qa_port",
"retention",
"webhook_secret_file"
],
"safe_paths": {
"repository": "nala/Investidor-V2",
"release_root": "/var/www/investmoz-homologacao/releases",
"postgis_image": "postgis/postgis@sha256:01a6a70e41e6c4467c8f55f6063555ed72db2d6662cd0d571040d42eadaeb6f6"
},
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
},
"protected_delta": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"installed": {
"status": "installed",
"commit": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"release": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"previous_release": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 4,
"preserved_L3_ISPC_FX_runtime_files_verified": 28,
"documentary_files_verified": 29,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "df13c9623faded047b71df595d350ec7"
},
"after": {
"rows": 106,
"checksum": "cf7d9fdcfb64c81360cce81a5fa8c45d"
}
},
"sessions": {
"before": {
"rows": 15,
"checksum": "2c17940b66d6fd97d011edabbbf9ec47"
},
"after": {
"rows": 16,
"checksum": "4b7ab676493d6d1892d9933b3fde1780"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"schema_permissions": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 15,
"after_rows": 18,
"changes": [
{
"key_sha256": "4dd9d761c194f0c736e2b800add6792a790734c947d6de06bb7d91dc8778ec3b",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "93dba7d9de797b0301f4395afa891df1c9803a7abbd2f5c083ebb4a01569f75e",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "0208243bb27c67eee43773c1d4f3df5a1df5a24af6402a68de18bb518ce27beb",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public_delta": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"branch": "main",
"built_at": "2026-10-25T18:06:03.871601+00:00",
"manifest_sha256": "feb2dce3fc8845c6307c982323b3e3523b333a018189c47488f9fcba25490555"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Calcular e guardar retenções IRPC": [
"assets/services-rCdKRO1R.js"
],
"Dispensa de retenção": [
"assets/project-dossier-I7GMfANo.js",
"assets/services-rCdKRO1R.js"
],
"Limite convencional": [
"assets/project-dossier-I7GMfANo.js"
],
"Portugal–Moçambique — royalties, artigo 12": [
"assets/project-dossier-I7GMfANo.js"
],
"Informação insuficiente: documente residência convencional": [
"assets/project-dossier-I7GMfANo.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-rCdKRO1R.js"
],
"Calcular e guardar restituição E": [
"assets/services-rCdKRO1R.js"
],
"Reutilizar selecção cambial": [
"assets/services-rCdKRO1R.js"
]
},
"assets": [
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-document-CR2W33oB.js",
"status": 200,
"sha256": "d5e23e7b8da99bdf4368991f54c6d4d5a12c206a18eeef754f0bc0f68183865c"
},
{
"file": "assets/project-dossier-I7GMfANo.js",
"status": 200,
"sha256": "2e5134e2163dbd23a83374d9e06e2ed68b3e37009f3ed07e97af7aa34f97e8ca"
},
{
"file": "assets/services-rCdKRO1R.js",
"status": 200,
"sha256": "ecd38dd17a4b371f2bc55167887206a98db8f066e6ab3f66b7a0b1938fdcf49d"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-GOBc44N3.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-relief-preparation.ts",
"sha256_LF": "e41a389ad0b5d3f33985e375b0c488eed8c2d185257eec1cf5f7d40fccd365d4"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "75bf1c5940595e90d7a27355aeae6f9fdca4841f3e9ce3cb02103376bbd4d91b"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "28dd35e40c5d8440adad01131714d324f0c7fcdfeb3f6ddd9d27750d563b5e4f"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
}
],
"preserved_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
}
],
"accepted_QA_proofs_reused": {
"routes": "normal Wayfinder generate --with-form through guarded QA wrapper",
"types": "tsc --noEmit passed",
"build": "complete QA build passed; existing optional-font/chunk-size notices only",
"frontend": "9 new tests passed",
"compatibility": "5 directed IRPC cases passed;no repeated L3/ISPC/FX suites",
"api": "1test/17assertions;private endpoints;55441/simulator_fiscal_delta_20261021_test;DatabaseTransactions rollback",
"report": "retentions preparation and financial dossier from actual API recovered sample",
"ui": {
"calculation": true,
"localSaveRecovery": true,
"privateApiProof": "IrpcReliefsDraftTest, separate",
"report": true,
"insufficientInformation": true,
"errors": []
}
},
"installer_report": {
"status": "installed",
"commit": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"release": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"previous_release": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"ce746d889d5711f23f4e0ac8d9802997b5e106f9"
],
"finished_at": "2026-10-25T18:06:07.393002+00:00"
},
"space": {
"status": "dependencies_archived_and_verified",
"versions": 5,
"free_before": 5281300480,
"free_after": 6596743168,
"receipt": "/var/backups/investmoz-build-dependencies-irpc-reliefs-20261025/receipt.json",
"protected": [
"/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"/var/www/investmoz-homologacao/releases/5c0cb25cea7826811c389b55a64bcdf5e43b937f-32c4fd00"
],
"active_or_previous_release_modified": false,
"source_data_backups_deleted": 0
},
"remaining": [
"Other68paragraphs and digital/resident-specific cases",
"Other countries,treaties,EP-related and special-relationship excess cases",
"Dividends,interest-specific treaty branches",
"Late-payment interest,rectifications,aggregation,MRFTA/CER/form filling",
"External treaty claiming formalities are not declared satisfied by this calculation"
],
"database_migrations": 0,
"content_imports": 0,
"L5_integrally_completed": false,
"scope": "Only demonstrated68d/68f and qualifiedPT-MZ12royalties/equipment;nextinterest/MRFTAincrementstaysQA",
"evidence": {
"backup.txt": "53019c43c14005ca429e747a38d909b175218490add7fa416d7b3c387211db3b",
"compact-dependencies.txt": "4f087279b4760e71de0621da342d2dea14dbf38272816e938d5b9e6c171afe1d",
"installed-protected.txt": "0dff5ae05c6e73542c99fa14f0c06fcf87e7c096d29ff80b1517d21b57404504",
"installed-public.txt": "ae35a04719d1f05478b4936d4d563f9050c47f1db7d9b69610322e7653878858",
"integration.txt": "1c4d1be9b3a758a39529c69ebf87eda0b2dea36aef7622ba550ca7021dc41b6f",
"operational-delta.txt": "711f26fd0e56b8b52cef90d6245bbf32f7ec1758f5af8fcb8112241a919dbd94",
"preflight.txt": "90411a15339db664782a58139072c0fec52331d5a336348d260d6e336f2d299e",
"restore.txt": "a199e138c500d1f94da75ab38022932aa37232585ca2a6914eaf1dea91accf1a",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status1.txt": "595260a11ec30b4e7ef3e2a2aad11a178077283300f3572270a8d104307fe3ad",
"status2.txt": "4de7380a350e99585cbeea3646331759892b469aae5fd121effdb4f18fa39922",
"status3.txt": "49c26c68447722bfafed48930cd7cf0da62a088d2f66c05b3ef0ed90c3dc32b8",
"status4.txt": "7cbb15d32c6b6455b60df644f045880854c7acc4e21dfce0dd77e0df88c2a97e",
"status5.txt": "7cbb15d32c6b6455b60df644f045880854c7acc4e21dfce0dd77e0df88c2a97e",
"status6.txt": "a1224e56d81b8fbed83555dd413084cb9fff74a6b4f88960ea83ee6faec09f2f",
"status7.txt": "e2b53e3916f2a77a530f663d971d66fe495aefd1159d37b4e7c595dd93f3bf0c"
}
}
@@ -0,0 +1,330 @@
{
"status": "QA_demonstrated_grouped_candidate_not_installed",
"baseline_reported_installed": "2b33a1c3",
"branch": "codex/irpc-l5-reliefs-qa-20261025",
"implemented": [
"CIRPC68d qualified on-account services/equipment",
"CIRPC68f own-property management,not fiscal transparency",
"PT-MZ12 qualified royalties/equipment10%gross definitive",
"Insufficient/contradictory/out-of-period evidence remains indeterminate",
"Private API persistence,recovery,history;standalone report and complete financial dossier",
"IRPC dossier section association restored"
],
"runtime_delta": [
{
"path": "resources/js/lib/irpc-relief-preparation.ts",
"sha256_LF": "e41a389ad0b5d3f33985e375b0c488eed8c2d185257eec1cf5f7d40fccd365d4"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "75bf1c5940595e90d7a27355aeae6f9fdca4841f3e9ce3cb02103376bbd4d91b"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "28dd35e40c5d8440adad01131714d324f0c7fcdfeb3f6ddd9d27750d563b5e4f"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
}
],
"verification": {
"routes": "normal Wayfinder generate --with-form through guarded QA wrapper",
"types": "tsc --noEmit passed",
"build": "complete QA build passed; existing optional-font/chunk-size notices only",
"frontend": "9 new tests passed",
"compatibility": "5 directed IRPC cases passed;no repeated L3/ISPC/FX suites",
"api": "1test/17assertions;private endpoints;55441/simulator_fiscal_delta_20261021_test;DatabaseTransactions rollback",
"report": "retentions preparation and financial dossier from actual API recovered sample",
"ui": {
"calculation": true,
"localSaveRecovery": true,
"privateApiProof": "IrpcReliefsDraftTest, separate",
"report": true,
"insufficientInformation": true,
"errors": []
}
},
"preserved_FX_files": [
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
}
],
"sources_inventory": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"bytes": 308401
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"bytes": 159748
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"bytes": 319577
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
"bytes": 256695
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
"bytes": 2267865
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"bytes": 440018
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
"bytes": 9456358
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
"bytes": 329070
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
"bytes": 17966640
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
"bytes": 905551
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
"bytes": 665722
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
"bytes": 590418
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
"bytes": 135471
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
"bytes": 730017
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
"bytes": 900370
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
"bytes": 2127554
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
"bytes": 1604284
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
"bytes": 1603184
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
"bytes": 1990307
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
"bytes": 147521
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
"bytes": 1894997
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
"bytes": 161625
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
"bytes": 1834284
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
"bytes": 1676884
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
"bytes": 186487
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
"bytes": 187572
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
"bytes": 309350
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
"bytes": 199331
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b",
"bytes": 197027
}
],
"new_sources": [
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
"bytes": 199331,
"url": "https://dcjri.ministeriopublico.pt/sites/default/files/documentos/instrumentos/rar36-1992.pdf"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b",
"bytes": 197027,
"url": "https://files.dre.pt/1s/2009/05/08900/0275202756.pdf"
}
],
"remaining": [
"Other68paragraphs and digital/resident-specific cases",
"Other countries,treaties,EP-related and special-relationship excess cases",
"Dividends,interest-specific treaty branches",
"Late-payment interest,rectifications,aggregation,MRFTA/CER/form filling",
"External treaty claiming formalities are not declared satisfied by this calculation"
],
"active_changes": false,
"active_verification": "No fresh live inspection claimed;2b33a1c3 remains last reported installation",
"schema_config_permissions_delta": false,
"L5_integrally_completed": false,
"L3_ISPC_FX": "Unchanged;accepted proofs reused;no repeated functional suites",
"installation_remaining": "Existing Git release process,destination comparison and fresh backup/restore safeguards at installation",
"proofs": [
{
"path": "outputs/irpc-reliefs/api.txt",
"sha256": "5cccf4ee4e62ae00ef85276d48482fa8c13e202ddf68b6d79b1948977fb1f597"
},
{
"path": "outputs/irpc-reliefs/build.txt",
"sha256": "c60d4a5285f57a6458285163f64279d87558a8119f9b386cad8d12861d49e025"
},
{
"path": "outputs/irpc-reliefs/calculated.json",
"sha256": "563e05189c0a1255bf071fd1086aa8e67d6f0872891c5851dccbfc0d944752fe"
},
{
"path": "outputs/irpc-reliefs/compatibility.txt",
"sha256": "f37ad0ac9a0f2675fa4199f7600f3ae4e5a2df35a7294fe6e5aefd8024344051"
},
{
"path": "outputs/irpc-reliefs/dossier.html",
"sha256": "a34c2e9ef8b4d202e23412aaf6862ef9d603efeee0518a16adeb9d895f775641"
},
{
"path": "outputs/irpc-reliefs/dossier.json",
"sha256": "717561321d4b6c7659f0e6ab82c0e411ada0002a4f5436ba42092f8002f96076"
},
{
"path": "outputs/irpc-reliefs/dossier.txt",
"sha256": "a0473de355821758c4d320eea8e7af76a0d196a9cee652c71af723d6f69832f0"
},
{
"path": "outputs/irpc-reliefs/frontend.txt",
"sha256": "f86464b0d6a36ccfc39e22c0616d4a2e4f657126da134cb2014fcc199a11bdf2"
},
{
"path": "outputs/irpc-reliefs/index.html",
"sha256": "6bb76e37ac20a73cb9ffcda14f1ac9db701aa01bc2ef2f62fc5adaaffb640ca8"
},
{
"path": "outputs/irpc-reliefs/Lei-19-2013-BR76.pdf-review.png",
"sha256": "b62716ed89669622a33bde81a5ab6dcf0a6faafaf41726a09cd5b473b59abab1"
},
{
"path": "outputs/irpc-reliefs/Lei-34-2007-BR52.pdf19.png",
"sha256": "8355aa0b103439bb2b652b8499b2abf9bee1e4f3cc1af54b1be3ea059a2384f4"
},
{
"path": "outputs/irpc-reliefs/Lei-4-2012-BR3.pdf-review.png",
"sha256": "207224d8712713c9f4c5dda4e61539eba28f37af1ec70ef139cff0b450a62b2e"
},
{
"path": "outputs/irpc-reliefs/preparation.html",
"sha256": "2943b6cd21cc4ac043ae9b0605aee23c0fbbbed552842aeafef187ff963389a1"
},
{
"path": "outputs/irpc-reliefs/protocol-page1.png",
"sha256": "d981c72e254239c911554ff1289b578f7136bae7964a3d53f76a69094186cc04"
},
{
"path": "outputs/irpc-reliefs/PT-MZ-CDT-1992.pdf13.png",
"sha256": "2a57bc9924c0c826452bbc7f097b48c1899e6b642d6cdc247c244ace8993bb96"
},
{
"path": "outputs/irpc-reliefs/PT-MZ-CDT-1992.pdf14.png",
"sha256": "9fd31dcf17bdd1526390758a48a5afa8f9b98aebd83209b962ea97b7deef4006"
},
{
"path": "outputs/irpc-reliefs/PT-MZ-Protocolo-2009.pdf-review.png",
"sha256": "ba5ad799456a16959b83878c8935eb326ec3f0d87a2ba32e43217411e3f0dac9"
},
{
"path": "outputs/irpc-reliefs/recovered.json",
"sha256": "0b2378d1b8232b1424cf3d13e199146f4eabc330b9750a74b2b59f172741515e"
},
{
"path": "outputs/irpc-reliefs/types.txt",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "outputs/irpc-reliefs/ui-proof.json",
"sha256": "274ffe6c237da799aceff79df76087cf17f2a83505755aa6354d90b9d1f85abb"
},
{
"path": "outputs/irpc-reliefs/ui.png",
"sha256": "55df91c9dfc9a028eceafaf0b55b4ad2df892da491f8ac97d5d8edaacea73a4e"
}
]
}
@@ -0,0 +1,200 @@
{
"status": "QA_first_scoped_increment_not_installed",
"base_installed": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"branch": "codex/irpc-l5-withholdings-qa-20261025",
"L5_integrally_completed": false,
"IRPC_integrally_completed": false,
"IRPS_integrally_completed": false,
"scope": "Shared counterpart/document reuse;2026event chronology;10% digitalgoods/services/emoneycommission,nonresident nonattributabletoEP with explicit IRPCpayer/recipient/Mozambiquesource and no invokedspecialrelief;withheld/remitted/proven amounts separate;private draft persistence/recovery/report/preparationexport.",
"sources": [
{
"file": "Lei-34-2007-BR52.pdf",
"url": "https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei_34_2007.pdf_2063068952.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
"pages": 22,
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"usage": "Art67(3)/68 visually reviewed onPDF19;other text identified"
},
{
"file": "Lei-4-2012-BR3.pdf",
"url": "https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei-n-4.2012-de-23-de-Janeiro-de-2012.pdf_2063068952.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
"pages": 3,
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"usage": "Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy"
},
{
"file": "Lei-19-2013-BR76.pdf",
"url": "https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei-n_19.2013.pdf_2063068952.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
"pages": 2,
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"usage": "Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy"
},
{
"file": "Decreto-9-2008-BR16.pdf",
"url": "https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Decreto_9_2008.pdf_2063068952.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
"pages": 11,
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"usage": "Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy"
},
{
"file": "AT-MRFTA-19-39.pdf",
"url": "https://www.at.gov.mz/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIRPS%2FIRPS-IRPC%20MRFTA%20-%2019-39.pdf",
"pages": 2,
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"usage": "MRFTA p1–2 visually reviewed;consultation/preparation,not submission"
}
],
"existing_2026_source": {
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"citation": "Lei12/2025 PDF18–20;p2180(18–20);PDF19visually reviewed via identical text in received4pageexemplar;62(5),67(5/7)"
},
"excluded_legacy_sources": [
{
"file": "IRPColectivas.pdf",
"sha256": "06b1ac1310e973c2cc0406396177f9182922988b2ce4f95786f128c8310f907f",
"reason": "Decreto21/2002 revogadoLei34/2007 art3;consultation only,not2026calculation"
},
{
"file": "BR252-2022.pdf",
"sha256": "3339f1a11099466b01bf7b9024ff36266d056e6a914d1fa67f6b60f0e9f12f2b",
"reason": "Filename identifiesdate/issue butactual3rdsupplementDecree74/2022 tourism;notLei20/2022"
}
],
"inventories_reused": [
"8143localaccessiblefiles",
"39ATforms and189ATlegislation:all inventoriedbeforeselection",
"existingModelosinventory andIRPC_IRPSM39structure;no new workbook formulas trusted"
],
"runtime_delta": [
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "7a2f92695d5732c3c3525f70f23598bbfd9ab0346429e2997c9e07e324106eb5"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "e513e9ee9318d71fb4cc40b8b132e6bb5fc6cf88746061fff8c537cb5e88291a"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
}
],
"existing_integrations_additions_only": {
"resources/js/components/simulation-form.tsx": 2,
"resources/js/lib/project-dossier.ts": 2
},
"unchanged_previous_resources": 438,
"previous_original_PDFs_preserved": 21,
"new_PDFs_preserved": 5,
"verification": {
"new_frontend_distinct": 17,
"frontend": "frontend.txt:16pass;directed-cross-context.txt:1pass",
"API": "1test/23assertions;guardedloopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;allpreviousL3/ISPCmapsidentical",
"types": "types-final.txt:exit0",
"build": "build-final.txt:exit0",
"UI": "Actualcomponent calculation/save/recover/report andexport;localfileharness distinguishedfromprivateAPI;reuse existingacquisition at373 demonstrated;UI proof reused for unchanged positive route after final shared-payment-key refinement;directed test proves only that delta",
"previous_functional_suites_repeated": false
},
"examples": {
"retained": "base100000;10%;tax10000;remittance6000;outstanding4000;cost2026-10-02beforepayment2026-11-03=>period2026-10",
"suffered": "base20000;tax2000;documentedwithholding1500;difference500notannualcredit"
},
"remaining_calculations_and_mapping": [
{
"item": "Taxas normais e especiais dos demais rendimentos",
"needed": "Corresponder62(1–4)/67 por rendimento e período,com alterações20/2009,4/2012,19/2013 e20/2022. Ficheiro local BR252/2022 contém apenas3.ºsuplemento/Decreto74/2022,semLei20/2022;INM identifica esta na p2731. Texto exacto em falta não é revalidação de autenticidade.",
"resolution": "Implementar ramo dirigido após correspondência do texto aplicável;não usar2002 ou taxa genérica."
},
{
"item": "Residentes/EP e dispensa68",
"needed": "Corresponder62(5) novo com dispensas68,em especial68(d),titular/rendimento imputável aEP e factos de cada dispensa;sem confundir taxa com obrigação de reter.",
"resolution": "Ramo próprio por natureza/dispensa;sem presumirretenção10%ouzero."
},
{
"item": "Convenções/benefícios",
"needed": "Convenção invocada,artigo,residência,beneficiário,condições,período e documento aplicável",
"resolution": "Só o caso dependente permanece indeterminado;nenhuma taxa reduzida sem esses elementos."
},
{
"item": "Conversão cambial",
"needed": "Moeda,montante,data,taxa efonte aplicáveis à operação",
"resolution": "Conversão rastreável;sem taxa actual nem relabelagemMZN."
},
{
"item": "Juros/regularizações/guia agregada",
"needed": "Regra/taxa/base/período próprios;guias/declarações anteriores e pagamentos para substituições",
"resolution": "Não substituir juros porzero;preparação actual não é declaração rectificativa nem liquidação anualIRPC."
}
],
"external_formalities": [
{
"item": "MRFTA19/39:rubricas eCER digitais/moeda electrónica",
"needed": "Correspondência da nova categoria62(5)a/b às rubricas/CERdo quadro7;remissão67(7)para62(6)existe no original,masnova taxa aparece62(5).",
"resolution": "Preservar divergência e original;não renumerar,adivinharCERou bloquear cálculo positivo independente."
},
{
"item": "GuiaM39 anterior eMRFTAactual",
"needed": "Manter exemplares;instruçõesMRFTAidentificamperíodoúnico e prazonominaldia20mêsseguinte àdedução;calendário/prorrogação eprocedimento2026específico nãoinferidos",
"resolution": "Mapa de preparação/exportação;sem preenchimentofinalCER,assinaturaouusodosserviços."
},
{
"item": "ActosAT",
"needed": "Submissão,recepção,aceitação eeventualcomprovativo externo",
"resolution": "Externos aoportal;exportar nãoexecuta nemcertifica estes actos."
}
],
"preservation": "L3/ISPCbooks unchanged;131L1closures preserved;P001/P058nonblocking;P084/P085closed;statistics/AIdeferred. ISPCinterest/otherexcess/forminstructionsremaininexistingmatrix;IRPSlimitedpriorcase.",
"technical_choices": "Snapshotversion1 extension,exactfractions,source fingerprints andsharedpaymentdependencies areimplementationchoices;notnewTempoapprovals. ExistingIVApayments remainboundtoIVA;newIRPCproofregisteredonce/reusedwithoutoverallocation;noautomaticannualcredit.",
"schema_backend_configuration_dependency_changes": false,
"active_changes": false,
"proof_hashes": {
"outputs/irpc-l5-20261025/preservation-before-tests.json": "bd4ac1ee0e0d892b204f30baeed8842d00787d4b1f20656479e11ccafaca279f",
"outputs/irpc-l5-20261025/frontend.txt": "40bfc0c12fbf5b1f690a7a12570fbdc390f039b9ac845bab4bbddca622bbbcee",
"outputs/irpc-l5-20261025/directed-cross-context.txt": "5303e16fb702f8e022ac694965345d2388779af278844a7262d66bcbc630fd16",
"outputs/irpc-l5-20261025/api.txt": "f2ec740d0df65c8336abcbea48bf49eecb8bfcc1c70440ba7a8b27d24707d9f3",
"outputs/irpc-l5-20261025/types-final.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"outputs/irpc-l5-20261025/build-final.txt": "28b7601fefa8d992c9ff7dcf95465a84358381d073dc5f537e37d9a48ae36d9e",
"outputs/irpc-l5-20261025/ui-report.txt": "545f5fdaabd96e5dad996e6992e0721a8f39ed4dd473d769450ea35bbf39c311",
"outputs/irpc-l5-20261025/ui-reuse.txt": "26fc3ae1fbb7c6a5afbc1f57181e93566415bd17d418aceebe7f0d579f99c532",
"outputs/irpc-l5-20261025/preparation.html": "dce6700bffbffb9885f80c777ba0d85c61b5303778f6993dd3f9d70eee3d9fde",
"outputs/irpc-l5-20261025/active-baseline.json": "2f2d1a9d3e311f12099d2372d0c1a01eb5ff3918a39218c73b668dfbe51c66f8"
},
"compiled_markers": {
"Calcular e guardar retenções IRPC": [
"assets/services-D_pyIjFg.js"
],
"Exportar preparação IRPC": [
"assets/services-D_pyIjFg.js"
],
"Reutilizar contrapartes e documentos existentes": [
"assets/services-D_pyIjFg.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-D_pyIjFg.js"
],
"Calcular e guardar restituição E": [
"assets/services-D_pyIjFg.js"
]
},
"active_revision_readonly": {
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"branch": "main",
"built_at": "2026-10-25T16:24:27.707113+00:00",
"manifest_sha256": "385a289f9ba26a632aa0164fbba3913cc8dc2fb891641881fc8d2dcda1951626"
},
"current_balance_followup": {
"receipt": "irpc-l5-grouped-qa-20261025.json",
"source2022_gap": "ResolvedbynewfullBR,p2731",
"currency_gap": "Resolvedthroughdeliveredmechanismforbaseandwithholdingproof",
"previous_proofs": "Preserved;originalscopeandhistorynotrevoked"
}
}
@@ -0,0 +1,359 @@
{
"status": "L6_first_scoped_adjustments_QA_not_installed",
"installed_baseline": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"branch": "codex/irpc-l6-adjustments-qa-20261025",
"QA_workspace": "C:\\laragon\\www\\portal-investidor-irpc-l6-qa-20261025",
"scope": "Projection from financial plan for resident general-regime subject,explicit12monthJan-Dec2026 mapping,MZN. First documented full addbacks36(1)c:noncontractual fines/charges and compensatory interest already included in accounting expense.",
"implemented": [
"reuse reconciled finance bridge;cash flows and loan principal excluded",
"per-document-line and expense-source traceability;positive cents,duplicate and source capacity guards",
"unknown case limits its own addition;partial result remains indeterminate if any adjustment unresolved",
"versioned separate opportunity book;save/recovery/history/stale source guards;installed L5 payload preserved",
"UI,partial HTML export and private recovered dossier reporting"
],
"not_implemented": [
"full taxable profit or taxable base/tax",
"automatic expense classification or actual accounting statement import",
"other addbacks/deductions,patrimonial variations,depreciation/tax amortisation,losses and collection",
"M20/M22 official field mapping/submission,annual withholding credits",
"automatic reuse of L5 simulated interest as actual expense",
"nonresidentEP/specialregimes/othercurrency/years/shorterhorizons"
],
"example": {
"origin": "synthetic projection",
"accounting_profit_before_tax": "6480.00 MZN",
"included_noncontractual_fine": "100.00 MZN",
"included_compensatory_interest": "20.00 MZN",
"partial_additions": "120.00 MZN",
"partial_adjusted_result": "6600.00 MZN",
"taxable_profit": null,
"taxable_base": null,
"tax": null,
"missing_reference_example": "Fine unsupported -> addition20 only;partial adjusted total indeterminate;principal financial result retained"
},
"verification": {
"frontend_new_tests": 7,
"private_API": "1test/19assertions,DatabaseTransactions rollback,isolatedloopback55441/simulator_fiscal_delta_20261021_test",
"typescript": "pass",
"QA_build": "pass exit0",
"UI": {
"calculation": true,
"localSaveRecovery": true,
"report": true,
"missingInformationPartial": true,
"independentAdditionPreserved": true,
"download": true,
"privateApi": "IrpcNormalDraftTest separate",
"errors": []
},
"dossier": "generated from actual privateAPI recovered payload;contains6600",
"accepted_suites": "not repeated;reused",
"protected_runtime_files": 32,
"old_originals": 30
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "659e8f198632097f08404857e7766621aa38d98622aaaaba8f6cf31a993fa2f0"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "a512052f4a170d7c40f55ab2bfe695281be839a1cacb92c6c5ec0da8f6b3c3d7"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
}
],
"originals_preserved": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"new_source": {
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
"bytes": 6269169,
"url": "https://www.at.gov.mz/api/webdav?path=%2FLEGISLA%C3%87%C3%83O%2FLEGISLA%C3%87%C3%83O%20GERAL%2FLEI%2FLei%20n%C2%BA.%2019-2009%2C%20de%2010%20de%20Setembro.pdf",
"read_scope": "Official AT catalogue title19/2009 contains BR36 4th supplement pp272(13–17),including20/2009;all5pages inventoried,PDF4/p272(16) visually reviewed.36(1)a–i retained;adds j–n. Only36(1)c used in this L6 increment. No L5 points reopened;no library publication/import or scan claimed."
},
"source_review": "Visual:Lei34/2007PDF6/10;Lei20/2009PDF4;Lei4/2012PDF2/3;Lei19/2013PDF1/2. Lei12/2025 explicit amendment list and effective date reused from accepted evidence;20/2022 changes61/62 reused. No generic legal revalidation.",
"proof_sha256": {
"api.txt": "ebefca22663853108963f34aa70c98b81fee7196b9dc96c9dd74ad5e532326a5",
"build-exit.txt": "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9",
"build.txt": "8268c2fe3d56f20c0ede7f8245a70657f54410c4941f77f2c337aae430c1eb20",
"calculated.json": "22968d447a30ad222f83bfb1c142ea1900fc2456945bfc6d517440829dec32cc",
"dossier.json": "4f5f1810cb60f4bb117958d89a8332231e82424e28b6ad380678932042e4374a",
"download.html": "b09b0f69a7aef7812d700234dfedbec3e5f4136cdd9e7497ad094052e8bcea99",
"frontend.txt": "6526af2df04cf412dc0b54e6282d32faa86661a9130712ae5b176eb54646c7a0",
"index.html": "9af7b69c19ca2fb213988ace8eb927008cb0bea73e267f16dee363fcdbcb0f12",
"preparation.html": "588d3f573d1f5cfc6286cd7da726dbfae39cb29d99d0753547580779090aac8f",
"recovered-preparation.html": "588d3f573d1f5cfc6286cd7da726dbfae39cb29d99d0753547580779090aac8f",
"recovered.json": "409eca12048865fc0f4d7828e45fb30554c6ace018c7e9960976c962e9e25eec",
"types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"ui-proof.json": "c381d89d855a0d4cc2f57c6c97795060f6638990eac6f1bea0c2d47bc24ec4dd",
"ui.png": "4a10262a1ce34d962fdeadc62fb43fa5724b874db821e37af19c009f95342124",
"ui.txt": "2529288ae9c74296003f1f591d984f3671c5e8922a99116bec67d42062a03230"
},
"active_changes": false,
"schema_API_config_permissions_dependencies_delta": false,
"L5_operational_demonstrated_scope": true,
"L5_complete": false,
"L6_complete": false,
"L5_AT_questions": "J1-J5/C1-C5 unchanged;no repeated research without new information"
}
@@ -0,0 +1,690 @@
{
"status": "installed_joint_L6_taxable_base_and_normal_colecta",
"installed": {
"status": "installed",
"commit": "2f684e59846187f3fb8a338d9d6f6a08cadb4d0d",
"release": "/var/www/investmoz-homologacao/releases/2f684e59846187f3fb8a338d9d6f6a08cadb4d0d-b46cd351",
"previous_release": "/var/www/investmoz-homologacao/releases/5e02c23af863485f6881e409c8704ec7e7573cc9-e83fcca2",
"database_migrations": 0,
"content_imports": 0
},
"previous_baseline": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"backup": {
"stage": "/var/backups/investmoz-irpc-l6-colecta-delivery-20261025/backup",
"created_at": "2026-10-25T20:05:19Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "0f33d0bd0b8740bcc5363445a0fe59c85af42c16f02e723f9db3d0ef5898e020",
"files_sha256": "498b72430bbe9bd005856b65cb0d7e41e12898380e3324c5687044730796e95c",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l5_restore_20261025",
"port": 55441,
"source_dump_sha256": "0f33d0bd0b8740bcc5363445a0fe59c85af42c16f02e723f9db3d0ef5898e020",
"active_database_writes": 0
},
"preservation": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/5e02c23af863485f6881e409c8704ec7e7573cc9-e83fcca2",
"installed": {
"status": "installed",
"commit": "2f684e59846187f3fb8a338d9d6f6a08cadb4d0d",
"release": "/var/www/investmoz-homologacao/releases/2f684e59846187f3fb8a338d9d6f6a08cadb4d0d-b46cd351",
"previous_release": "/var/www/investmoz-homologacao/releases/5e02c23af863485f6881e409c8704ec7e7573cc9-e83fcca2",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 6,
"preserved_L3_ISPC_FX_runtime_files_verified": 37,
"documentary_files_verified": 31,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "7ff72d185a8c0dc624a7043fb5e68d72"
},
"after": {
"rows": 106,
"checksum": "49de7290166a6bdb90b3b2428106a6a5"
}
},
"sessions": {
"before": {
"rows": 28,
"checksum": "86bfbd7a7cc79988cf30ee47bc023e33"
},
"after": {
"rows": 29,
"checksum": "875df8b3f32a30fa7cbf7764e5290472"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"schema_permissions": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 28,
"after_rows": 31,
"changes": [
{
"key_sha256": "521c7bd9ee130bd5be6200caff027c80f95ac631aa7889296adfd3c9504726fe",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "52e0cf41e90b1efe2651dee901feefc64e2b2a2edc2ee76238ae280765f7794d",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "e4606ee652bc13d62167aff5f88b13ddb14a746bd84e0445961832b344cfa3e4",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public_verification": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "2f684e59846187f3fb8a338d9d6f6a08cadb4d0d",
"branch": "main",
"built_at": "2026-10-25T20:08:55.991892+00:00",
"manifest_sha256": "db2d2ff2e4f69877f6112cf57886720e3b57635b8bc993478f1cb2083fe94d23"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Iniciar determinação da matéria colectável": [
"assets/services-C5XL4k_e.js"
],
"Iniciar cálculo da colecta normal": [
"assets/services-C5XL4k_e.js"
],
"Colecta — regime normal": [
"assets/services-C5XL4k_e.js",
"assets/project-dossier-DG7_2Cag.js"
],
"Saldo final — âmbito L8": [
"assets/project-dossier-DG7_2Cag.js"
],
"colecta simulada:": [
"assets/project-dossier-DG7_2Cag.js"
],
"Saldo final a pagar ou recuperar por determinar emL8:": [
"assets/project-dossier-DG7_2Cag.js"
],
"Simulação pelos pressupostos introduzidos, sem confirmação fiscal dos juros.": [
"assets/services-C5XL4k_e.js"
],
"Códigos provisórios ou de simulação não são correspondências oficiais.": [
"assets/project-dossier-DG7_2Cag.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-C5XL4k_e.js"
],
"Calcular e guardar restituição E": [
"assets/services-C5XL4k_e.js"
],
"Reutilizar selecção cambial": [
"assets/services-C5XL4k_e.js"
]
},
"assets": [
{
"file": "assets/services-C5XL4k_e.js",
"status": 200,
"sha256": "4a97b79acd063296697ca75cc6c7be36dec142d697c74247a539457925ff2531"
},
{
"file": "assets/project-dossier-DG7_2Cag.js",
"status": 200,
"sha256": "4a04d6ca91df6db1c03f3a08a658a5f65dffbe9dd88f6e66aa2c62bc4b7250ed"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-document-Ctx2pT1S.js",
"status": 200,
"sha256": "fa9a89f7136265a8a701f723cfcc961c86f711566de71d77fe09194be97ca213"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-CN8XDMiO.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-normal-base.ts",
"sha256_LF": "ab7f7389bac23abd990d0d3a8d4c52b81f7b11066586d74b4254c6cc2c15392f"
},
{
"path": "resources/js/components/simulation-irpc-taxable-base.tsx",
"sha256_LF": "e4fe9f66d35d24aa68fd87de6a5a6a0e901706b270c18962fd0c7ab00f9abd93"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "682de29e04cd0e3a6c33ef7c5cb2ebf763e16448bdf787be5de66e94fac61bc1"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "78274f4d63162d0bb0fb32dcedbfc8b1de9b7eb4fbb7b638f8db1b8a064c0d58"
},
{
"path": "resources/js/lib/irpc-normal-assessment.ts",
"sha256_LF": "e5bce1e5015b52477febce1ba2a164e4064d887385f550b7ee55d1e20065b5a8"
},
{
"path": "resources/js/components/simulation-irpc-assessment.tsx",
"sha256_LF": "7174cc0160005a0c332ea40f02ba8a6d57985081b5ab45177ccd6e721bceea54"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
}
],
"originals": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"pipeline_checks": [
"OK (1 test, 3106 assertions)",
"built in 29.57s",
"OK (59 tests, 317 assertions)",
"# tests 906",
"# pass 906",
"# fail 0"
],
"accepted_proofs_reused": true,
"manually_repeated_accepted_functional_suites": false,
"sequence": {
"taxable_profit": "6700MZN simulated",
"taxable_base": "4400MZN simulated",
"normal_colecta": "1408MZN simulated,32%,2026",
"final_payable": null,
"final_recoverable": null,
"final_balance_scope": "L8"
},
"remaining_L6": [
{
"work": "Outros ajustamentos ordinários: admissibilidade de custos e correcções aos proveitos",
"evidence": "`irpc-normal.ts`, `NormalAdjustment.rule` e `calculateNormal`: apenas multas não contratuais e juros compensatórios36(1)c; `other` fica fora do recorte. `irpc-normal-profit.ts` não aplica `incomeCorrections`/`expenseCorrections` conhecidos não zero.",
"example": "Encargo de terceiro de250MZN com qualificação36(1)b, ou despesa não documentada36(1)g, incluído no resultado; a correcção não tem regra executável neste livro. A eventual tributação autónoma é outra operação, emL7.",
"completion_criterion": "Corresponder a regra geral e condições de cada categoria incluída, calcular acréscimo/dedução/exclusão com sinal e origem, evitar dupla contagem e demonstrar reflexo no lucro, base e colecta. A tributação autónoma que possa coexistir pertence aL7."
},
{
"work": "Dedutibilidade dos juros financeiros ordinários",
"evidence": "`irpc-normal-profit.ts`, `closeNormalProfit`: qualquer remanescente não zero de `interest_expense` mantém pendência; só os compensatórios integralmente acrescidos estão cobertos.",
"example": "Juros de financiamento comercial de120MZN, distintos de juros compensatórios, com finalidade/custo documentados.",
"completion_criterion": "Qualificar a parcela ordinária, dedutibilidade e correcção aplicável, conservar os montantes reconhecidos/pagos separados e fechar o lucro sem a equiparar a infracção. Relações especiais/benefícios e regras especiais seguemL7; taxa de juros compensatóriosL5 só é dependência se esse cálculo for efectivamente usado."
},
{
"work": "Reintegrações/amortizações fiscais e diferença face à contabilidade",
"evidence": "`irpc-normal-profit.ts`: `depreciation` positivo bloqueia o fecho; não existe mapa fiscal de activos/quotas nesta família de módulos.",
"example": "Depreciação contabilística120MZN com quota fiscal do activo ainda por corresponder.",
"completion_criterion": "Reutilizar activo, base e datas; corresponder método/taxa/limites e afectação ordinários, calcular quota fiscal e diferença para o resultado; manter mapas por activo/exercício e histórico. Incentivos, majorações e regimes especiais de activos seguemL7."
},
{
"work": "Variações patrimoniais e periodização ordinárias de montante não zero",
"evidence": "`irpc-normal-profit.ts`, `profitTopics`/`closeNormalProfit`: `positivePatrimonial`, `negativePatrimonial` e `timing` conhecidos não zero conservam valor e impedem o fecho; ausência/zero suportados são o caminho demonstrado.",
"example": "Variação500MZN fora do resultado, ou diferença temporal300MZN entre reconhecimento contabilístico e exercício fiscal, com natureza concreta documentada.",
"completion_criterion": "Corresponder natureza/ano/regra ordinária e decidir inclusão, exclusão ou ajustamento com sinal; impedir reaplicação em dois exercícios; demonstrar cálculo→gravação→recuperação→relatório. Operações especiais/benefícios do tópico `special` não são saldo deL6."
},
{
"work": "Resultado fiscal negativo do próprio exercício",
"evidence": "`irpc-normal-base.ts`, `calculateNormalBase`: lucro negativo é conservado, mas a base fica indeterminada; o livro de perdas só admite exercícios anteriores ao de utilização.",
"example": "Resultado fiscal actual−500MZN conhecido; não é uma perda anterior dedutível a si própria.",
"completion_criterion": "Tratar a situação da base/colecta nesse exercício e preparar a perda fiscal própria com origem/ano para utilização futura, conforme regra aplicável, sem confundir ausência de lucro, falta de informação, crédito ou consumo do saldo oficial. Perdas anteriores ordinárias já demonstradas continuam aceites."
},
{
"work": "Extensões do âmbito normal previstas no L6 original",
"evidence": "`irpc-normal.ts` fixa12meses/ano civil2026/residente/MZN; `irpc-normal-base.ts` exige exercícios anuais ordinários; a entrada deL6 no plano original inclui exercício fiscal e residência/EP.",
"example": "Caso de estabelecimento estável sob regime geral, ou período fiscal normal diferente do calendário/horizonte do plano; plano noutra moeda ainda sem reconciliação fiscal anualMZN.",
"completion_criterion": "Delimitar os casos normais a admitir, imputação de resultados ao sujeito/EP, datas/períodos e reconciliaçãoMZN usando o câmbio já entregue; demonstrar o percurso dependente. Não reimplementar câmbio, exigir pesquisa de todos os anos históricos ou aplicar automaticamente32% fora do período correspondido. Benefícios/convenções/regimes específicos pertencem aos lotes próprios."
},
{
"work": "Representação fiscal da colecta com fracção de cêntimo",
"evidence": "`irpc-normal-assessment.ts` conserva o racional e assinala `centExact:false`; não aplica regra fiscal de arredondamento/transcrição.",
"example": "Base0,01MZN×32%=0,0032MZN exactos; o caso1408MZN não tem esta ambiguidade e continua válido.",
"completion_criterion": "Identificar e executar a convenção aplicável à colecta/representação do formulário, mantendo o exacto e a rastreabilidade do valor transcrito. Não importar por analogia arredondamento de prestações/pagamentosL8 nem criar uma regra por defeito."
},
{
"work": "Correspondência dos dados de L6 aos exemplares M/20/M/22",
"evidence": "A família `irpc-normal*` produz mapaHTML/dossier e exclui expressamente correspondência/transcrição oficial; o âmbito original deL6 inclui M/20/M/22 e diferenças de ediçãoPDF/XLSX.",
"example": "Resultado, correcções, perdas, base4400 e colecta1408 existem no mapa de trabalho; os respectivos campos/anexos aplicáveis dos exemplares não estão correspondidos no motor.",
"completion_criterion": "Cotejar os exemplares já inventariados e mapear apenas os dados deL6 aos campos/versões efectivamente aplicáveis, com prova de preenchimento/recuperação. Os campos de retenções,pagamentos,créditos e saldo final sãoL8. Submissão electrónica/aceitaçãoAT não são presumidas como parte desta correspondência."
}
],
"remaining_scope_origin": "Existing L6 scope in traceability-and-manual.md table:normal costs/amortisations/losses/colecta/M20-M22,exercise and residence/EP;actual code at2f684e59. No new backlog or generic legal approval imposed.",
"excluded_from_L6_remainder": {
"L7": "Annual benefits/exemptions,reduced/cooperative rates,autonomous expense/capital-gain taxation,special operations,transferred losses and special-regime segregation",
"L8": "Annual retentions,PPC/PEC/otherpayments,credits/deductions tocolecta,doubletaxation,limits/carryforwards,reconciliation,final payable/recoverable balance/calendar",
"data_gaps": "Missing support,identity,amount,completeness or qualification under an already implemented rule is case data,not automatically new development",
"already_accepted": "Demonstrated6700->4400->1408 path,persistence/history/recovery/report,known/absent/missing handling,L3/ISPC/FX/L5 proofs"
},
"matrix_row": "AUD-SIM-INT02 existing matrix only",
"L6_status": "operational in demonstrated scope;partial only for the eight listed L6 work items,not for L7/L8",
"L6_complete": false,
"documentation_runtime_changed": false,
"new_legal_research": false,
"proof_files": {
"backup.txt": "26a42cfc6ac437c9bf7ffbd46f5f87b355b9e05e4fb82b10ee9b9f519dfe317c",
"compact-dependencies.txt": "80e9605f77b859630bd5d52c43908d72e76ee055e62892c3617b5e8c9cd82aaa",
"installed-protected.txt": "4c655d788b48214a1e6697bef459315756815eb6974e0c930c32a53334c8f7fc",
"installed-public-delta.json": "8d4d53ff066a5c48a505870973f26ca4d168e95376bb8085eed9b3cd6bdc0385",
"installed-public.txt": "4f6a74186b0d1371a7438a8e50bfbd0548b4039c3d8d04f850c8fbf0530bd9a7",
"integration.txt": "871bb24ee1fa0f45d096b85141124940500c6b84edfae01d8ff2bcf1d53bffd8",
"manifest-served.json": "db2d2ff2e4f69877f6112cf57886720e3b57635b8bc993478f1cb2083fe94d23",
"operational-delta.txt": "a24421b24ebc470bf0b0a12cc5345b41b229c1f5181320d2a7422f1bd044687c",
"preflight.txt": "2b68ed9a649a68ca1ba6c0c217a7e60287dc56d4af7e83c3dfe77e8a18a13f83",
"preparation.json": "d5c4124098015fef2a7f69bfc5d88f7789dc95cad38ef4430d24a34079f5b68f",
"progress.txt": "458df3545877efa51b97967221b8e3b2b737316970f3ccc63a01d5e07a6d8dda",
"remaining-section.md": "32ce79517daa0c9d33963f71c15e068eb5be548d7eddbf9874bab594b5592461",
"restore.txt": "524b246a6c0f62692c7a774347560962c4021bcf46e0368d9a075c44843b362a",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status-final.txt": "c20d733a19ff8d25afdf4a52e67193b1d0d255847d8aeef2c78c80a4dcf29476",
"status1.txt": "0d2be4308f1b2a4eda966d5bf4c10d719bf13cb87ba69b724bf90f765543fee4",
"status2.txt": "248a3a7e6921d2021971e43cc15df8bc0f76a5834a7ef6c46c839304e1a21349",
"status3.txt": "248a3a7e6921d2021971e43cc15df8bc0f76a5834a7ef6c46c839304e1a21349",
"status4.txt": "df65a125eb3ea41c86c9b0f2fd78ea77775aa240846eac75faeacbf459b55382"
}
}
@@ -0,0 +1,582 @@
{
"status": "normal_colecta_QA_joint_with_taxable_base_prepared_not_installed",
"installed_baseline": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"previous_QA": "b8d45796dd8785e26dd27375f6da8b745c73e6ad",
"branch": "codex/irpc-l6-colecta-qa-20261025",
"QA_workspace": "C:\\laragon\\www\\portal-investidor-irpc-l6-colecta-qa-20261025",
"scope": "Normal general rate32%,CIRPC61(1),annual2026,01January-31December,MZN,resident general regime,current taxable base. Explicit case classification/reference;special/reduced/benefit/autonomous cases not mapped to general rate by approximation.",
"sequence": {
"simulated_taxable_profit": "6700MZN",
"simulated_taxable_base": "4400MZN",
"general_rate": "32%",
"simulated_colecta": "1408MZN",
"final_balance_payable": null,
"final_balance_recoverable": null,
"final_balance_scope": "L8"
},
"implemented": [
"Reuse current taxable base from b8d45796,not profit as a substitute;no re-entry of4400",
"Versioned statutory rate identification scoped to2026 and resident-general/MZN classification;missing/special case keeps base visible but colecta indeterminate",
"Exact rational base*32/100;zero only when base known zero,subcent result retained exact without invented fiscal rounding",
"Optional calculationversion4;legacy1/2/3 readers/history remain supported and legacy3 current without recalculation",
"UI and exports preserve profit -> base -> colecta -> final balance order;known1408 never labelled final payable amount",
"FinalBalance explicitly not_calculated/payable null/recoverable null,L8;legacytax remains null",
"No withholding/payment/annual credit input,netting,refund or final settlement introduced",
"Private API create/update/recovery;known/missing dossier from actual recovered payload"
],
"source_review": {
"existing_primary_sources": [
"Lei34/2007PDF17/p768(71),61(1):32%general",
"Lei4/2012PDF2/p34(5),61(2) amendment reused",
"Lei20/2022PDF1/p2731:61(1)retained,61(2)temporary reductions end31/12/2025",
"Lei12/2025PDF18/p2180(18):amendment list excludes61(1);PDF20/p2180(20):separate61-Acapitalgain taxation and effective01/01/2026"
],
"visual_review": "2007PDF17,2022PDF1,2025PDF18/20;accepted originals unchanged",
"primary_index": "https://www.inm.gov.mz/pt-br/content/br-n%C2%BA-252-de-301222-boletim-da-rep%C3%BAblica-i-serie",
"new_originals": 0,
"not_inferred": "No reduced-rate extension,benefit eligibility,autonomous tax or rounding rule presumed. No L5 tax-rate/CER research reopened."
},
"verification": {
"frontend_new_tests": 8,
"private_API": "1test/40assertions;create/update If-Match/recovery;DatabaseTransactions rollback;isolated127.0.0.1:55441/simulator_fiscal_delta_20261021_test",
"Wayfinder": "existing guarded generation ofroutes/actions",
"typescript": "passed",
"QA_build": "passed exit0",
"UI": {
"normalColecta1408": true,
"ratePeriodClassificationVisible": true,
"baseReused": true,
"sequenceOrdered": true,
"finalPayableAndRecoverableUnknownL8": true,
"localSaveRecovery": true,
"download": true,
"specialCaseNoGeneralRate": true,
"missingClassificationIndeterminate": true,
"privateApi": "IrpcNormalAssessmentDraftTest separate",
"errors": []
},
"dossier": "known and missing outputs from actual private API recovery",
"accepted_proofs": "b8d45796,L5,L3,ISPC,FX reused,no manual repeated accepted suites;legacy3 snapshot only read/roundtripped",
"legacy_fixture_sha256": "ee1b1b49e0686bed3f8171beaacf9f57327850bcd36c96e1cc2ba5f1064ff585",
"protected_from_previous_QA": 39,
"protected_from_installed": 37,
"originals": 31
},
"runtime_delta_increment": [
{
"path": "resources/js/lib/irpc-normal-assessment.ts",
"sha256_LF": "e5bce1e5015b52477febce1ba2a164e4064d887385f550b7ee55d1e20065b5a8"
},
{
"path": "resources/js/components/simulation-irpc-assessment.tsx",
"sha256_LF": "7174cc0160005a0c332ea40f02ba8a6d57985081b5ab45177ccd6e721bceea54"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "682de29e04cd0e3a6c33ef7c5cb2ebf763e16448bdf787be5de66e94fac61bc1"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "78274f4d63162d0bb0fb32dcedbfc8b1de9b7eb4fbb7b638f8db1b8a064c0d58"
}
],
"runtime_delta_joint_from_5e02c23a": [
{
"path": "resources/js/lib/irpc-normal-base.ts",
"sha256_LF": "ab7f7389bac23abd990d0d3a8d4c52b81f7b11066586d74b4254c6cc2c15392f"
},
{
"path": "resources/js/components/simulation-irpc-taxable-base.tsx",
"sha256_LF": "e4fe9f66d35d24aa68fd87de6a5a6a0e901706b270c18962fd0c7ab00f9abd93"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "682de29e04cd0e3a6c33ef7c5cb2ebf763e16448bdf787be5de66e94fac61bc1"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "78274f4d63162d0bb0fb32dcedbfc8b1de9b7eb4fbb7b638f8db1b8a064c0d58"
},
{
"path": "resources/js/lib/irpc-normal-assessment.ts",
"sha256_LF": "e5bce1e5015b52477febce1ba2a164e4064d887385f550b7ee55d1e20065b5a8"
},
{
"path": "resources/js/components/simulation-irpc-assessment.tsx",
"sha256_LF": "7174cc0160005a0c332ea40f02ba8a6d57985081b5ab45177ccd6e721bceea54"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256_LF": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
}
],
"protected_previous_QA_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256_LF": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
},
{
"path": "resources/js/lib/irpc-normal-base.ts",
"sha256_LF": "ab7f7389bac23abd990d0d3a8d4c52b81f7b11066586d74b4254c6cc2c15392f"
},
{
"path": "resources/js/components/simulation-irpc-taxable-base.tsx",
"sha256_LF": "e4fe9f66d35d24aa68fd87de6a5a6a0e901706b270c18962fd0c7ab00f9abd93"
}
],
"originals_preserved": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"proof_sha256": {
"api.txt": "0d75de04e58963d6c3a6c4f8a8347770ca3ece09784e0ad2a9db6fd7e457af13",
"BR-248-I-Suplemento-1-2025.pdf-page18.png": "48e5cde488cb879bbe55f35a75e4153b4a29668757e9da49c3c67f69b581ed1b",
"BR-248-I-Suplemento-1-2025.pdf-page20.png": "9412fe514a0ee097ddd32c5bf212b72a87063d251118a4b97565bf29c0be634d",
"BR252-I-Serie-2022-Lei20-PESOE.pdf-page1.png": "be4585d255933806a3a79fa826c8bf2ee57a096b64dbb0b65b1eb0014bf05c80",
"build-exit.txt": "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9",
"build.txt": "00d322501e52ed59d4a36d1dde50a8cc15c6643f8af8a786da522ebe11308f6c",
"calculated.json": "16f6398a752c780781ad7d8a3133afbeb3bbc0776beadb7341d10ca2923ff58e",
"dossier-calculated.json": "d9f6b225930dbc0652593d67119bf06190e39dc46e73328ddb8d41a3d487fb87",
"dossier-missing.json": "cd8f122e98c62e6170676594bd413644323af6ed6d44ee2613bd5449ba67f636",
"download.html": "65ad3a808e97404fb0690a587ecf9a09cd58ced4d640956615d0aaf48e58d941",
"frontend.txt": "baae440ead1ff0649087f86431e4751db91d21f7639c40e1073e8b4fb6247dd0",
"index.html": "9af7b69c19ca2fb213988ace8eb927008cb0bea73e267f16dee363fcdbcb0f12",
"Lei-34-2007-BR52.pdf-page17.png": "55de382892c9ec9c9344aa8a8dc195abf0cffd41535a36bafadf1868f80614c0",
"missing.json": "bd9a8feca32ac0eb36abbc8c81b8eb898856bf9a14fe4bb2fd9ead35c87583d1",
"preparation.html": "d1c159d8747b25233f4b2f2cb729d2f9c56c117e9a9cbd9f4253d6a3b907fb46",
"recovered-calculated.html": "d1c159d8747b25233f4b2f2cb729d2f9c56c117e9a9cbd9f4253d6a3b907fb46",
"recovered-calculated.json": "7dc6602a5751822d556181d92a4517d631d1689b8d7073f9b14a206dfb22f57d",
"recovered-missing.html": "4f5c9d02bf4feb8413d452aaa4b5bbffead43bf1e8581e6074ebee39d17caf09",
"recovered-missing.json": "86087de983c1cb43406fb605b6ff10958b22e543206dac281f64656b7621f9cb",
"regulation.txt": "c680dfb73eeb638cf85d06fb0fe19550487de2994ce76f60077ef4baa88e3238",
"types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"ui-colecta.png": "2de2150e0a13c97a6e9ef641da5f426aa6f73a4e2e583dcc684c99de4b247b71",
"ui-missing.png": "33d0f91aa83e03aaf7667c6540aa73cd5d26852101b1109180dfa4c8fb7c1728",
"ui-proof.json": "491adb430be266abe0e8c95a311fa187d186a6d2beba2658f1431b6e61f58bed",
"ui.txt": "9bd1f1515b85823da48fc2a6b2b513b37b421e26764367f08b3dea23eb77e151"
},
"not_claimed": [
"Final annual payable/recoverable balance,annual withholding/payment/credit reconciliation reserved toL8",
"Reduced or benefit rates,autonomous taxes,capital gains61-A or other special cases",
"Fiscal cent rounding or official M20/M22 transcription/submission",
"Full L6 completion or installation of b8d45796/colecta candidate"
],
"prepared_joint_delivery": "b8d45796 taxable base plus this colecta increment over installed5e02c23a;bundle/manifest aftercommit. No push/installation.",
"active_changes": false,
"schema_API_config_permissions_dependencies_delta": false,
"L6_complete": false,
"L8_implemented": false,
"L5_questions": "Only dependent cases blocked;ten questions unchanged"
}
@@ -0,0 +1,145 @@
{
"status": "three_compatible_L6_sets_QA_prepared_not_installed",
"installed_baseline": "2f684e59846187f3fb8a338d9d6f6a08cadb4d0d",
"branch": "codex/irpc-l6-compatible-sets-qa-20261025",
"QA_workspace": "C:\\laragon\\www\\portal-investidor-irpc-l6-sets-qa-20261025",
"scope": "Ordinary documented rules, annual MZN periods ending2026, resident general or attributable EP result; no assumed fiscal rounding or final settlement.",
"demonstrated": {
"accounting_profit": "6240MZN",
"installed_addbacks": "220MZN",
"new_effects": {
"third_party_tax": 250,
"patrimonial_gain": 200,
"patrimonial_cost": -50,
"timing": 100,
"depreciation_difference": 20
},
"taxable_profit": "6980MZN",
"previous_losses_explicit_deduction": "2300MZN",
"taxable_base": "4680MZN",
"general_rate": "32%",
"colecta": "1497.60MZN",
"payable": null,
"recoverable": null,
"current_loss_case": "3820MZN loss;known zero base/colecta;no official carryforward",
"EP_case": "2025-07-01 to2026-06-30,12 monthly periods"
},
"new_proofs": {
"frontend_tests": 14,
"private_API_tests": 1,
"private_API_assertions": 78,
"database": "127.0.0.1:55441/simulator_fiscal_delta_20261021_test;DatabaseTransactions rollback",
"routes_actions_generated": true,
"typescript": "passed",
"build": "passed",
"actual_UI": "field editing;unsupported asset rate;missing interest;save/recovery;download;current loss",
"dossier": "from API-recovered calculated/missing/loss/EP JSON"
},
"preservation": {
"installed4_fixture_matches_accepted_sha256": true,
"versions1_to4_keys_unchanged_without_optin": true,
"other_runtime_changes": false,
"schema_API_config_permissions_dependencies_changed": false,
"L3_ISPC_FX_L5_accepted_proofs": "reused;not repeated",
"L5_ten_questions": "unchanged,only dependent cases blocked",
"active_data_changed": false
},
"runtime_delta": [
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "e33b3839aac53a1b7ca2a76eda0ec4c54015a6d1c75e386aaeb5d342943f5965"
},
{
"path": "resources/js/components/simulation-irpc-schedules.tsx",
"sha256_LF": "eebd6d9e4100920a5ebf91b800537ffe301fd6a994b86a3b080d673f4a9c9a42"
},
{
"path": "resources/js/lib/irpc-normal-assessment.ts",
"sha256_LF": "1dc6adc0835af033ef296d12cdc1e9ef354b2f54cd36e2349b2df66e369c1ee3"
},
{
"path": "resources/js/lib/irpc-normal-base.ts",
"sha256_LF": "85fa1eb78ce2b8a144a9f0dcda93b542083a7ff119cbc43f4334c87284bfd312"
},
{
"path": "resources/js/lib/irpc-normal-forms.ts",
"sha256_LF": "4e986addb9f2d74e7a80345f8f1e4d8e0b2f562c867fa6eee84880d9f72a3649"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "d5a2b52f7deb4cf35651188e04f103fcba950a007e3aa4de5ba7017e686614df"
},
{
"path": "resources/js/lib/irpc-normal-schedules.ts",
"sha256_LF": "b0045fd2c072998ebb290c2a8332c26d05a1f5f746b3beb1805508147497cac8"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "62d20bbcebb523f77fde950f623933a13f03283238665cf22fec9390f7ba9333"
}
],
"source_exemplar_added": {
"document": "Decreto72/2013,BR102,2suplemento,23December2013",
"official_issue": "https://www.inm.gov.mz/pt-br/content/conselho-de-ministros-suplemento-n%C2%BA-2-de-231213-pag-1074-3-24-br-n%C2%BA-102-boletim-da-rep%C3%BAblica",
"gazette_copy": "https://www.lexlink.eu/FileGet.aspx?FileId=1152468",
"local_original": "C:\\laragon\\www\\portal-investidor-irpc-l6-sets-qa-20261025\\outputs\\irpc-l6-sets\\decreto-72-2013.pdf",
"sha256": "922ef67cb0c1111405c3c0a092d8c302a74fba8a34d627b6e9e13223612e0659",
"visual_pages": [
1,
2,
17
],
"rate_table": "tableII/group3/items9=25%,9.1=20%,Gazettepage1074(21)/PDF17",
"consultation": "preserved in QA proof archive;no publication/import into active library",
"legal_application": "articles3–7,ordinary annual constant method,tableI precedence;other categories/methods visibly unsupported",
"scan_status": "not asserted"
},
"existing_form_sources": {
"M22": "4b61bd83d1fbcfd3b7b5c5523cea5923f7d0f65dc4c004eff58e5db38f763c88;three accepted page images reused",
"M20_workbook": "1ceca6f4c6d77853c1b2b445876599b42093175fa89eecf40590180956d83a9e;existing structure inventory reused;no third-party sample values or cached formulas",
"concrete_conflict": "M20A.1 refers result to M22 field201/Q8;PDF M22 uses200/Q10;automatic transfer blocked only for that mapping"
},
"remaining": "Concrete cases enumerated in same matrix/manual section25/10;cost limits/provisions/prior-year timing;remaining asset categories/methods;short periods/annual foreign-currency reconciliation;fractional fiscal representation;remaining result/form mapping. L7 benefits/special cases and L8 settlement remain own scopes.",
"L6_complete": false,
"installation_performed": false,
"next_delivery": "Joint Git bundle from installed2f684e59;fresh authenticated destination backup/restore and delta required only at installation,not performed in QA.",
"proof_sha256": {
"api.txt": "3c3142dd55febf17c5e16e3cfabf2266759be7290b8d5ac92823e0f71cbffa6a",
"build-exit.txt": "13bf7b3039c63bf5a50491fa3cfd8eb4e699d1ba1436315aef9cbe5711530354",
"build.txt": "ba955cab87896b78652787f188c092e79108fc0e5289f237be1ddf21d73dbbf3",
"calculated.json": "109426b86ae7c14463699b1d197064617f124ecec0c55085d9e81aeddc505a5a",
"decreto-72-2013.pdf": "922ef67cb0c1111405c3c0a092d8c302a74fba8a34d627b6e9e13223612e0659",
"decreto-72-2013.txt": "bbbf05f109201a6d31e153046576a088e6c0cca97ada07833d0499698d0afcfa",
"decreto-72-page1.png": "bb681e5df24a13d8484a521ae58e480c9dd23b4fd09de3ff11d5287ddd26a4f9",
"decreto-72-page17.png": "bb3468fde9f95576d8d6392a4c906ae904941ad35843c472d3671492c24f0945",
"decreto-72-page2.png": "9bf0f11a4724b079b494f640e905eee5bd278b729091e67aa03d0bfe71f5c273",
"dossier-calculated.json": "e9487c0325db125f8a0ff5266d137141916f329283857f2efc1f64732353454b",
"dossier-ep.json": "57b55c94118bd9767f06b4cd0673bcecbd8882ca1ec8681c393216a0fc3a7ac7",
"dossier-loss.json": "28eb77522fea39947a6cffd7419c24cd37795f361559050377f79d8b9f1cd1fb",
"dossier-missing.json": "bda0394cb059a1800a5dcf4728ba58a5b3ee975a87a7a938ebf5673e0ace1587",
"dossier.mjs": "9ab7bc1ad64ab8f04936068df0f0555749048d9edd9f2d48e8246542204257dc",
"download.html": "d084c44b3b527c9ed5f3f2c2e7ccd88229b0a19b9956e153e63b14618020acdb",
"ep.json": "9ae0b179c100ea5e642ce2ed9362b74e60bf1040bf6e7227592db84220babb23",
"frontend.txt": "92d096de8d364f04339178feeb6e77cf247cbc4974974bce56ba7728401bbdc5",
"index.html": "09941968500d2910121bdcb0029e326fc6d44bb025b01766654289a28caa62fa",
"loss.json": "8a0e85205db146a02fc9e06a2667cdce5a00e48ed8a7e7568a50d361e40671b2",
"missing.json": "1f52b06286d0724fe27d24ab91386732c873fc65064521c270faf357ac193135",
"preparation.html": "7ac15855048512bec05690170368df1ee4d4879f224a9d6c56749c3500d2d9c0",
"qa.tsx": "e2f5dc5e9a9c142b3fe65889c0cefcbfb03fb3b46957437af1108dbf20569647",
"recovered-calculated.html": "7ac15855048512bec05690170368df1ee4d4879f224a9d6c56749c3500d2d9c0",
"recovered-calculated.json": "db98c66ba9cf46a67ead4267d7b3d25b08275a4d8a11bbd316f4bec2b77644af",
"recovered-ep.html": "47df28ba65d7825192ec7fd3fad61998f378829046df2c1b3ab74b7fb32980ef",
"recovered-ep.json": "56f12435276c4cf9604f10e8c53bba61f1eb84dcaa5b911ac06242112d740764",
"recovered-loss.html": "a3f70ddcfe4a10a38110690b7583f1c89be6427fe347a321e9a395db6214fc6a",
"recovered-loss.json": "fe280337741a5004c13c83a41f83ca87c98c07f815fc87b617a0d5c8dbd03573",
"recovered-missing.html": "8989a835f9145e94434f31c90c96c801219494019fbc6167f1c8272d08c6debc",
"recovered-missing.json": "a4a24bc80dd6352c0883a1a555de9cd32a71335bd07b4826526ebe311700766f",
"types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"ui-calculated.png": "1578772454a4e5902d3ac8f607dbcda3b3c3b7e23d0870bbe233da036f15ba5e",
"ui-missing.png": "72d48f81bc67bd9342c5078d81044290912afacd305980806c42cd96b038a614",
"ui-proof.json": "7bd7a522b4307d8f72fb04317106c3b7cc53763fe8923017ae0f63a510b9bb9e",
"ui.cjs": "207eea61db65ac778f26f35beecd18387d6126b75e1effcf3e33c1e26e957215",
"ui.txt": "9b120d22b3e2539e8862c5ce5a973cce4fc2632a16680e7f997020f4e2cd0196",
"vite.config.ts": "11a4a8f0bf0394f380e731cfb30cf4a0f3de3c6f3734653491e1aa26f57315f1"
}
}
@@ -0,0 +1,599 @@
{
"status": "installed_joint_L6_through_scoped_simulated_taxable_profit",
"installed": {
"status": "installed",
"commit": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"release": "/var/www/investmoz-homologacao/releases/5e02c23af863485f6881e409c8704ec7e7573cc9-e83fcca2",
"previous_release": "/var/www/investmoz-homologacao/releases/7a11c4ef8f06ef149eb0488be3cd0749dc609bd0-68c76bdc",
"database_migrations": 0,
"content_imports": 0
},
"previous_baseline": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"backup": {
"stage": "/var/backups/investmoz-irpc-l6-profit-delivery-20261025/backup",
"created_at": "2026-10-25T19:38:10Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "5dfb2cd96d7c440e12ec860080660ee1e88f8704075f9814e3225421ab007c71",
"files_sha256": "117c6e457320c08b63cd69599f63c676f48ad8b90cac5d6091e9d748c8b8850c",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l5_restore_20261025",
"port": 55441,
"source_dump_sha256": "5dfb2cd96d7c440e12ec860080660ee1e88f8704075f9814e3225421ab007c71",
"active_database_writes": 0
},
"preservation": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/7a11c4ef8f06ef149eb0488be3cd0749dc609bd0-68c76bdc",
"installed": {
"status": "installed",
"commit": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"release": "/var/www/investmoz-homologacao/releases/5e02c23af863485f6881e409c8704ec7e7573cc9-e83fcca2",
"previous_release": "/var/www/investmoz-homologacao/releases/7a11c4ef8f06ef149eb0488be3cd0749dc609bd0-68c76bdc",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 6,
"preserved_L3_ISPC_FX_runtime_files_verified": 33,
"documentary_files_verified": 31,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "ed89c778b68dc12d870c1e1883be7e90"
},
"after": {
"rows": 106,
"checksum": "767a064eedb1c472eee28f9a0a59c907"
}
},
"sessions": {
"before": {
"rows": 25,
"checksum": "2821ae7c8c768e6f77acf2820265e3db"
},
"after": {
"rows": 26,
"checksum": "179f6c6d10853b16bb62ee44f1b7ca41"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"schema_permissions": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 25,
"after_rows": 28,
"changes": [
{
"key_sha256": "7ed81a892bf75b5fda7e5071799a98d547242fcc64a5a29c0f169994073eb2ba",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "f72c5658d3a886e194bf35fa62f9c2c94c793790736bf253f9520936c75844f9",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "c28bc1e32e3d9c0eca1c9e1ad610e6b238ea101b609bff46a41a1f7a416bf83b",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public_verification": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"branch": "main",
"built_at": "2026-10-25T19:41:48.731555+00:00",
"manifest_sha256": "316ad1f339fe14d64c8dce10ddf9c2ecc2080ce400fc9e87f9700de6e7333a59"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Iniciar conferência até ao lucro tributável": [
"assets/services-cKAPGaXt.js"
],
"Suporte da completude do sujeito passivo no exercício": [
"assets/services-cKAPGaXt.js"
],
"Valor conhecido zero com suporte;distinto de ausência declarada.": [
"assets/project-dossier-B6lVijAe.js"
],
"Ausência declarada contradiz o montante conhecido da origem.": [
"assets/project-dossier-B6lVijAe.js"
],
"lucro tributável simulado:": [
"assets/project-dossier-B6lVijAe.js"
],
"Simulação pelos pressupostos introduzidos, sem confirmação fiscal dos juros.": [
"assets/services-cKAPGaXt.js"
],
"Códigos provisórios ou de simulação não são correspondências oficiais.": [
"assets/project-dossier-B6lVijAe.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-cKAPGaXt.js"
],
"Calcular e guardar restituição E": [
"assets/services-cKAPGaXt.js"
],
"Reutilizar selecção cambial": [
"assets/services-cKAPGaXt.js"
]
},
"assets": [
{
"file": "assets/project-dossier-B6lVijAe.js",
"status": 200,
"sha256": "2882700d6723356a13be75f2287d9b71da3ba601ae95dee0e7c4b2cd9d31d690"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/services-cKAPGaXt.js",
"status": 200,
"sha256": "a62d8c8859d285db2fcddb89e93b358f6e8ceb2ee076d93c7ff1ea2934c5a8e1"
},
{
"file": "assets/project-dossier-document-bIxweCUO.js",
"status": 200,
"sha256": "88d93dd8177ed4b651b6f0b01ab494df38572bf136869a857581c8ab9b473dab"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-Q-Wi-bGe.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "387292520216d3d37870e4080880e5ec026702977a2f4c556be6c82dd34a7fce"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "d15a42d6bc295a4794b8427c668780335305d6091363002b570109aa0ac1aef9"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
}
],
"originals": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"pipeline_checks": [
"OK (1 test, 3106 assertions)",
"built in 30.45s",
"OK (59 tests, 317 assertions)",
"# tests 888",
"# pass 888",
"# fail 0"
],
"accepted_proofs_reused": true,
"manually_repeated_accepted_functional_suites": false,
"limitations": "6480+220=6700MZN simulated taxable profit in demonstrated ordinary annual case;not taxable base or tax payable. Known amounts,declared absence and missing information distinct. L6partial. L5questions only limit dependent cases.",
"L6_complete": false,
"next": "QA taxable-base determination:documented ordinary own losses and delineated deductions;no unrestricted subtraction of benefit amounts",
"proof_files": {
"backup.txt": "fa06ec92a10c5918b4273d1f8714d5be4fddf9e18ddfe739e9154b2eb0fb96cf",
"compact-dependencies.txt": "afa3afafaf78314fff511b52a1fbc4a2f25a28fa549f9100400f2bc9a01e3579",
"installed-protected.txt": "8417903e69430856d316dbbc0874e355bbbb8cd8b6a55ab1f5f184c9b872829c",
"installed-public-delta.json": "633c50e0befc472d4504bf714f6bb9f6cd8b133c191040c360a06f30e1710648",
"installed-public.txt": "cec9d549fa288f970b85f7feeb131363b163884a5871dc3274a7e6b954f5fddd",
"integration.txt": "55ad35300fee092fff8bd9ab78e446342dd7735533fd534a5d4cf6bc771193bc",
"manifest-served.json": "316ad1f339fe14d64c8dce10ddf9c2ecc2080ce400fc9e87f9700de6e7333a59",
"operational-delta.txt": "28e02f58f87bb099ca2fddee7be182d736b4b85e9c1140e9a51482813929457d",
"preflight.txt": "484186b67968f20f506127460ebd6d0805a5077d7943f48e4b8cd7c9d2a257f5",
"preparation.json": "88c48f4a53fb1a59c47552b79dbb0c4c5db37cfde3b214f6eced213074d1bdf5",
"restore.txt": "f89d146854467f33fc5fa8643ad2b6155fd5e143c85daa856fdd6f0c7ec7bd72",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status1.txt": "eeddc365cc723cf3ad4783203517ef713eafcf4db6a70a78bec9960d3084d0eb",
"status2.txt": "da80cda2b3fead23b76868de2f1538dbb30abf5f72487aa12361e744ba7609c8",
"status3.txt": "bba01cbcdacefa72b7c6e8065158a488e8476de911d707cf5a2c1f50a842f2ba"
}
}
@@ -0,0 +1,385 @@
{
"status": "scoped_taxable_base_losses_deductions_QA_not_installed",
"installed_baseline": "5e02c23af863485f6881e409c8704ec7e7573cc9",
"branch": "codex/irpc-l6-taxable-base-qa-20261025",
"QA_workspace": "C:\\laragon\\www\\portal-investidor-irpc-l6-base-qa-20261025",
"scope": "2026 resident general regime,declarative method,ordinary annual own fiscal losses,same taxpayer,complete corrected balances. Explicit proposed utilisation within balance/profit;no FIFO or percentage cap assumed. No positive-benefit rule,transferred losses,special/short periods or negative current-result base implemented.",
"implemented": [
"Reuse calculated taxable profit,no re-entry of6700;optional reuse of existing same-opportunity MRFTA NUIT preserves deliberate edits",
"Loss ledger by origin year,NUIT,assessed/corrected fiscal amount,previous use and explicit proposed current use;source/reference and ordinary-period/general-activity/balance facts",
"Five subsequent ordinary fiscal years41(1),activity/object restriction41(7),specific indirect/partial-exempt/transparency/correction/short-period dependencies identified",
"Expired or changed-object exclusions visible;positive request against excluded loss is not silently ignored",
"Cap by available balance and total profit;no implicit allocation order;negative base prevented through explicit reconciliation",
"Known benefits zero,declared absence and missing information kept separate;positive benefit amount recorded but no arbitrary subtraction15(4)",
"No official loss balance consumption on calculation/save/repeat;source uses unchanged",
"Optional calculationversion3 preserves currentversion2 and histories1/2;changed input makes onlynewresult stale",
"PrivateAPI create/update/recovery,UI and HTML/dossier from recovered known/missing payloads"
],
"examples": {
"profit": "6700 MZN simulated taxable profit,not tax",
"loss2021": "assessed1000-prior200=available800;proposed800,lastordinaryyear2026,remaining0",
"loss2024": "assessed3000-prior500=available2500;proposed1500,lastordinaryyear2029,remaining1000",
"base": "6700-2300=4400 MZN simulated taxable base;tax payable indeterminate",
"supported_absence": "Losses and benefits absent with support -> base6700,not assumed before evidence",
"missing_benefit": "profit6700 and proposed eligible losses2300 retained;base/deductions indeterminate",
"known_positive_benefit": "known200 preserved,not subtracted without implemented rule",
"expired2020": "lastordinaryyear2025;explicitzero request -> no deduction2026",
"negative_current_profit": "kept signed;base indeterminate,no automatic zero or current-loss carryforward"
},
"verification": {
"frontend_new_tests": 10,
"private_API": "1test/42assertions,create/update If-Match/recovery,DatabaseTransactions rollback,isolated127.0.0.1:55441/simulator_fiscal_delta_20261021_test",
"typescript": "passed",
"Wayfinder": "existing guarded routes/actions procedure",
"QA_build": "passed exit0",
"UI": {
"profitReused": true,
"baseCalculated": true,
"taxPayableIndeterminate": true,
"localSaveRecovery": true,
"explicitLossAllocation": true,
"sourceBalancesNotConsumed": true,
"overuseRejected": true,
"download": true,
"missingBenefitIndeterminate": true,
"positiveBenefitPreservedNotSubtracted": true,
"privateApi": "IrpcNormalBaseDraftTest separate",
"errors": []
},
"dossier": "known and missing outputs from actual API recovery",
"accepted_proofs": "reused,no manual accepted suite repeats;version2 snapshot only read/roundtripped",
"legacy_fixture_sha256": "105857393035cb5e7c569dc9e6c7b91f51c335b9799fc148b1bfee57057f3138",
"protected_runtime": 37,
"originals": 31
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-normal-base.ts",
"sha256_LF": "ab7f7389bac23abd990d0d3a8d4c52b81f7b11066586d74b4254c6cc2c15392f"
},
{
"path": "resources/js/components/simulation-irpc-taxable-base.tsx",
"sha256_LF": "e4fe9f66d35d24aa68fd87de6a5a6a0e901706b270c18962fd0c7ab00f9abd93"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "df3ac3ba0bd60a9687cc64bfa2d5766cc975d044b51901d96a815cc426255b5c"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "0f9fe320814db4a5329688cedaf9a2e1388812c80bb49ade21601392abce1a28"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256_LF": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
}
],
"originals_preserved": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"new_sources": 0,
"source_review": "Accepted CIRPC Lei34/2007PDF5/p768(59):15(1)a/15(2-4),PDF12/p768(66):41(1-7),visually read. Accepted amendment lists reused:Lei20/2009 adds41-A(transfer,not applied),4/2012,19/2013,20/2022,12/2025 do not change15/41 within this scope. No new L5 research. No indirect method,partial-exempt ringfencing,transparency,transfer41-A,short periods or positive benefit rule inferred.",
"proof_sha256": {
"api.txt": "7e78ac0a8460d463505b54ed510287b70030ddf65c115deeec8ab322de53d37b",
"build-exit.txt": "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9",
"build.txt": "b0ed7b4b3220a4dd33918c1297c0bda4ee219f205a63758ddd2c03d2e5753c00",
"calculated.json": "ee1b1b49e0686bed3f8171beaacf9f57327850bcd36c96e1cc2ba5f1064ff585",
"CIRPC-page12.png": "ac413f5d39bf353fcaa4adb5bc630f328f34c3cd9ebeef47e73bd08d99d28bb9",
"CIRPC-page5.png": "af1209cfc8c5820ec7d46652bc9a1d30ca30e21e6e7c7e3bf49e52cfb46812a7",
"dossier-calculated.json": "a0f4223464e40e85810ddbd868fd9ff7fc8d5c0b2071380389805ed6b80f5bc3",
"dossier-missing.json": "551a9231f7ab48405ff45117f4667b0ee8431726b5136a96d4bb77e2095a99ee",
"download.html": "db4b0f82ad31825c016d1f3cf70f8b8da3484d26408d0ae043b2b2049949472c",
"frontend.txt": "3be8a5ea29b874a5c3b768c328035ad9c793fdec3d6e51337715ad88f82318bb",
"index.html": "9af7b69c19ca2fb213988ace8eb927008cb0bea73e267f16dee363fcdbcb0f12",
"missing.json": "3607986c3ec80b800effe2a48bd623c94cf2039b84a645007236e5528286290c",
"preparation.html": "1f970ab58e6f71a3ee80e93331496104745a19c570b4273eff5978e7a312f7ac",
"recovered-calculated.html": "1f970ab58e6f71a3ee80e93331496104745a19c570b4273eff5978e7a312f7ac",
"recovered-calculated.json": "9bdd82a0a1b1a8b0a3fd18c0a54ef2ffa7233cf10f012d16c830e795b85129ea",
"recovered-missing.html": "29a11c4e9af4f35f36d032244fbcfaa843cc0d90f1051cd80fdda0b0e4ac7311",
"recovered-missing.json": "994f44a62032acf7c1b2805c312b90f0665176d3438b0cf10da9af06229cd809",
"types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"ui-base.png": "d53f7e096abedf6dc1361aa9be303c7c2afb5604ab02e9d704d8ffe52f6f3e3d",
"ui-pending.png": "d900c53f829675b5f4ab500ed36c85dd9a71605e6e4f727d5abc9193511d2039",
"ui-proof.json": "85d4bbade8f97b676b7ecade5b283df853b93c74eef4314cb27d39b1f9fad651",
"ui.txt": "13c8982f58552f00e26ef4eda1d83a20489d57ba51dcf368455a74500241e660"
},
"not_claimed": [
"tax collection,tax payable,annual withholding credits,M20/M22/submission",
"Official consumption of loss ledger or complete fiscal regime",
"Positive benefits automatically deductible from typed amount/reference",
"Full L6 completion or resolution of L5 ten questions"
],
"active_changes": false,
"schema_API_config_permissions_dependencies_delta": false,
"L6_complete": false,
"L5_questions": "Only actually dependent cases limited;existing ten questions unchanged"
}
@@ -0,0 +1,384 @@
{
"status": "scoped_financial_result_to_taxable_profit_demonstrated_QA_not_installed",
"installed_baseline": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"previous_QA": "664c88c8f7381548a2f1d8ecacdf10715e8408f5",
"branch": "codex/irpc-l6-taxable-profit-qa-20261025",
"QA_workspace": "C:\\laragon\\www\\portal-investidor-irpc-l6-profit-qa-20261025",
"scope": "Annual Jan-Dec2026,MZN,resident general regime,complete subject-year projection. Ordinary recognised revenues and indispensable documented ordinary costs,with no other exclusions/limits declared. Fines and compensatory interest36(1)c added back from existing entries. Positive depreciation and remaining financial interest require their own treatment and remain pending.",
"implemented": [
"Optional explicit annual review reuses existing plan and adjustment rows;no repeated financial amounts entered",
"Each financial line classified with support and known amount;declared absence cannot override nonzero source",
"Three persistent evidence states:known amount including zero,declared supported absence,missing information",
"Six existing-effect topics:positive/negative non-accounting patrimonial variations,other income/expense corrections,timing,special operations;known nonzero amount preserved but blocks this limited path until implemented",
"Taxable profit=financial profit before tax+supported addbacks only when subject-year complete and remaining effects expressly absent/known zero",
"No-adjustment and negative-result cases supported without presumed zero or loss carryforward",
"Version2 optional closure;legacyversion1 result remains current without recalculation,newinput changes invalidate only new result;history retained",
"Private API create/update/recovery,UI,HTML and dossier from recovered payload include all evidence states"
],
"examples": {
"known_case": "6480 financial profit +100 noncontractual fine +120 compensatory interest included in financial costs =6700 simulated taxable profit;ordinary remaining costs qualified with support;all other effects expressly absent/known zero",
"known_zero": "Income corrections known0 stored separately from absent patrimonial variations",
"missing_case": "Missing negative-patrimonial evidence -> taxable profit indeterminate;6480 financial profit and220 additions retained",
"unsupported_case": "Known positive variation500 or positive depreciation or financial interest remaining -> amount visible,profit indeterminate",
"no_adjustments": "Financial profit6600 with full review/no additions -> simulated profit6600",
"negative_result": "Financial result-5280 with full review retained signed;no carryforward or tax credit inferred"
},
"not_claimed": [
"Taxable base,tax collection,loss carryforward,annual withholding credits or M20/M22",
"Full normalIRPC or L6 completion",
"Actual accounting statement or tax authority confirmation;origin remains projected",
"General treatment of nonzero patrimonial changes,other corrections,depreciation/financial-interest limits",
"Any conclusion to L5 J1-J5/C1-C5"
],
"verification": {
"frontend_new_tests": 9,
"private_API": "1test/38assertions;create then If-Match update and recovery;DatabaseTransactions rollback;isolated127.0.0.1:55441/simulator_fiscal_delta_20261021_test",
"typescript": "passed",
"Wayfinder": "routes/actions generated using existing guarded procedure",
"QA_build": "passed exit0",
"UI": {
"calculationToTaxableProfit": true,
"localSaveRecovery": true,
"knownZeroDistinct": true,
"declaredAbsenceDistinct": true,
"missingInformationIndeterminate": true,
"absenceContradictionDetected": true,
"independentAdditionsPreserved": true,
"download": true,
"privateApi": "IrpcNormalProfitDraftTest separate",
"errors": []
},
"dossier": "both known and missing outputs generated from actual private API recovery",
"accepted_proofs": "reused;no manual repeat of accepted functional suites;legacy snapshot only read and roundtripped",
"legacy_fixture_sha256": "22968d447a30ad222f83bfb1c142ea1900fc2456945bfc6d517440829dec32cc",
"preserved_runtime": 33,
"preserved_originals_from_664c88c8": 31,
"installed_public_revision": {
"commit": "7a11c4ef8f06ef149eb0488be3cd0749dc609bd0",
"branch": "main",
"built_at": "2026-10-25T19:18:14.226356+00:00",
"manifest_sha256": "d78df5e7caee48690641143c8e8633b850db421468c837ec37992ee9cfa21aaa"
}
},
"runtime_delta_joint_from_7a11c4ef": [
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "387292520216d3d37870e4080880e5ec026702977a2f4c556be6c82dd34a7fce"
},
{
"path": "resources/js/components/simulation-irpc-normal.tsx",
"sha256_LF": "d15a42d6bc295a4794b8427c668780335305d6091363002b570109aa0ac1aef9"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "85b024a7f45ceb52efd6ff1f21d0eab1fd8fcf1ab59e4b5302c08685235c472a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a0909bbfcdf7e8542b010faa104fcb918e86ae38ddf096082d4d5be98d31b2b9"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "5207a2ffeb208cd5ace6713038cee85208020ee618194dca7114e94fc3200b6c"
},
{
"path": "resources/js/lib/irpc-normal-profit.ts",
"sha256_LF": "35dc586d9ab6c77405f3a46ed2ce3d9db74c54f338314d5e3c4959f0b6a55860"
}
],
"protected_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256_LF": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256_LF": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256_LF": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256_LF": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256_LF": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256_LF": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256_LF": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256_LF": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256_LF": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256_LF": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256_LF": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256_LF": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256_LF": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256_LF": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256_LF": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256_LF": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256_LF": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256_LF": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
},
{
"path": "resources/js/lib/irpc-interest.ts",
"sha256_LF": "f8e6390b3b2c58c296f7e3fd14576e06ae248bc0cabce1a666b7094611f2a7dd"
},
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "76dcce8954f68b081d500be61de9c5b146a452a3eb578a0b78776ba9e1f8051c"
},
{
"path": "resources/js/lib/irpc-mrfta-cases.ts",
"sha256_LF": "4266746076ab3f70312fd042351e24dd2f136c4f3e8a277b57dd97849a9f1862"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "913d1bb4ac0fc59763cf5d27bc637f6a713b2050c4463748db554af4be451538"
},
{
"path": "resources/js/lib/financial-fiscal-bridge.ts",
"sha256_LF": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33"
}
],
"originals": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf",
"sha256": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b"
},
{
"path": "docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
"sha256": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf",
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf",
"sha256": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf",
"sha256": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf",
"sha256": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf",
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf",
"sha256": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
"sha256": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d"
},
{
"path": "docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf",
"sha256": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
}
],
"new_source_files": 0,
"source_review": "Existing accepted sources only. Visually read Lei34/2007 PDF6/p768(60),PDF7/p768(61):17/18/20/22;Lei20/2009 official AT archived exemplar PDF2/3,p272(14/15):18/20/21/22/24;remaining accepted amendment chain reused. New nonzero variations/other corrections not activated. Official webdav page inaccessible via web tool;archived official exact exemplar used,not secondary reconstruction. No L5 rate/CER search.",
"proof_sha256": {
"api.txt": "13961d8421e329123ae99e4202e182ef1089de5c5e7d28b503d3b15797eab1b2",
"build-exit.txt": "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9",
"build.txt": "8272c7eb2f6058ddf64925103d5cc9ac9e4707c0a518c7073ecf04c690fb58e0",
"calculated.json": "105857393035cb5e7c569dc9e6c7b91f51c335b9799fc148b1bfee57057f3138",
"dossier-calculated.json": "addc82429306cac3ff0d25899f0cad48ec3756e0a8cbfbc0ec8c34507e9ca346",
"dossier-missing.json": "b790abf0a99ef2e13091c5f63d2f697b3424133d676e97570a6b4d2196bf11e8",
"download.html": "14935a24e370cd2378eac64264734591981c40e25c7beffbc15a9d82646c7c32",
"frontend.txt": "ca819072c4ee39ff25d70f1d2ef4c374f7e0e4565ed59d26dd63f08c9e375bfc",
"index.html": "9af7b69c19ca2fb213988ace8eb927008cb0bea73e267f16dee363fcdbcb0f12",
"Lei-20-2009-BR36-AT-exemplar19.pdf-page2.png": "e39eadef731b6c3ae8cb4820238c4db3184111557d982a20dadee139ea2952a2",
"Lei-20-2009-BR36-AT-exemplar19.pdf-page3.png": "a4a39a81849f32e4c596ef7c0726d2054e74bf45531dd8e920d3927cafdb70bd",
"Lei-34-2007-BR52.pdf-page6.png": "de2c1cc9c8bf5b0cefa9671cc8ad776e21a8492b791648be492d1540d78f748f",
"Lei-34-2007-BR52.pdf-page7.png": "7a934a93b77131bac30455309228232dc15c6ccd614893d6a0497f692d7970c4",
"missing.json": "7ca5bf593230bd973b1098d8e82866f5c6e0d534c5aa0f0d794e23ffc77ce7b4",
"preparation.html": "9a07ab3a4e7fbce036f9337c60cb1bafd385395070c38af57a9becffda852df6",
"recovered-calculated.html": "9a07ab3a4e7fbce036f9337c60cb1bafd385395070c38af57a9becffda852df6",
"recovered-calculated.json": "36afb1c036d7470282df6e083456da4c0be1991660a5944e784d6ae24a116e5b",
"recovered-missing.html": "8167c25ec05f66b9a26f53d185ee7bbc64ae6ed4dc4812e4fff010b0e966eacf",
"recovered-missing.json": "e7727a76405c2ac848c90379543e88a36d6be2ee734a2565245c5ad4e4cb6bf3",
"types.txt": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"ui-missing.png": "aa07cc3b77c7a3a12944f1790a492ed96a3796ee3a21ea1d0fd757e7f0832996",
"ui-profit.png": "f4359bd9719bea78587c7024abc1e72d4fbc02ea392ffed92402f7e9649b3ee8",
"ui-proof.json": "015fd14e35d12a27c02640712222beedc00773f6b55e8a9aa94826ff120ed2f6",
"ui.txt": "7bb7fc5145f1226fd948164fadf9f2f6a4e9efb1f070e90530b93aea4fdd13d7"
},
"prepared_joint_delivery": "Includes664c88c8 plus this delta,base7a11c4ef;Git bundle/manifest to be verified after commit. No push or installation;fresh destination/backup/restore remain installation steps.",
"active_changes": false,
"schema_API_config_permissions_dependencies_delta": false,
"L5_operational_demonstrated_scope": true,
"L5_complete": false,
"L6_complete": false,
"L5_AT_questions": "Ten questions J1-J5/C1-C5 unchanged;only dependent cases limited"
}
@@ -0,0 +1,535 @@
{
"status": "installed_scoped_MRFTA_documented_interest_delta_verified",
"candidate_installed": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"previous_installed": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"authorization": "Tempo:concluir entrega5fa64bc0 peloGit,backup/restauro fresco e delta;preservarce746d88,L3,ISPC,câmbio;seguir em QA apenas juros automáticos eCER/rubricas;L5parcial.",
"fresh_backup": {
"stage": "/var/backups/investmoz-irpc-mrfta-delivery-20261025/backup",
"created_at": "2026-10-25T18:28:38Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "4721dc593969b542c9cdbd3633e9a71bbd21b2e7a6ecfa2d4c180147a322d841",
"files_sha256": "51ba4c5d214b25bae9123489f9a432289fb41ef118142900e4048b22d5cec9d9",
"restore_verified": false
},
"isolated_restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l5_restore_20261025",
"port": 55441,
"source_dump_sha256": "4721dc593969b542c9cdbd3633e9a71bbd21b2e7a6ecfa2d4c180147a322d841",
"active_database_writes": 0
},
"preflight": {
"free_bytes": 5446705152,
"existing_pipeline_minimum_bytes": 5368709120,
"space_guard_satisfied": true,
"installed": {
"status": "installed",
"commit": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"release": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"previous_release": "/var/www/investmoz-homologacao/releases/2b33a1c343d192f80fb24aac2a27b2d375af5601-23fd8416",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"release_revision": {
"commit": "ce746d889d5711f23f4e0ac8d9802997b5e106f9",
"branch": "main",
"built_at": "2026-10-25T18:06:03.871601+00:00",
"manifest_sha256": "feb2dce3fc8845c6307c982323b3e3523b333a018189c47488f9fcba25490555"
},
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"configuration_keys": [
"repository",
"branch",
"target_url",
"legacy_root",
"state_root",
"release_root",
"current_link",
"shared_assets",
"php",
"schema_contract",
"ci_environment",
"postgis_image",
"test_database",
"qa_port",
"retention",
"webhook_secret_file"
],
"safe_paths": {
"repository": "nala/Investidor-V2",
"release_root": "/var/www/investmoz-homologacao/releases",
"postgis_image": "postgis/postgis@sha256:01a6a70e41e6c4467c8f55f6063555ed72db2d6662cd0d571040d42eadaeb6f6"
},
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
},
"protected_delta": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"installed": {
"status": "installed",
"commit": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"release": "/var/www/investmoz-homologacao/releases/5fa64bc0f4b067e81d8728b344eb8697415ebedf-b08a592f",
"previous_release": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 4,
"preserved_L3_ISPC_FX_runtime_files_verified": 29,
"documentary_files_verified": 30,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "e0ffe70896abb7ef550be154a6c755c6"
},
"after": {
"rows": 106,
"checksum": "ac75911294e9f6e3aeae2665d0d212b2"
}
},
"sessions": {
"before": {
"rows": 18,
"checksum": "0b7305e61724007da03a5cfd786f14d0"
},
"after": {
"rows": 19,
"checksum": "069206643d7e4e1f788a65e9c9fd3cd3"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"schema_permissions": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "dbb99b7e17f5b4b9bb7a8bdf9350d9b2ae368aaa4bc44593a2522d87617d8461",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "c1c7bc86ef3255c103a0be6aeb651b824eb07259e993cc5daf3665c1a6afff2d",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 18,
"after_rows": 21,
"changes": [
{
"key_sha256": "78207abc124e12f093844b879b74b5688a9d83d5816a3dde5ef08a77817039dc",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "163d86a1d136564be2cd032d5f0232442e89cebba612f73b789e0da0fa932290",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "03d1ab44d145b80341139dacf4a8a1f6d9d9b2689880049244ba20926cdab2dd",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public_delta": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"branch": "main",
"built_at": "2026-10-25T18:33:01.349237+00:00",
"manifest_sha256": "d1fd6fad9c48cf8c1feedcefbedae5a9b5471f0710894422ff9ae1a1633368a4"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Preparar e guardar MRFTA": [
"assets/services-Cp_vtFz7.js"
],
"Transcrever liquidação documentada de juros compensatórios": [
"assets/services-Cp_vtFz7.js"
],
"Não são juros calculados pelo portal.": [
"assets/project-dossier-DldGGCX7.js"
],
"CER numérico e referência aplicável por identificar;sem código presumido.": [
"assets/project-dossier-DldGGCX7.js"
],
"Dispensa de retenção": [
"assets/services-Cp_vtFz7.js",
"assets/project-dossier-DldGGCX7.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-Cp_vtFz7.js"
],
"Calcular e guardar restituição E": [
"assets/services-Cp_vtFz7.js"
],
"Reutilizar selecção cambial": [
"assets/services-Cp_vtFz7.js"
]
},
"assets": [
{
"file": "assets/services-Cp_vtFz7.js",
"status": 200,
"sha256": "a7868d6f94fa6ead018f44d0df3900e827bdf2e9ea8cd1ee8db6d55de0db5ca9"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-DldGGCX7.js",
"status": 200,
"sha256": "48e31ad3e2de0d0182b5f1abdea98b9db1283a20667e63c7cd910327e923ae4c"
},
{
"file": "assets/project-dossier-document-BUtxzH85.js",
"status": 200,
"sha256": "d3b7d7907a2fdf6bce247ed43a115d9d3c104882331d41e8975a894c49ccfb23"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-CfQbzHq7.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"runtime_delta": [
{
"path": "resources/js/lib/irpc-mrfta.ts",
"sha256_LF": "1ff1725724dbdaaa9a3857941d03e312c6a7da573d369ee86015edc90cd2d0d1"
},
{
"path": "resources/js/lib/irpc-withholdings.ts",
"sha256_LF": "8e5f3c035ce5e4d6c3fc82f933439ab580fa5519492f9c4d32cfb71b77b54803"
},
{
"path": "resources/js/components/simulation-irpc-mrfta.tsx",
"sha256_LF": "9cf7d5e447e1a9ed37d1bd24b4ac5104b1adec3790ff8db4356c3b68b339d89a"
},
{
"path": "resources/js/components/simulation-irpc-withholdings.tsx",
"sha256_LF": "751af4fab346659bc5ccb08b8a2169769af7521ea0035050af32b41ea7f5aa76"
}
],
"preserved_runtime": [
{
"path": "resources/js/components/acquisition-beverage-restitution.tsx",
"sha256": "6f44897b8b12569314551df0022c26da57a165634087942a724293e66837558d"
},
{
"path": "resources/js/components/fiscal-calculation-gaps.tsx",
"sha256": "1dab6ceb73756d4e023096b3b2ba767aaa843ff6cc69046ea630ab449a00b0dd"
},
{
"path": "resources/js/components/fiscal-l3-preparation.tsx",
"sha256": "e84a7b1ccadaa1b5bd78d778a3287f96ccaf530855eef404786cd7aa3d321b73"
},
{
"path": "resources/js/components/simulation-acquisitions.tsx",
"sha256": "c206d4cfe575d6ba007aa2b425b5f898efa97e4162b8710e358b6ecfd9458542"
},
{
"path": "resources/js/components/simulation-operations.tsx",
"sha256": "a7e55972fa790063dcf11945055de2af46a77db9e509900af22ede7ec47bb4cf"
},
{
"path": "resources/js/lib/iva-acquisition-bc.ts",
"sha256": "b0ef55e0917bdb79f14b53ba9e95d73c08153befeb7d4ce73f81e6fb13992225"
},
{
"path": "resources/js/lib/iva-beverage-allocation.ts",
"sha256": "32968d198c7fe0c53ca89641c22d5749be6636be2c79127b867e4e3afd0dd40d"
},
{
"path": "resources/js/lib/iva-beverage-restitution.ts",
"sha256": "5c650cbd9469d5f99001f56fc4ff99ac973eb368036d4e96c6d171f1b220bd9e"
},
{
"path": "resources/js/lib/iva-calculation-gaps.ts",
"sha256": "2e7d84a0c196bd5b56fd67cc1a389d43d5041894184e675680a4de3cd10b31a2"
},
{
"path": "resources/js/lib/iva-operations.ts",
"sha256": "ec37b949f1233c5f5c14a87450c421ed29fabf1ed5b73fb32564564a2bc31f54"
},
{
"path": "resources/js/lib/l3-form-preparation.ts",
"sha256": "fc47f5fa5ec1420fbd847d0d081f00d99ebbb524164eef785b20877e0562f704"
},
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/lib/iva-acquisitions.ts",
"sha256": "cce283b1d0a07fb383fcb527225f4dd5bec829010a662cbaae1d60e595221977"
},
{
"path": "resources/js/lib/iva-modelo-a.ts",
"sha256": "c641619a05613c1620385baad0e9ffbf810dd970aafb30e12b3a7f9a3bf11846"
},
{
"path": "resources/js/lib/iva-fx-selection.ts",
"sha256": "9aa07ad443bc777b80510a3b5bd6aff9ddb9814d2450f3c690e531e74d71d998"
},
{
"path": "resources/js/components/simulation-fx-selection.tsx",
"sha256": "39bb6d87d404745b0b66349bc11626545a3672ae27321ce9b4658416592059bf"
},
{
"path": "resources/js/lib/business-financial-plan.ts",
"sha256": "c20274722d1ffcd0360f041a6cacb5d868fe0621cb27a1aca6e06826612c3ebb"
},
{
"path": "resources/js/lib/iva-currency-events.ts",
"sha256": "cc9f2045d302d7987310da4006cc250fc5c99a27397918d166d649bfc32fab08"
},
{
"path": "resources/js/lib/irpc-fx.ts",
"sha256": "5c4a7a477429f8d775acf6db3e117008468f5554e5731dec81f60fbb75e948fb"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256": "01d20f4761933a3e4dd7c776bd4adcf9610ac0435d918a1998ae9f0c3ce3f234"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256": "df8b224b9472449711d0b69a873fa75f9cc9f4d84dce1a314fc576fae9c6eae2"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256": "4523365e2d4a2fcd014e13393deb33a5ec4b9396ff580d8a237aa8c4f02265e4"
}
],
"accepted_QA_proofs_reused": {
"frontend": "12 new tests+1 directed existing IRPC presentation test passed",
"types": "tsc --noEmit exit0",
"build": "complete QA build exit0",
"private_api": "1test/14assertions;DatabaseTransactions rollback;127.0.0.1:55441/simulator_fiscal_delta_20261021_test",
"dossier": "generated from actual private API recovered model",
"UI": {
"calculation": true,
"localSaveRecovery": true,
"privateApiProof": "IrpcMrftaDraftTest, separate",
"report": true,
"documentedInterest": true,
"insufficientInformation": true,
"download": true,
"errors": []
},
"CER_example": "999 is explicitly fictional QA data,not an official recipe-code mapping",
"unchanged_proofs": "AcceptedL3/ISPC/FX and ce746d88 calculation proofs reused;no manual repeat suites"
},
"installer_report": {
"status": "installed",
"commit": "5fa64bc0f4b067e81d8728b344eb8697415ebedf",
"release": "/var/www/investmoz-homologacao/releases/5fa64bc0f4b067e81d8728b344eb8697415ebedf-b08a592f",
"previous_release": "/var/www/investmoz-homologacao/releases/ce746d889d5711f23f4e0ac8d9802997b5e106f9-5fdb1b51",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"5fa64bc0f4b067e81d8728b344eb8697415ebedf"
],
"finished_at": "2026-10-25T18:33:04.381640+00:00"
},
"remaining_only_two_points": {
"juros": {
"entregue": "Transcrição de liquidação de juros compensatórios, com montante/data/período/documento; ou ausência de atraso demonstrada por entrega integral e prazo documentado. Nenhuma taxa aplicada pelo motor para calcular juros.",
"resta": [
"Corresponder fonte, parâmetro/taxa e versão temporal aplicáveis ao cálculo automático dos juros da retenção; a referência MAIBOR12meses+2p.p. e a descontinuidade documentada não autorizam escolher MIMO/Prime como substituto.",
"Delimitar, na mesma operação, início/fim da contagem, natureza por conta/definitiva, base em dívida após entregas parciais, regra diária e arredondamento; distinguir compensatórios e mora sem cumulação presumida.",
"Implementar apenas os casos com regra completa e provar o novo delta: atraso com entrega integral/parcial, mudança de parâmetro se aplicável e dados/taxa ausentes. Reutilizar transcrição, persistência e relatórios já demonstrados."
],
"condicao_de_fecho": "Cálculo reproduzível do caso suportado com fonte/versão, principal, taxa, dias e juros discriminados; sem parâmetro aplicável, juros continuam indeterminados e o principal mantém-se disponível.",
"nao_reabrir": [
"Registo de juros documentados",
"Conferência de entrega integral no prazo documentado",
"Gravação/recuperação/histórico/relatório já demonstrados"
]
},
"cer_rubricas": {
"entregue": "Rubricas correntes correspondidas pelo rendimento e natureza; CER transcrito com referência. Ausência de CER, rubrica desconhecida e mistura de taxas/CER ficam pendentes. CER999 é exclusivamente fictício de QA.",
"resta": [
"Corresponder códigos CER a rubrica, natureza, rendimento e período com o catálogo/modelo/procedimento oficial aplicável; os números dos campos da guia antiga não são códigos CER por inferência.",
"Resolver apenas as rubricas ainda pendentes: digital/moeda electrónica, categorias especiais e outros rendimentos sem correspondência actual, incluindo casos por conta que não cabem nas rubricas já mapeadas.",
"Corresponder o tratamento de taxas/CER diferentes na mesma rubrica: conservar parcelas e documentos; não fundir taxas, calcular taxa média ou criar declarações/anexos por presunção.",
"Acrescentar casos dirigidos para cada nova correspondência e para código ausente, período incompatível ou rubrica desconhecida, mantendo casos independentes e cálculos anteriores."
],
"condicao_de_fecho": "Cada novo caso liga rendimento/natureza/período ao CER e à rubrica com referência verificável e apresentação correcta; o catálogo parcial nunca implica cobertura integral.",
"nao_reabrir": [
"Preparação de um mês/ano",
"Bases/taxas/imposto/entregas provenientes do cálculo guardado",
"Separação de dispensas, retenções sofridas e outros períodos",
"Exportação HTML e dossier demonstrados"
]
}
},
"database_migrations": 0,
"content_imports": 0,
"L5_integrally_completed": false,
"scope": "Period preparation,documentedinterestrecord andMRFTA reports only;notautomaticinterestnorcompleteCERmapping. Nexttwo-pointincrement staysQA.",
"evidence": {
"backup.txt": "151cbb1c3c4954da4679a9a2e54ba636afbd2e5c4b228f68ad4c236ae30663eb",
"installed-protected.txt": "32cff2aff1e1d7148af22820a8136267364efe3b4ede9cac3f7790f8f29bca5a",
"installed-public.txt": "82a8ae2b9113b83212f2b030abc537e1975d86b5597ed9385c67438f7d636549",
"integration.txt": "130dc00f5fafda21e09bfbfd1f934d630c03732127a60f21df69d075176950ae",
"operational-delta.txt": "e9c29d6e9691fb44f30eccc3041dfa3455905e6d5eb01410b8b898fcdf1f2f25",
"preflight.txt": "c87ceda50c49b392d55fd624bef9cc1f37cec9c1b888e4fded8c64d4b76ab60a",
"restore.txt": "d103daf999311fc6e6fd0a20f0b07162200ce5a14f1ad558f00be2fcb30d5943",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status1.txt": "f14354ab7188e19bf1188ec9ad9ed7d3834fac3996412cbda1d7436a418804fd",
"status2.txt": "a6fc5285be3f927ee0b1d882ae25f246d2026f0fe3b77d176e402ace6cf39b02",
"status3.txt": "193ef46c35707af20292cca967902aa265f90bfc1336189ea6e61b6dbb6cc9c9"
}
}
@@ -0,0 +1,397 @@
{
"status": "installed_scoped_habitual_quarterly_ISPC_and_delta_verified",
"authorization": "Tempo25/10:concluir instalação6af7092e peloGit combackup/restaurofresco,conferirdelta,preservarL3eprovasaceites;ISPCnãoéintegralmenteconcluído.",
"candidate_installed": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"previous_installed": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"prepared_receipt": "ispc-l4-prepared-delivery-20261025.json",
"authenticated_preflight": {
"free_bytes": 7635865600,
"existing_pipeline_minimum_bytes": 5368709120,
"space_guard_satisfied": true,
"installed": {
"status": "installed",
"commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"previous_release": "/var/www/investmoz-homologacao/releases/7ad187f9f0745245268e3ed5317547a96b4700f3-066618f1",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"release_revision": {
"commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"branch": "main",
"built_at": "2026-10-25T15:12:37.806036+00:00",
"manifest_sha256": "cddac25dc66b3e555f2380cf3a9d4b2da6501cd03927c183c832a05b0ee5c993"
},
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"configuration_keys": [
"repository",
"branch",
"target_url",
"legacy_root",
"state_root",
"release_root",
"current_link",
"shared_assets",
"php",
"schema_contract",
"ci_environment",
"postgis_image",
"test_database",
"qa_port",
"retention",
"webhook_secret_file"
],
"safe_paths": {
"repository": "nala/Investidor-V2",
"release_root": "/var/www/investmoz-homologacao/releases",
"postgis_image": "postgis/postgis@sha256:01a6a70e41e6c4467c8f55f6063555ed72db2d6662cd0d571040d42eadaeb6f6"
},
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
},
"fresh_backup": {
"stage": "/var/backups/investmoz-ispc-l4-delivery-20261025/backup",
"created_at": "2026-10-25T15:25:16Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "77ba24736ff574d9273845359db90d1a032ff0f39d7f9195efaeff842d5b5857",
"files_sha256": "59917d3f0420dc8ede0562da70ae5f67877aa99f77313950f9e1d840b7505e3b",
"restore_verified": false
},
"isolated_restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "ispc_l4_restore_20261025",
"port": 55441,
"source_dump_sha256": "77ba24736ff574d9273845359db90d1a032ff0f39d7f9195efaeff842d5b5857",
"active_database_writes": 0
},
"installed_protected_delta": {
"installed": {
"status": "installed",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"previous_release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 9,
"L3_unchanged_runtime_files_verified": 11,
"documentary_files_verified": 17,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "81ca74112a72e3638ad335678ebfd0ef"
},
"after": {
"rows": 106,
"checksum": "e799b80b260c8c23326c72a5d7c52881"
}
},
"sessions": {
"before": {
"rows": 156,
"checksum": "5b29e80e2877c2e0bf0c81e046230987"
},
"after": {
"rows": 157,
"checksum": "e83a47d5ba184b55f1680f52ff7e0993"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 156,
"after_rows": 159,
"changes": [
{
"key_sha256": "5045187d392f685b58ae0ce1749c84eb5a30c5ab441aa0e65cfc6d905d0180fa",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "3d45feddb6a0eafd7d40e3efe516866803e4432d922c6a6b6e839276d8461075",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "712b82ddcfb6f6af6a4ea5937ae2d5195976cf4c808e6202a4b234eef1560210",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"installed_public": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"branch": "main",
"built_at": "2026-10-25T15:29:39.962545+00:00",
"manifest_sha256": "0761702f0aa0f54dd4e7dac14efadf290830c52a5762a97733d82f5332fb44a8"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"ISPC — enquadramento e opção": [
"assets/services-tj9wihZS.js"
],
"ISPC — apuramento trimestral": [
"assets/services-tj9wihZS.js"
],
"ISPC — retenção em aquisições ocasionais": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-tj9wihZS.js"
],
"Conferir e guardar retenção ISPC": [
"assets/services-tj9wihZS.js"
],
"Repartição do IVA documental em MZN": [
"assets/services-tj9wihZS.js"
],
"Reconciliação da dedução anterior": [
"assets/services-tj9wihZS.js"
],
"Cálculos indeterminados e condições para resolver": [
"assets/services-tj9wihZS.js"
],
"Preparação dos quadros L3 e formalidades": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar restituição E": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar acompanhamento D": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar substituições C": [
"assets/services-tj9wihZS.js"
]
},
"assets": [
{
"file": "assets/project-dossier-document-DlW49dDv.js",
"status": 200,
"sha256": "7002e22485098102c9a49e6f637a8818a4ecb153cf58f9c9cfb377e1b8a3d5a0"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-B9kwzlsI.js",
"status": 200,
"sha256": "c2b62654e0a286c0dfb16a44f3aac513064c8db305cccc827388de35cc6c720f"
},
{
"file": "assets/services-tj9wihZS.js",
"status": 200,
"sha256": "9e88d806f7c8e7193dda407ba1efe8bf720e5eeb76ca40798f3e6c4914e57f4b"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-CkfkH6Xv.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"pipeline_status": {
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"installed": {
"status": "installed",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"previous_release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"database_migrations": 0,
"content_imports": 0
},
"latest_report": {
"status": "installed",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"previous_release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"6af7092e83b9b3932712aa7a9f527393fcec4da8"
],
"finished_at": "2026-10-25T15:29:42.957691+00:00"
},
"log_file": "1792941995601985924.log",
"summaries": [
"OK (1 test, 3106 assertions)",
"built in 31.63s",
"OK (59 tests, 317 assertions)",
"# tests 782",
"# pass 782",
"# fail 0"
],
"log_bytes": 227445
},
"archived_old_build_dependencies": {
"status": "dependencies_archived_and_verified",
"versions": 8,
"free_before": 5531414528,
"free_after": 7635984384,
"receipt": "/var/backups/investmoz-build-dependencies-ispc-l4-20261025/receipt.json",
"protected": [
"/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"/var/www/investmoz-homologacao/releases/7ad187f9f0745245268e3ed5317547a96b4700f3-066618f1"
],
"active_or_previous_release_modified": false,
"source_data_backups_deleted": 0
},
"accepted_QA_proofs_reused": {
"prior_proofs": "L4-A12testes eL1/L2/L3/P001não repetidos;inventário eaceitações reutilizados",
"new_frontend": "13distinctpassed:10quarter/3withholding;frontend-final.txt",
"private_API": "1test/21assertions passed;loopback55441/simulator_fiscal_delta_20261021_test,DatabaseTransactions rollback;otheraccount404;api.txt",
"UI": "Componentesreais:avaliar/opçãoguardada→calcular→guardarficheiroQA→recuperar→relatório;persistênciaprivadaconferidaemAPIseparadamente;ui-recovered-report.txt/png",
"report_fix": "GrupoISPCmapeadoàsecçãofinanceira;testeactualdoexportadorincluiimposto/opção;ausênciaidentificadanademonstraçãoecorrigidaantesdeconcluir.",
"types": "exit0;types-final.txt",
"build": "exit0;build-final.txt",
"inventory": "outputs/ispc-l4b-20261025/preservation-before-tests.json;reutiliza8143ficheirosinventariadoseL1fechados"
},
"manual_functional_tests_repeated": false,
"pipeline_checks": "Existing Git process mandatory checks only;no new discretionary functional round.",
"example": {
"context": "opportunity:375;SYNTHETIC QA",
"option": "documentada2026-01-01",
"quarter": "2026/T2",
"prior_turnover_MZN": "100000",
"quarter_base_MZN": "200000",
"rate_percent": 12,
"tax_MZN": "24000",
"payment_MZN": "24000",
"declaration": "mantida",
"other_fiscal_books": "exactamente preservados"
},
"remaining_L4_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
],
"L3": "Preserved;11runtimehashes,17originals and additive integrations verified. Specific residuals remain in existing matrix.",
"preserved_L3_amounts": {
"documentary_VAT_MZN": 16,
"deduction_this_route_MZN": 0,
"recognised_MZN": 12,
"received_MZN": 7,
"awaiting_receipt_MZN": 5
},
"residuals": "P001/P058awaitdefinedclarificationswithoutblocking;P084/P085closed;statistics/AIdeferred.",
"schema_migrations": 0,
"content_imports": 0,
"ISPC_integrally_completed": false,
"proof_hashes": {
"outputs/ispc-l4-delivery-20261025/preflight.txt": "985e4cabc9f4f80ee55f89aa9a20580c1bc3b691225241165b01cc66ba4b5d19",
"outputs/ispc-l4-delivery-20261025/backup.txt": "23f72466038eed5153c93408e5acd508b5c6a66fc0e4c3a9bd30a580367fe8ea",
"outputs/ispc-l4-delivery-20261025/restore.txt": "d0100e1378c2e0e8a4be61de640e0e331695721080bae16d8a7a708cf4d4eb83",
"outputs/ispc-l4-delivery-20261025/integration.txt": "d92b419bd0c57c7951d558039e1414acca4ec2abc47e5a9d2f2389b1401adf7c",
"outputs/ispc-l4-delivery-20261025/status-final.txt": "638710d6205b634b8ab8f8cf625ee308fb76c4fe7c21608130d2b79afba60e0c",
"outputs/ispc-l4-delivery-20261025/installed-protected.txt": "83231f0b6619828618188e7abb9337f6b5e92e4192f7e5a8bbf165f7d2b70a44",
"outputs/ispc-l4-delivery-20261025/installed-public-delta.json": "7b944512bd87b5fa99e83e554247f1567c5629481b2dcdf668b411f118849aa2",
"outputs/ispc-l4-delivery-20261025/operational-delta.txt": "e79fc1267ac6f06e0f2fe78a9ed00eb0cfc05b1ec1ab7bec92c61268e4acbd93",
"outputs/ispc-l4-delivery-20261025/compact-dependencies.txt": "236ebb16564acf706dd434186b20013b9c035dd201f5f728ebcaf1e3813e2053"
}
}
@@ -0,0 +1,285 @@
{
"status": "prepared_for_Git_delivery_not_installed",
"authorization": "Tempo25/10:preparar entrega do âmbito L4 trimestral habitual demonstrado em6af7092e;conferir apenas delta,preservarL3;sem declararL4integralmenteconcluído.",
"installed_baseline": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"candidate": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"branch": "codex/ispc-l4-quarterly-qa-20261025",
"changes": [
"docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json",
"docs/investmoz/simulations/ispc-l4-quarterly-qa-20261025.json",
"docs/investmoz/simulations/ispc-l4a-eligibility-qa-20261025.json",
"docs/investmoz/simulations/l3-additional-delivery-20261025.json",
"docs/investmoz/simulations/l3-e-additional-coverage-qa-20261025.json",
"docs/investmoz/unification/traceability-and-manual.md",
"docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
"resources/js/components/simulation-form.tsx",
"resources/js/components/simulation-ispc-eligibility.tsx",
"resources/js/components/simulation-ispc-quarter.tsx",
"resources/js/components/simulation-ispc-withholding.tsx",
"resources/js/lib/ispc-eligibility.ts",
"resources/js/lib/ispc-quarter.ts",
"resources/js/lib/ispc-withholding.ts",
"resources/js/lib/project-dossier-report.ts",
"resources/js/lib/project-dossier.ts",
"tests/Feature/IspcQuarterDraftTest.php",
"tests/frontend/fixtures/ispc-quarter-preserved.json",
"tests/frontend/ispc-eligibility.test.mjs",
"tests/frontend/ispc-quarter.test.mjs",
"tests/frontend/ispc-withholding.test.mjs"
],
"runtime_delta": [
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "606e6e29f92323450433e8411b2064ba5f55b795a3376794ad1eb30729841c3c"
},
{
"path": "resources/js/components/simulation-ispc-eligibility.tsx",
"sha256_LF": "f48dd4a8f87a994eda0447f81a463589905e5873b2e1044debac9d10825a880c"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "0b950091e9204b2b20823694ea16dc94e4863914080542253966367a5580d62d"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e688a8d6a2e1e20c1e10a85d33152d58a5c14867672cf4ffb834980ec1732f08"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "d8c3ab8b2687af905d3048db192b690fa6d49ab693ff58f2e8f57f76dfb4a1fb"
},
{
"path": "resources/js/lib/ispc-quarter.ts",
"sha256_LF": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129"
},
{
"path": "resources/js/lib/ispc-withholding.ts",
"sha256_LF": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a24e0484f558580c14c4a261de66db8d245ffccf9c6fe17b6d639e9e2cbbe3c2"
},
{
"path": "resources/js/lib/project-dossier-report.ts",
"sha256_LF": "0db9f5fcb2929fd8340894bd13b74ee7c400af25e483ddfe5651002fd7160f49"
}
],
"existing_integrations_additions_only": {
"resources/js/components/simulation-form.tsx": 6,
"resources/js/lib/project-dossier.ts": 6,
"resources/js/lib/project-dossier-report.ts": 1
},
"L3_runtime_preserved_unchanged": [
"resources/js/components/acquisition-beverage-restitution.tsx",
"resources/js/components/fiscal-calculation-gaps.tsx",
"resources/js/components/fiscal-l3-preparation.tsx",
"resources/js/components/simulation-acquisitions.tsx",
"resources/js/components/simulation-operations.tsx",
"resources/js/lib/iva-acquisition-bc.ts",
"resources/js/lib/iva-beverage-allocation.ts",
"resources/js/lib/iva-beverage-restitution.ts",
"resources/js/lib/iva-calculation-gaps.ts",
"resources/js/lib/iva-operations.ts",
"resources/js/lib/l3-form-preparation.ts"
],
"L3_documentary_originals_preserved": 17,
"documentary_delta": [
{
"path": "docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf",
"sha256": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf",
"sha256": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5"
},
{
"path": "docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf",
"sha256": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf",
"sha256": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf",
"sha256": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf",
"sha256": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf",
"sha256": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be"
},
{
"path": "docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf",
"sha256": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf",
"sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf",
"sha256": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf",
"sha256": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf",
"sha256": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf",
"sha256": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf",
"sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf",
"sha256": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf",
"sha256": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d"
}
],
"schema_runtime_PHP_configuration_dependencies_delta": false,
"P001_experimental_changes_excluded": true,
"accepted_QA_proofs_reused": {
"prior_proofs": "L4-A12testes eL1/L2/L3/P001não repetidos;inventário eaceitações reutilizados",
"new_frontend": "13distinctpassed:10quarter/3withholding;frontend-final.txt",
"private_API": "1test/21assertions passed;loopback55441/simulator_fiscal_delta_20261021_test,DatabaseTransactions rollback;otheraccount404;api.txt",
"UI": "Componentesreais:avaliar/opçãoguardada→calcular→guardarficheiroQA→recuperar→relatório;persistênciaprivadaconferidaemAPIseparadamente;ui-recovered-report.txt/png",
"report_fix": "GrupoISPCmapeadoàsecçãofinanceira;testeactualdoexportadorincluiimposto/opção;ausênciaidentificadanademonstraçãoecorrigidaantesdeconcluir.",
"types": "exit0;types-final.txt",
"build": "exit0;build-final.txt",
"inventory": "outputs/ispc-l4b-20261025/preservation-before-tests.json;reutiliza8143ficheirosinventariadoseL1fechados"
},
"accepted_proof_hashes_verified": {
"outputs/ispc-l4b-20261025/frontend-final.txt": "2b0ec25bb83505ec9ce8ace02e0860faeeac4ce233083859f9a502069944f49f",
"outputs/ispc-l4b-20261025/api.txt": "2a770d07561a1475973795d5bac01ce5d94ee8a91be1d57d9b0702c621b8284d",
"outputs/ispc-l4b-20261025/ui-recovered-report.txt": "234bae0f17ef84dd9928197bfa38ad4a8a05c2dae18051e1ea9bd88852bb84fa",
"outputs/ispc-l4b-20261025/build-final.txt": "9683e783fd6e457c89a747d4a1a6deb10ba00a034f7891cf69e4c1a0cb1f0073",
"outputs/ispc-l4b-20261025/types-final.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"tests/frontend/fixtures/ispc-quarter-preserved.json": "30266584de9cacb0e4d771a9cc9c38838b62a3472583792e13effcd094247c39"
},
"compatible_build_and_types": "Already passed on identical runtime hashes;proofs reused,no rerun.",
"compiled_markers": {
"ISPC — enquadramento e opção": [
"assets/services-tj9wihZS.js"
],
"ISPC — apuramento trimestral": [
"assets/services-tj9wihZS.js"
],
"ISPC — retenção em aquisições ocasionais": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-tj9wihZS.js"
],
"Conferir e guardar retenção ISPC": [
"assets/services-tj9wihZS.js"
],
"Repartição do IVA documental em MZN": [
"assets/services-tj9wihZS.js"
],
"Reconciliação da dedução anterior": [
"assets/services-tj9wihZS.js"
],
"Cálculos indeterminados e condições para resolver": [
"assets/services-tj9wihZS.js"
],
"Preparação dos quadros L3 e formalidades": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar restituição E": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar acompanhamento D": [
"assets/services-tj9wihZS.js"
],
"Calcular e guardar substituições C": [
"assets/services-tj9wihZS.js"
]
},
"public_baseline_readonly": {
"commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"branch": "main",
"built_at": "2026-10-25T15:12:37.806036+00:00",
"manifest_sha256": "cddac25dc66b3e555f2380cf3a9d4b2da6501cd03927c183c832a05b0ee5c993"
},
"examples": {
"context": "opportunity:375;SYNTHETIC QA",
"option": "documentada2026-01-01",
"quarter": "2026/T2",
"prior_turnover_MZN": "100000",
"quarter_base_MZN": "200000",
"rate_percent": 12,
"tax_MZN": "24000",
"payment_MZN": "24000",
"declaration": "mantida",
"other_fiscal_books": "exactamente preservados"
},
"remaining_L4_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
],
"preserved_amounts_L3": {
"documentary_VAT_MZN": 16,
"deduction_this_route_MZN": 0,
"recognised_MZN": 12,
"received_MZN": 7,
"awaiting_receipt_MZN": 5
},
"residuals": "P001/P058awaitdefinedclarificationswithoutblocking;P084/P085closed;L3residualsremaininexistingmatrix;statistics/AIdeferred.",
"execution_remaining": [
"Fresh authenticated destination/schema/data/configuration/permissions and disk comparison.",
"Fresh backup and verified isolated restore,without modifying active database.",
"Fast-forward integration via existing Git process only after guards pass;verify servedrevision,manifest,compiled L4/L3 markers and protected delta with equivalent identities/context."
],
"backup_restore": "Not executed in preparation;prior L3 receipt preserved,not represented as fresh L4 backup.",
"main_changed": false,
"active_changes": false,
"Git_preparation": {
"feature_ref": "refs/heads/codex/ispc-l4-quarterly-qa-20261025",
"remote_verified": {
"refs/heads/codex/ispc-l4-quarterly-qa-20261025": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"refs/heads/main": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6"
},
"bundle": "outputs/ispc-l4-delivery-20261025/candidate.bundle",
"bundle_sha256": "2d1b690ffbca0cdcc2365d2f5c8cf9f4d34a3e64f9cb5bd4fa2ce23835143c4d",
"bundle_verified": true,
"main_pushed": false
},
"execution_scripts": {
"outputs/ispc-l4-delivery-20261025/backup.py": "f82ee71b83527e2e3b431f88aa24deb0433308f4c15a2873779068a21785c99d",
"outputs/ispc-l4-delivery-20261025/bridge.py": "b12bb51e68c0c3270ac9d127d20aaf69c04745837fb06788e9e1d37a623e3487",
"outputs/ispc-l4-delivery-20261025/installer-status.py": "47cf71d02bbbac76bdf8edf87ab9b69b88d6c610d4b1755e1da69060af8b02cf",
"outputs/ispc-l4-delivery-20261025/integrate-after-guards.py": "b2146ae221af4fa5f26f3a16ba7de22eb3d35fed2ff9b606f49065b0a9524171",
"outputs/ispc-l4-delivery-20261025/preflight.py": "d22ae1370f261cce91201830f39833d03019df5110be8aa5a9eccdfd639de55c",
"outputs/ispc-l4-delivery-20261025/reconcile-operational-delta.py": "d2e2ab7093594ab667b03f76ef7620120d7fd580e22edeb335b3c5c208493cd0",
"outputs/ispc-l4-delivery-20261025/restore.py": "51c03e0e590f3ad8d795334e67140f6de7c594fe52fb5ee9098b2da8bc508a3b",
"outputs/ispc-l4-delivery-20261025/verify-protected.py": "5acdb275e6bd5de5237000f8a8a27234f9d00be4bf1cd1cf71ecf24bc0a7f415",
"outputs/ispc-l4-delivery-20261025/verify-public.py": "e31052548421a2095d23435a716c34086542992fda3ede04f6ae3cd1d24f291b"
},
"execution_script_checks": "Python syntax checked;not executed against active target. Authenticated baseline,fresh backup/isolatedrestore andtimestamp guards prepared;disk comparison pending at execution.",
"guard_origins": {
"base_and_scope": "DecisãoTempo:preservarL3fa32 eentregar apenas âmbitoQA6af.",
"disk_5_GiB": "Requisito técnico do processo de entrega já existente;conferido no código emexecuçãoL3,sem criar regra organizacional.",
"backup_freshness_30_minutes": "Escolha técnica do script de integração;expiração exige actualizar preflight/backup-restauro,sem nova aprovação organizacional."
},
"superseded_by": "ispc-l4-delivery-20261025.json",
"installation_followup": "6af7092e83b9b3932712aa7a9f527393fcec4da8"
}
@@ -0,0 +1,102 @@
{
"status": "installed_scoped_habitual_quarterly_ISPC",
"matrix_anchor": "AUD-SIM-INT02",
"scope": "Actividade habitual ISPC2026/MZN, enquadramento/opção, cálculo trimestral e retenção12(3–4) delimitada. Não é encerramento de operações ocasionais próprias ou formalidades sem correspondência de modelo.",
"source": {
"file": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"citation": "Lei9/2025,republicaçãoISPC,arts8–12;PDF11/p2180(11),enquadramento2–5PDF10",
"application": "8(1)a selecciona taxa3/4/5 pelo volume anual2026 declarado e9 aplica-a à base trimestral; não repartir limites anuais por4 nem copiar acesso2025. Serviços12/15; cumulação usa taxa maior8(2).20%somenteparcela acima limite anual4.000.000 com acumulado anterior; cálculos racionais exactos."
},
"new_implementation": [
"Livro trimestral por contexto; receitas de cada trimestre e suporte explícitos,volume global do sujeito passivo confirmado; previsão anual distinta de ano encerrado reconciliado.",
"Elegibilidade actual e opção documentada reutilizadas; preparação apenas simula; opção posterior ao trimestre não retroage automaticamente.",
"Imposto/prestação/obrigação declarativa separados; inferior500 dispensa pagamento, não declaração;igual500 mantém pagamento. Não acumular dispensas nem deduzir custos/IVA.",
"Retenção5%separada para aquisições ocasionais a pessoa singular não inscrita3(3–4),ligadasàactividade,limiteglobalanual2.500.000;acima limiteindeterminado,semtruncar. Sem crédito contraimpostopróprio,mínimo500não aplicadoàretenção.",
"Gravação/recuperação mantém outros livros e históricos;alterações conservam resultado congelado até nova versão;relatório financeiro inclui grupoISPC."
],
"verification": {
"prior_proofs": "L4-A12testes eL1/L2/L3/P001não repetidos;inventário eaceitações reutilizados",
"new_frontend": "13distinctpassed:10quarter/3withholding;frontend-final.txt",
"private_API": "1test/21assertions passed;loopback55441/simulator_fiscal_delta_20261021_test,DatabaseTransactions rollback;otheraccount404;api.txt",
"UI": "Componentesreais:avaliar/opçãoguardada→calcular→guardarficheiroQA→recuperar→relatório;persistênciaprivadaconferidaemAPIseparadamente;ui-recovered-report.txt/png",
"report_fix": "GrupoISPCmapeadoàsecçãofinanceira;testeactualdoexportadorincluiimposto/opção;ausênciaidentificadanademonstraçãoecorrigidaantesdeconcluir.",
"types": "exit0;types-final.txt",
"build": "exit0;build-final.txt",
"inventory": "outputs/ispc-l4b-20261025/preservation-before-tests.json;reutiliza8143ficheirosinventariadoseL1fechados"
},
"example": {
"context": "opportunity:375;SYNTHETIC QA",
"option": "documentada2026-01-01",
"quarter": "2026/T2",
"prior_turnover_MZN": "100000",
"quarter_base_MZN": "200000",
"rate_percent": 12,
"tax_MZN": "24000",
"payment_MZN": "24000",
"declaration": "mantida",
"other_fiscal_books": "exactamente preservados"
},
"remaining_specific": [
"Operações ocasionais próprias3(3–4)enquanto sujeito passivo,distintas da retenção do adquirente;mantidas indeterminadas no percurso específico.",
"Aquisições acima limiteglobal2.500.000:correspondência do tratamento próprio;nãoliquidar5%porpresunção.",
"Formulário/modelo,instruções eprocedimentos da regulamentação2026;relatório depreparação não édeclaraçãosubmetida. Aviso primário do Governo confirma aprovação de novo regulamento,mas não contém articulado/modelos: https://portaldogoverno.gov.mz/governo-introduz-alteracoes-nos-regulamentos-fiscais-para-reforcar-eficiencia-tributaria/ . Sem impor segunda validação jurídica ou repetir pesquisa sem nova evidência."
],
"active_changes": false,
"schema_changes": false,
"rules_published_or_activated": 0,
"residuals": "P001/P058nãointerrompem;P084/P085fechados;L3residuaisapenasbloqueiamcasosdependentes;estatísticas/IAadiadas.",
"runtime_hashes": {
"resources/js/lib/ispc-quarter.ts": "f66bd52e9cdfe1ddaa6b00a931465862b3d890b9be216b7a056740f027f24129",
"resources/js/lib/ispc-withholding.ts": "6c31b240299edd3262efa28f7f3d5aee21123f94e30ef4ab90e26c35777cb6e4",
"resources/js/components/simulation-ispc-quarter.tsx": "0b950091e9204b2b20823694ea16dc94e4863914080542253966367a5580d62d",
"resources/js/components/simulation-ispc-withholding.tsx": "e688a8d6a2e1e20c1e10a85d33152d58a5c14867672cf4ffb834980ec1732f08",
"resources/js/lib/project-dossier-report.ts": "0db9f5fcb2929fd8340894bd13b74ee7c400af25e483ddfe5651002fd7160f49"
},
"proof_hashes": {
"outputs/ispc-l4b-20261025/frontend-final.txt": "2b0ec25bb83505ec9ce8ace02e0860faeeac4ce233083859f9a502069944f49f",
"outputs/ispc-l4b-20261025/api.txt": "2a770d07561a1475973795d5bac01ce5d94ee8a91be1d57d9b0702c621b8284d",
"outputs/ispc-l4b-20261025/ui-recovered-report.txt": "234bae0f17ef84dd9928197bfa38ad4a8a05c2dae18051e1ea9bd88852bb84fa",
"outputs/ispc-l4b-20261025/build-final.txt": "9683e783fd6e457c89a747d4a1a6deb10ba00a034f7891cf69e4c1a0cb1f0073",
"outputs/ispc-l4b-20261025/types-final.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"tests/frontend/fixtures/ispc-quarter-preserved.json": "30266584de9cacb0e4d771a9cc9c38838b62a3472583792e13effcd094247c39"
},
"compatible_QA_preparation": {
"branch": "codex/ispc-l4-quarterly-qa-20261025",
"path": "C:\\laragon\\www\\portal-investidor-ispc-qa-20261025",
"base": "fa32a2b9",
"runtime_files": [
"resources/js/components/simulation-form.tsx",
"resources/js/components/simulation-ispc-eligibility.tsx",
"resources/js/components/simulation-ispc-quarter.tsx",
"resources/js/components/simulation-ispc-withholding.tsx",
"resources/js/lib/ispc-eligibility.ts",
"resources/js/lib/ispc-quarter.ts",
"resources/js/lib/ispc-withholding.ts",
"resources/js/lib/project-dossier.ts",
"resources/js/lib/project-dossier-report.ts"
],
"runtime_hashes_match_accepted_QA": true,
"P001_runtime": "fa32a2b9 unchanged; experimental d1551dab runtime excluded",
"compatible_build": "exit0;outputs/ispc-l4b-20261025/compatible-build.txt",
"compatible_types": "exit0;outputs/ispc-l4b-20261025/compatible-types.txt",
"functional_proofs": "13frontend/API1-21/UIreport reused; no new functional round",
"installed": true,
"functional_source_commits": [
"479b6681",
"1b7ccfee"
],
"candidate_commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"functional_candidate_commit": "49b448eb47df9ded3f906996e36c1d5ebd855741",
"installed_at_preparation": false,
"installed_commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8"
},
"QA_status_before_delivery": "QA_demonstrated_eligibility_option_quarter_calculation_private_recovery_and_report_not_installed",
"installation_followup_20261025": {
"status": "installed_scoped_habitual_quarterly",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"receipt": "ispc-l4-delivery-20261025.json",
"QA_proofs": "preserved;no manual repetition",
"ISPC_integrally_completed": false
}
}
@@ -0,0 +1,50 @@
{
"status": "QA_partial_eligibility_and_separate_option_not_installed",
"matrix_anchor": "AUD-SIM-INT02",
"authorization": "Tempo25/10: preparar entrega compatível L3, reconciliar saldo e avançar L4 ISPC; P001 residual não bloqueia trabalho independente.",
"source": {
"path": "docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf",
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"law": "Lei9/2025, republicação ISPC; arts2–5,9-A/13; PDF10–11; vigência2026art6/PDF9",
"acceptance": "Fonte oficial aceite pela Tempo; sem segunda validação de proveniência ou aprovação genérica Fiscalista."
},
"scope": [
"Condições preliminares de acesso habitual em2026/MZN; pessoa,actividade nacional,volume anterior2025 ou previsão de início2026,contabilidade obrigatória e exclusões3(2).",
"Limite4.000.000 inclusivo; desconhecido permanece indeterminado e não vira zero; operação ocasional tem percurso próprio ainda não implementado.",
"Serviços liberais8(1)c:183dias versus184 à mesma entidade; não aplicar esta exclusão aos serviços8(1)b.",
"Opção separada de elegibilidade; seleccionarISPC não adopta regime nem alteraIVA/IRPS/IRPC.",
"Reutilização de perfil com diferenças e confirmação; nenhuma inferência de categoria,volume anual anterior ou opção a partir de vendas correntes.",
"Livro por contexto no snapshot existente; preserva mapas fiscais,histórico e resultados congelados; relatório do dossier inclui enquadramento e opção."
],
"verification": {
"inventory_before_tests": "outputs/ispc-l4a-20261025/preservation-before-tests.json",
"new_frontend_tests": 12,
"frontend_result": "12 passed/0failed; outputs/ispc-l4a-20261025/frontend.txt",
"types": "exit0;outputs/ispc-l4a-20261025/types.txt",
"build": "exit0;outputs/ispc-l4a-20261025/build.txt",
"persistence": "serialização/recuperação e preservação dos livros/históricos cobertas nos novos testes; transporte privado existente reutilizado,sem nova rondaAPI",
"UI": "componente integrado;sem demonstração visual nova nesta passagem",
"synthetic_fixture": "outputs/ispc-l4a-20261025/calculated.json; não importada no activo"
},
"remaining_L4": [
"Apuramento trimestral e aplicação dos escalões3/4/5%,serviços12%,liberal15%,excesso20% e actividades mistas8; identificar correspondência exacta anual/trimestral antes do cálculo.",
"Mínimo trimestral500 e obrigação declarativa; retenção5% nas aquisições ocasionais próprias,limite2.500.000 e modelo; sem reutilizar taxa deIVA.",
"Percurso ocasional3(3–4),formalidades,modelos e prazos do regulamento aplicável; conferir apenas correspondências concretas necessárias,sem nova validação genérica.",
"Demonstração visual integrada e gravação privada deste incremento antes de propor entregaL4."
],
"preserved": {
"L1": "131entregues;P001residual;P058parcial com exclusões",
"P084_P085": "fechados no âmbito operacional Tempo;sem pesquisa",
"L3": "candidata0f4df8a4 preparada,não instalada;saldo próprio não encerraL3",
"E_original": "16MZN documental/zero dedução nesta via/12 reconhecidos/7recebidos/5porreceber",
"statistics_AI": "adiadas"
},
"active_changes": false,
"schema_changes": false,
"runtime_hashes": {
"resources/js/lib/ispc-eligibility.ts": "1828cb2d696a6bd852078fc3f1cf90a6649c1f3a0df5bec0a72ac1d1f175b2eb",
"resources/js/components/simulation-ispc-eligibility.tsx": "38ebe2b2fd340e269ba6fdeec96f0d39d0594892b9cb968ec094b2c165346b42",
"resources/js/components/simulation-form.tsx": "5090175a3fee965795fb47ac7f673c5aafc3641c25d323be0be631178afae775",
"resources/js/lib/project-dossier.ts": "de70672560162ef94f1e5429f70c2466a8347e73b2d800da013c7c50e480091c"
}
}
@@ -0,0 +1,479 @@
{
"schema_permissions_comparison": {
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
"filesystem_permissions": {
".env": {
"mode": 416,
"uid": 1001,
"gid": 33
},
"storage": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"storage/app": {
"mode": 1533,
"uid": 1001,
"gid": 33
},
"bootstrap/cache": {
"mode": 1528,
"uid": 1001,
"gid": 33
}
},
"comparison_identity": "postgres;catalogue read only;no passwords collected",
"unchanged": true
},
"status": "installed_grouped_ISPC_residual_delta_verified",
"authorization": "Tempo: deliver grouped residual delta through Git with fresh backup/restore and delta verification; preserve habitual6af and L3; not full IRPS/ISPC completion.",
"candidate_installed": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"previous_installed": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"fresh_backup": {
"stage": "/var/backups/investmoz-ispc-residual-delivery-20261025/backup",
"created_at": "2026-10-25T16:20:55Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "027d5dfdd06b317c9b480b1673b1b55b91cfb222f2720d039d62801733773cfe",
"files_sha256": "1857e41142879c97b0166277546dc01880326dbe832e5520a871cfbf19796d41",
"restore_verified": false
},
"isolated_restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "ispc_residual_restore_20261025",
"port": 55441,
"source_dump_sha256": "027d5dfdd06b317c9b480b1673b1b55b91cfb222f2720d039d62801733773cfe",
"active_database_writes": 0
},
"authenticated_preflight": {
"free_bytes": 6490124288,
"existing_pipeline_minimum_bytes": 5368709120,
"space_guard_satisfied": true,
"installed": {
"status": "installed",
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"previous_release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"release_revision": {
"commit": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"branch": "main",
"built_at": "2026-10-25T15:29:39.962545+00:00",
"manifest_sha256": "0761702f0aa0f54dd4e7dac14efadf290830c52a5762a97733d82f5332fb44a8"
},
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"configuration_keys": [
"repository",
"branch",
"target_url",
"legacy_root",
"state_root",
"release_root",
"current_link",
"shared_assets",
"php",
"schema_contract",
"ci_environment",
"postgis_image",
"test_database",
"qa_port",
"retention",
"webhook_secret_file"
],
"safe_paths": {
"repository": "nala/Investidor-V2",
"release_root": "/var/www/investmoz-homologacao/releases",
"postgis_image": "postgis/postgis@sha256:01a6a70e41e6c4467c8f55f6063555ed72db2d6662cd0d571040d42eadaeb6f6"
},
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
},
"installed_protected_delta": {
"installed": {
"status": "installed",
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"release": "/var/www/investmoz-homologacao/releases/5c0cb25cea7826811c389b55a64bcdf5e43b937f-32c4fd00",
"previous_release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 7,
"L3_unchanged_runtime_files_verified": 16,
"documentary_files_verified": 21,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "22eb03056dae006c1c92badee23e6109"
},
"after": {
"rows": 106,
"checksum": "eec58e1179f9023ab578cd1401bca5de"
}
},
"sessions": {
"before": {
"rows": 9,
"checksum": "cc0d72daaa3994d422a41cc7c84a5f60"
},
"after": {
"rows": 10,
"checksum": "98394985102c0779844faa9d537a7b53"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"installed_public": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"branch": "main",
"built_at": "2026-10-25T16:24:27.707113+00:00",
"manifest_sha256": "385a289f9ba26a632aa0164fbba3913cc8dc2fb891641881fc8d2dcda1951626"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Calcular e guardar operações ocasionais": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar parcela excedente": [
"assets/services-Cvwv29Mo.js"
],
"Preparar e guardar campos B–Geral": [
"assets/services-Cvwv29Mo.js"
],
"Descarregar preparação B–Geral": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar restituição E": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar acompanhamento D": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar substituições C": [
"assets/services-Cvwv29Mo.js"
]
},
"assets": [
{
"file": "assets/services-Cvwv29Mo.js",
"status": 200,
"sha256": "aa51139b6509bd66927a578e88cd115f497f80f9ae6406d6fb84db7df858340c"
},
{
"file": "assets/project-dossier-BJrlh6zA.js",
"status": 200,
"sha256": "e800e5bd5bcbb18cb417db0796c9c3e85600fd65c79b9808577148c4805eb3dc"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-document-kUHwyL01.js",
"status": 200,
"sha256": "575c47d1ad13193cabc84b43fe555551fba677fb617f57c0f7445dc2d0409f98"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-DmFRsc4U.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 9,
"after_rows": 12,
"changes": [
{
"key_sha256": "b7fa07a8ea67586994a66f15ffcc4d1a0df81fbe07dc8ade44bfdba20db30651",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "eb22f458a6354ff34d4e80ede2a4c9f3a81c4fa1be35f34fae1dc8d9f20dc294",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "4a0a44f3b0a78e66a5aac0587d8474f21e26cc91018361267b795afcbea203a2",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"pipeline_status": {
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"installed": {
"status": "installed",
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"release": "/var/www/investmoz-homologacao/releases/5c0cb25cea7826811c389b55a64bcdf5e43b937f-32c4fd00",
"previous_release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"database_migrations": 0,
"content_imports": 0
},
"latest_report": {
"status": "installed",
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"release": "/var/www/investmoz-homologacao/releases/5c0cb25cea7826811c389b55a64bcdf5e43b937f-32c4fd00",
"previous_release": "/var/www/investmoz-homologacao/releases/6af7092e83b9b3932712aa7a9f527393fcec4da8-647c8e2e",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"5c0cb25cea7826811c389b55a64bcdf5e43b937f"
],
"finished_at": "2026-10-25T16:24:30.738299+00:00"
},
"log_file": "1792945281843706519.log",
"summaries": [
"OK (1 test, 3106 assertions)",
"built in 29.13s",
"OK (59 tests, 317 assertions)",
"# tests 801",
"# pass 801",
"# fail 0"
],
"log_bytes": 231911
},
"runtime_delta": [
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "07f7d0d73993ffc2924f1b9b2d21cbc53fb7c95aab959c0820fd7dbc35a1fffa"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "beca4eebd3959afa520061f231de25d064723537bd98deb541712ab448eba369"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
}
],
"accepted_QA_proofs_reused": {
"preservation_before_tests": "outputs/ispc-residuals-20261025/preservation-before-tests.json",
"new_frontend_distinct": 19,
"frontend_proofs": [
"frontend-final.txt:14passed",
"directed-final.txt:1additionalpass",
"directed-retention-form.txt:1additionalpass",
"directed-known-exclusions.txt:1additionalpass",
"directed-dispensation-form.txt:1additionalpass",
"directed-liberatory-history.txt:1additionalpass"
],
"API": "1test/22assertionspassed;QAloopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;APP_BASE_PATHcandidateexplicit",
"UI": "Vendedor376/adquirente375separados;3000/5000/20000/25000;guardar→recuperar→relatório;B–Geralpreparadodescarregado;visibilidadeapenasdascondiçõesafectadasverificada",
"UI_proofs": [
"ui-own-report.txt",
"ui-acquisition-report.txt",
"ui-occasional-applicability.txt",
"ui-regular-applicability.txt",
"preparation.html"
],
"types": "exit0;types-final.txt",
"build": "exit0;build-final.txt",
"habitual_re_evaluation": "not repeated;arithmetic engines unchanged;24000snapshotpreservedexactly;onlyconditionalvisibilitydeltaexamined"
},
"manual_functional_tests_repeated": false,
"pipeline_checks": "Mandatory existing Git pipeline checks only.",
"available": [
"Operações ocasionais próprias no âmbito demonstrado, sem segunda prestação sobre retenção liberatória documentada.",
"Parcela excedente no caso IRPS qualificado demonstrado; sem taxa automática para outros enquadramentos.",
"Preparação/exportação B–Geral com documentos e histórico."
],
"remaining_calculations": [
{
"item": "Juros compensatórios",
"state": "montante documentado pode ser conservado;fórmula ainda não implementada",
"needed": "regra/taxa/base/período/dias efectivamente aplicáveis,no documento/instrução correspondente;sem zero ou taxa presumidos"
},
{
"item": "Outros enquadramentos da parcela excedente",
"state": "sem fórmula genérica;casos diferentes do acto isolado qualificado não recebem taxa automática",
"needed": "natureza,regime do fornecedor,opção aplicável,base e suporte concretos;encaminhar para o cálculo próprio quando for outro regime,não bloquear o caso positivo implementado"
}
],
"remaining_formal_correspondences_instructions": [
{
"item": "Quadro2doB–Geral",
"needed": "correspondência concreta do mês/ano a inscrever para o trimestre;comunicado fornece meses de pagamento,que não são copiados automaticamente para período"
},
{
"item": "Dispensa inferior500MZN noB–Geral",
"needed": "Representação declarativa do imposto apurado com prestação dispensada10-A;sem preencher montanteapurado comozero porpresunção. O cálculo imposto/prestação jáestá implementado."
},
{
"item": "Entrega de retenções",
"needed": "modelo/código/instrução próprios12(3)ISPCe57(2k)IRPS;B–Geraldeapoio nãoéapresentadocomocorrespondênciacompletadestasretenções"
},
{
"item": "Regulamentação2026/instruções de envio de facturas",
"needed": "texto/exemplar/instrução concreta quando disponibilizado;comunicado transitório já implementado,não se mantém pesquisa genérica como aprovação adicional"
},
{
"item": "Submissão e pagamento",
"needed": "actos externos e comprovativos reais;nenhuma operaçãoATfoiexecutadaemQA"
}
],
"external_to_portal": "Actos da AT: exportação não equivale a submissão, recepção, aceitação ou pagamento.",
"ISPC_integrally_completed": false,
"IRPS_integrally_completed": false,
"schema_migrations": 0,
"content_imports": 0,
"preserved_L3_amounts_MZN": {
"documentary": 16,
"deduction_this_route": 0,
"recognised": 12,
"received": 7,
"awaiting": 5
},
"residuals": "L3residuals in existing matrix;P001/P058 nonblocking;P084/P085 closed;statistics/AI deferred.",
"proof_hashes": {
"outputs/ispc-residual-delivery-20261025/backup.txt": "2c5838cda547495dee6ac3acc1971457b4d6a34399766c142e13501ac16fac61",
"outputs/ispc-residual-delivery-20261025/installed-protected.txt": "95a376d4970744f3a0f02757870968f989d87b3549f6aa841676ddf38df4bddf",
"outputs/ispc-residual-delivery-20261025/installed-public-delta.json": "f092efaeb3091d3fc345ab2979a5f3fa3ee8ed644d05175e45f393fb78910ac7",
"outputs/ispc-residual-delivery-20261025/installed-public.txt": "88facda241ab71035c481c9cc2d4a21c0c2fe5eb4d703d88ffa8557c7602dcb3",
"outputs/ispc-residual-delivery-20261025/integration.txt": "52d05eed26351310f897d3b647c605e6fdb0b7d6a570487ff6f7b8a3c11287ed",
"outputs/ispc-residual-delivery-20261025/manifest-served.json": "385a289f9ba26a632aa0164fbba3913cc8dc2fb891641881fc8d2dcda1951626",
"outputs/ispc-residual-delivery-20261025/operational-delta.txt": "7ba0c56bd9395003f7b384683ee106d00dfa500d98ce61e45d5057548e9451dc",
"outputs/ispc-residual-delivery-20261025/preflight.txt": "f05ba4c7c5e636da470a6aeb63332d5a673807d2493213df98ef016acef0770d",
"outputs/ispc-residual-delivery-20261025/preparation.json": "49e3ade28b69afddb94cf3076964c8bf61197ae201d4eecb9b1619962c9f8a2d",
"outputs/ispc-residual-delivery-20261025/progress.txt": "db8b637be9106ed97abbca2ccef38729509a47f2ee006784e2f6f0a0a485bd87",
"outputs/ispc-residual-delivery-20261025/restore.txt": "093b66c345788125f01f02aa93867812a3587107515b5592f7aa999cf3f437cc",
"outputs/ispc-residual-delivery-20261025/schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"outputs/ispc-residual-delivery-20261025/schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"outputs/ispc-residual-delivery-20261025/status-final.txt": "3f0db035a0d53507176ff8af6f9361c813fe0f64975c61f91ea48a6b53ab5ea5",
"outputs/ispc-residual-delivery-20261025/status1.txt": "33f1595c6ab8b9f6e6231e2c54ae78c171dbb560e24dc305180061d8a04a5425",
"outputs/ispc-residual-delivery-20261025/status2.txt": "7d9f4cb894d96915b622734a2b39f70df8ef0832337f92136e010f51a5abda6d",
"outputs/ispc-residual-delivery-20261025/status3.txt": "8414250023b01144b3d2cdabe21e7ad35c89aee6883b938950b50f6642ba0203",
"outputs/ispc-residual-delivery-20261025/status4.txt": "0d8002ce39bc890aade37606652c68c7b10bc05db3372da770aab879cce1742d",
"outputs/ispc-residual-delivery-20261025/status5.txt": "0d8002ce39bc890aade37606652c68c7b10bc05db3372da770aab879cce1742d",
"outputs/ispc-residual-delivery-20261025/status6.txt": "0d8002ce39bc890aade37606652c68c7b10bc05db3372da770aab879cce1742d",
"outputs/ispc-residual-delivery-20261025/status7.txt": "3f0db035a0d53507176ff8af6f9361c813fe0f64975c61f91ea48a6b53ab5ea5"
}
}
@@ -0,0 +1,260 @@
{
"status": "installed_grouped_scoped_residual_delta",
"matrix_anchor": "AUD-SIM-INT02",
"base_installed": "6af7092e83b9b3932712aa7a9f527393fcec4da8",
"branch": "codex/ispc-residuals-qa-20261025",
"scope": "Operações ocasionais próprias3(3–4),aquisições acima do limite12(3)comcorrespondênciapositivaIRPS57(2k),preparação/transporte de camposB–Geral e histórico externo;semfechointegralISPC.",
"sources": [
{
"path": "docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf",
"bytes": 308401,
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"availability": "private source archive;not automatically published/imported into active library",
"scan": "not claimed"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf",
"bytes": 319577,
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"availability": "private source archive;not automatically published/imported into active library",
"scan": "not claimed"
},
{
"path": "docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf",
"bytes": 159748,
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"availability": "private source archive;not automatically published/imported into active library",
"scan": "not claimed"
},
{
"path": "docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf",
"bytes": 1894997,
"sha256": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
"availability": "private source archive;not automatically published/imported into active library",
"scan": "not claimed"
}
],
"official_source_inventory": {
"local_reused": "outputs/ispc-l4a-20261025/preservation-before-tests.json",
"AT_forms": "39documents;at-forms.json",
"AT_legislation": "189documents;at-legislation.json",
"AT_communications": "4documents;at-communications.xml",
"provenance": "AT public document APIs reached through links/configuration of the official website;BR2017 republication hostedOCAM;no generic second authenticity validation",
"AT_comunicado": {
"url": "https://www.at.gov.mz/api/webdav?path=%2FINFORMA%C3%87%C3%95ES%2FCOMUNICADO%20DE%20IMPRENSA%2F07-10-2026%20-%20COMUNICADO%20N%C2%BA9_2026%20-%20CUMPRIMENTO%20DAS%20OBRIGA%C3%87%C3%95ES%20DECLARATIVAS%20E%20DE%20PAGAMENTO%20DO%20ISPC.pdf",
"listing": "https://www.at.gov.mz/informacoes/comunicado-de-imprensa",
"file": "C:\\laragon\\www\\portal-investidor-ispc-residuals-qa-20261025\\docs\\investmoz\\simulations\\source-archive\\AT-Comunicado-9-2026-ISPC.pdf",
"sha256": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"bytes": 308401,
"origin": "AT official website; public document linked from communications page",
"automatic_rule_activation": false
},
"AT_forms_selected": [
{
"id": "ed263a2ecdd81846af4cdc8f75fc76c1",
"title": "Modelo 30 ISPC IMPOSTO SIMPLIFICADO PARA PEQUENOS CONTRIBUINTES",
"description": "Documentação oficial sincronizada em tempo real.",
"size": "156 KB",
"date": "06/01/2026",
"url": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIRPC%2FModelo%2030%20ISPC%20IMPOSTO%20SIMPLIFICADO%20PARA%20PEQUENOS%20CONTRIBUINTES.pdf",
"downloadUrl": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIRPC%2FModelo%2030%20ISPC%20IMPOSTO%20SIMPLIFICADO%20PARA%20PEQUENOS%20CONTRIBUINTES.pdf",
"viewUrl": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIRPC%2FModelo%2030%20ISPC%20IMPOSTO%20SIMPLIFICADO%20PARA%20PEQUENOS%20CONTRIBUINTES.pdf",
"file": "C:\\laragon\\www\\portal-investidor-ispc-residuals-qa-20261025\\docs\\investmoz\\simulations\\source-archive\\AT-Modelo-30-ISPC.pdf",
"origin": "AT official forms directory",
"sha256": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"bytes": 159748
},
{
"id": "c37f0377df612928865f37cfbfc9dabd",
"title": "MODELO B GERAL",
"description": "Documentação oficial sincronizada em tempo real.",
"size": "312 KB",
"date": "28/10/2025",
"url": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIVA%2FMODELO%20B%20GERAL.pdf",
"downloadUrl": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIVA%2FMODELO%20B%20GERAL.pdf",
"viewUrl": "/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIVA%2FMODELO%20B%20GERAL.pdf",
"file": "C:\\laragon\\www\\portal-investidor-ispc-residuals-qa-20261025\\docs\\investmoz\\simulations\\source-archive\\AT-Modelo-B-Geral.pdf",
"origin": "AT official forms directory",
"sha256": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"bytes": 319577
}
],
"IRPS_Bulletin_URL": "https://ocam.org.mz/wp-content/uploads/2024/06/Lei-n-19_2017-de-28-de-Dezembro-IRPS-2-1.pdf"
},
"implemented_calculations": [
{
"case": "Operação ocasional própria",
"positive": "Pessoa singular,semactividadehabitual,actoimprevisível/nãoreiterado,nacional,nasfamílias3(4);IRPS8(3h,4)/9da republicação19/2017;ISPC4/5/8/9/10-A. Cenário100000MZN/3%=3000;opção/factosefectivosdistintosdeprevisão.",
"anti_duplication": "Retenção liberatória5%documentadareconciliadacomabase não gera segunda liquidação própria;divergência ficaindeterminada,nãohácréditopresumido."
},
{
"case": "Aquisição que atravessa2.500.000MZN",
"positive": "Acumulado2400000+aquisição200000:parcela100000atélimite/retencão5000;excedente100000separado. SóactoIRPSqualificado57(2k),semopçãoISPCaplicável,comrendimentoilíquidoidentificado permite20000noexcedente;total25000de retenções,não imposto próprio do adquirente.",
"limits": "Sem enquadramento/base/documentos,parcela excedente e total permanecem indeterminados. Fornecedor com opçãoISPC não recebeIRPS20automaticamente;factura/liquidação própria são âmbito separado. Não se usa20%do excesso de vendasISPC para compras."
}
],
"implemented_formal_preparation": [
"ATcomunicado9/2026visualizado:ModeloB–Geraltransitório,enquanto sistemaéajustado;mesesJaneiro/Abril/Julho/Outubro;nenhumdiadomêsinventado.",
"OriginalB–Geral2pconferido:quadros1/2/3/5/6/8/10;linha1base01/montante05,linha2base02/montante06,subtotal09;numeração própria doquadro10nãosemisturacomquadro8.",
"HTMLdepreparação,relatóriorecuperado efontes/originaispreservados;semrecriarformuláriooficial,assinatura,recibosouacçãodafuncionário. RetençõesISPC5/IRPS20descritas separadamente.",
"Modelo30oficialdisponívelaindaexibe75.000/3%antigos:preservadoparaconsulta,nãotransportadopara2026.",
"Estadosdepreparação/submissão/recepção/pagamentodeclaradoscomreferência/dataehistórico;sem efectuaressasacçõesoucertificarAT."
],
"remaining_calculations": [
{
"item": "Juros compensatórios",
"state": "montante documentado pode ser conservado;fórmula ainda não implementada",
"needed": "regra/taxa/base/período/dias efectivamente aplicáveis,no documento/instrução correspondente;sem zero ou taxa presumidos"
},
{
"item": "Outros enquadramentos da parcela excedente",
"state": "sem fórmula genérica;casos diferentes do acto isolado qualificado não recebem taxa automática",
"needed": "natureza,regime do fornecedor,opção aplicável,base e suporte concretos;encaminhar para o cálculo próprio quando for outro regime,não bloquear o caso positivo implementado"
}
],
"external_formal_dependencies": [
{
"item": "Quadro2doB–Geral",
"needed": "correspondência concreta do mês/ano a inscrever para o trimestre;comunicado fornece meses de pagamento,que não são copiados automaticamente para período"
},
{
"item": "Dispensa inferior500MZN noB–Geral",
"needed": "Representação declarativa do imposto apurado com prestação dispensada10-A;sem preencher montanteapurado comozero porpresunção. O cálculo imposto/prestação jáestá implementado."
},
{
"item": "Entrega de retenções",
"needed": "modelo/código/instrução próprios12(3)ISPCe57(2k)IRPS;B–Geraldeapoio nãoéapresentadocomocorrespondênciacompletadestasretenções"
},
{
"item": "Regulamentação2026/instruções de envio de facturas",
"needed": "texto/exemplar/instrução concreta quando disponibilizado;comunicado transitório já implementado,não se mantém pesquisa genérica como aprovação adicional"
},
{
"item": "Submissão e pagamento",
"needed": "actos externos e comprovativos reais;nenhuma operaçãoATfoiexecutadaemQA"
}
],
"operation_data_missing_in_synthetic_preparation": "Identidade/NUIT/área fiscal/domicílio,referência de período ejuros são dados para formalizar a operação,não nova condição de acesso ao cálculo.",
"verification": {
"preservation_before_tests": "outputs/ispc-residuals-20261025/preservation-before-tests.json",
"new_frontend_distinct": 19,
"frontend_proofs": [
"frontend-final.txt:14passed",
"directed-final.txt:1additionalpass",
"directed-retention-form.txt:1additionalpass",
"directed-known-exclusions.txt:1additionalpass",
"directed-dispensation-form.txt:1additionalpass",
"directed-liberatory-history.txt:1additionalpass"
],
"API": "1test/22assertionspassed;QAloopback55441/simulator_fiscal_delta_20261021_test;DatabaseTransactionsrollback;APP_BASE_PATHcandidateexplicit",
"UI": "Vendedor376/adquirente375separados;3000/5000/20000/25000;guardar→recuperar→relatório;B–Geralpreparadodescarregado;visibilidadeapenasdascondiçõesafectadasverificada",
"UI_proofs": [
"ui-own-report.txt",
"ui-acquisition-report.txt",
"ui-occasional-applicability.txt",
"ui-regular-applicability.txt",
"preparation.html"
],
"types": "exit0;types-final.txt",
"build": "exit0;build-final.txt",
"habitual_re_evaluation": "not repeated;arithmetic engines unchanged;24000snapshotpreservedexactly;onlyconditionalvisibilitydeltaexamined"
},
"runtime_delta": [
{
"path": "resources/js/lib/ispc-residuals.ts",
"sha256_LF": "40d5751c06c7c155ab4b7a17ee2d1653da2fbbf075807fbb8561cdbe19820955"
},
{
"path": "resources/js/components/simulation-ispc-residuals.tsx",
"sha256_LF": "a9219d6f41ccbd0ce45659d4f6aa0fa1c169a685840f5cb1e18daeca377d5e18"
},
{
"path": "resources/js/components/simulation-form.tsx",
"sha256_LF": "07f7d0d73993ffc2924f1b9b2d21cbc53fb7c95aab959c0820fd7dbc35a1fffa"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "beca4eebd3959afa520061f231de25d064723537bd98deb541712ab448eba369"
},
{
"path": "resources/js/lib/ispc-eligibility.ts",
"sha256_LF": "44675c5efacdc1ae19505667611ba3b522d3043cebacc8754597c3a68ca89d25"
},
{
"path": "resources/js/components/simulation-ispc-quarter.tsx",
"sha256_LF": "2c2555309b32d4261f14e7164f39314c9188129c2990357fc54090a2468dd2b4"
},
{
"path": "resources/js/components/simulation-ispc-withholding.tsx",
"sha256_LF": "e0445d015b72859e48726959aa52686f79b1cf5c2ade29751efa83257068b878"
}
],
"compiled_markers": {
"Calcular e guardar operações ocasionais": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar parcela excedente": [
"assets/services-Cvwv29Mo.js"
],
"Preparar e guardar campos B–Geral": [
"assets/services-Cvwv29Mo.js"
],
"Descarregar preparação B–Geral": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar apuramento trimestral ISPC": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar restituição E": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar acompanhamento D": [
"assets/services-Cvwv29Mo.js"
],
"Calcular e guardar substituições C": [
"assets/services-Cvwv29Mo.js"
]
},
"schema_backend_configuration_dependency_changes": false,
"active_changes": false,
"originals_previous_preserved": 17,
"existing_books_preserved": "L3,ISPC habitual andacceptedhistories;no reset or overwrite of deliberateedits",
"P001_P058": "unchanged;notblocking",
"P084_P085": "closed",
"statistics_AI": "deferred",
"proof_hashes": {
"outputs/ispc-residuals-20261025/frontend-final.txt": "bb0db1bde933e5fe08356537df1ba783003629f7fcc21abdcf18e119bcb0ab8d",
"outputs/ispc-residuals-20261025/directed-final.txt": "9a2de706bca568599efd9dbfff7cb2c55ba037d64139e0b7d269271b9d84582b",
"outputs/ispc-residuals-20261025/directed-retention-form.txt": "44061cb0f2661fb27b6c1e0acca437710d6569f482c0ad521bec95aced7216f5",
"outputs/ispc-residuals-20261025/directed-known-exclusions.txt": "9c2e039af72cd3b46624979d1d07cae31ffc7f19572dfec1c279272dfdaee0dc",
"outputs/ispc-residuals-20261025/directed-dispensation-form.txt": "ff6ab503c476af55e950937d99a40eb6591d7d479cfed60dcddc681dcf7421fb",
"outputs/ispc-residuals-20261025/api.txt": "12ac172c5898f91ed9ac1bd0216265c33683e6984e817c5d6cb8759c1448b184",
"outputs/ispc-residuals-20261025/types-package.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"outputs/ispc-residuals-20261025/build-package.txt": "d3b9271730c3e0e6dd87f770a7d7badeb7a5e25e76aac44877b4484078e037b4",
"outputs/ispc-residuals-20261025/ui-own-report.txt": "c770078829e65c3830116c192d819c1f8327b8024806b841d88436219bb26571",
"outputs/ispc-residuals-20261025/ui-acquisition-report.txt": "ce976d2042e8ab7f13c42c42b8bd13a32ad67a2eb64ccf408ddf7d20688f1534",
"outputs/ispc-residuals-20261025/ui-occasional-applicability.txt": "72a3eee5b24c5b18faef1ab00076fb9e4d550b84daac41690dfc4488201311b8",
"outputs/ispc-residuals-20261025/ui-regular-applicability.txt": "2fb06f6e9e845022a464c9ffcc1fdee66b3ee2566bfce811c3e63b02cef4ab0a",
"outputs/ispc-residuals-20261025/preparation.html": "bd8dabebcc27b1e27df345648cf6b8fd5ce780f37d422d23f3689ef941f52cf1",
"outputs/ispc-residuals-20261025/active-baseline.json": "ed1e4d9c09215f9695fad1e02e6efec4c5a7097c5c35f0425e3a5142e98f2bc1",
"outputs/ispc-residuals-20261025/directed-liberatory-history.txt": "ec7836ece4ea47a5e5b039958f18ed0d00cd87af219e1ce3cad2316c7f36977d",
"outputs/ispc-residuals-20261025/types-final.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"outputs/ispc-residuals-20261025/build-final.txt": "939ba2172a3b5360d909d36199887f34a9a654f2f4e57a19a12b9c763dd9ca92"
},
"preservation_audit": {
"matrix_only_changed": "AUD-SIM-INT02",
"L1_closed_preserved": 131,
"original_PDFs_preserved": 17,
"habitual_arithmetic_engines": "ispc-quarter.ts/ispc-withholding.ts byte-identical to6af7092e",
"eligibility_regular_path": "byte-identical except message for occasional route",
"source_scope_choices": "Separate books,concrete factinputs and exact cap intervals are implementation choices,not new organisational approvals;no generic legal/provenance revalidation."
},
"liberatory_history_guard": "Same operation reference/date/quarter/amount with documented prior liberatory withholding cannot generate another own payment without explicit correction reference; history preserved.",
"QA_status_before_delivery": "QA_grouped_compatible_delta_not_installed",
"installation_followup": {
"commit": "5c0cb25cea7826811c389b55a64bcdf5e43b937f",
"receipt": "ispc-residual-delivery-20261025.json",
"ISPC_integrally_completed": false,
"IRPS_integrally_completed": false
}
}
@@ -1,6 +1,6 @@
{
"status": "prepared_compatible_QA_not_installed_fresh_authenticated_backup_restore_pending",
"authorization": "Tempo25/10:avançarcoberturaL3QA,conferirapenasofaltanteepreparentregacompatível;depoissaldoL3eL4ISPC.",
"status": "installed_and_delta_verified",
"authorization": "Tempo25/10:entregarL3combackup/restaurofrescoeconferênciadodelta;L3mantémresiduaispróprios.",
"base_installed": "7ad187f9f0745245268e3ed5317547a96b4700f3",
"source_QA": "b189d0fa",
"candidate_branch": "codex/l3-additional-delivery-20261025",
@@ -262,5 +262,262 @@
"SemcontacentralATpresumida,novaautoridadeoucondiçãoorganizacional.",
"Preparação não equivale ainstalação;backup antigo nãoéprovafresca."
],
"active_writes": 0
"active_writes": 0,
"candidate_commit": "0f4df8a4d1cfd0d7b788e58d7f6af8d385384d82",
"candidate_build_proof": "outputs/l3-additional-delivery-20261025/candidate-build-final.txt",
"candidate_types_proof": "outputs/l3-additional-delivery-20261025/candidate-types.txt",
"requested_candidate": "0f4df8a4d1cfd0d7b788e58d7f6af8d385384d82",
"installed_commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"compatibility_correction": {
"requested_candidate": "0f4df8a4",
"actual_target": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"delta": "tests/frontend/iva-l1-delta.test.mjs only; obsolete text assertions updated to accepted P001 residual. No fiscal/runtime/schema/config/data changes.",
"new_evidence": "pipeline756/757;singlefailurelegacywording",
"directed_verification": "1passed;legacy-assertion.txt",
"P001": "remainsresidual;no functional expansion or research"
},
"authenticated_backup": {
"stage": "/var/backups/investmoz-l3-additional-delivery-20261025/backup",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "ef95cc22d9c5c6b924309fa8c7654a42d7afe67e26b0c118903f507dd2693d0e",
"files_sha256": "b60d64adfc99ed51621ace3d8b273bf3c723978cf8dd08b16c61fab5a3dfb0e3",
"restore_verified": false
},
"isolated_restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "l3_additional_restore_20261025",
"port": 55441,
"source_dump_sha256": "ef95cc22d9c5c6b924309fa8c7654a42d7afe67e26b0c118903f507dd2693d0e",
"active_database_writes": 0
},
"installed_preservation": {
"installed": {
"status": "installed",
"commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"release": "/var/www/investmoz-homologacao/releases/fa32a2b9e127da9c4d764dd99ef58ee43b770aa6-ad33eeab",
"previous_release": "/var/www/investmoz-homologacao/releases/7ad187f9f0745245268e3ed5317547a96b4700f3-066618f1",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 12,
"documentary_files_verified": 17,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "8ba41882cd8a7068c45619b3234af395"
},
"after": {
"rows": 106,
"checksum": "e2140cc9610defc5e64743159fb4df57"
}
},
"sessions": {
"before": {
"rows": 153,
"checksum": "66a8c21d1167a5c4ef27e205006736d4"
},
"after": {
"rows": 154,
"checksum": "6bd8d1311dcc20736dacc02873316399"
}
}
},
"preserved_counts": {
"published_fiches": 29,
"relations": 28,
"geometries": 408
},
"migration_count": 0,
"content_imports": 0,
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
"writes_by_verification": 0
},
"installed_public": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"branch": "main",
"built_at": "2026-10-25T15:12:37.806036+00:00",
"manifest_sha256": "cddac25dc66b3e555f2380cf3a9d4b2da6501cd03927c183c832a05b0ee5c993"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"Repartição do IVA documental em MZN": [
"assets/services-Yy7oCdim.js"
],
"Reconciliação da dedução anterior": [
"assets/services-Yy7oCdim.js"
],
"Cálculos indeterminados e condições para resolver": [
"assets/services-Yy7oCdim.js"
],
"Preparação dos quadros L3 e formalidades": [
"assets/services-Yy7oCdim.js"
],
"Calcular e guardar restituição E": [
"assets/services-Yy7oCdim.js"
],
"Calcular e guardar acompanhamento D": [
"assets/services-Yy7oCdim.js"
],
"Calcular e guardar substituições C": [
"assets/services-Yy7oCdim.js"
]
},
"assets": [
{
"file": "assets/project-dossier-document-DEYq4rSm.js",
"status": 200,
"sha256": "76e21fbdb32395a7208023b171208a278d966a726ca5da75616eb4895f900085"
},
{
"file": "assets/services-Yy7oCdim.js",
"status": 200,
"sha256": "fcccdac290664ac7ab03656f2b82fc412d558352611f96d356d0fa6b82eabee8"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/project-dossier-BFOK3ylo.js",
"status": 200,
"sha256": "ee9695ec2699120f5e9381d3e27384a6e4c969899f12659b75b47e7f8f3fa2ac"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-8LF5gm1q.js",
"existing_fiscal_availability": {
"data": {
"enabled": true,
"coverage_start": "2026-01-01",
"coverage_end": "2026-12-31",
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
}
},
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"build_dependency_archival": {
"status": "dependencies_archived_and_verified",
"versions": 11,
"free_before": 4627697664,
"free_after": 7521255424,
"receipt": "/var/backups/investmoz-build-dependencies-20261025/receipt.json",
"protected": [
"/var/www/investmoz-homologacao/releases/de36f02880adf2337edf9f08c3eb424424adcca0-b247ef3c",
"/var/www/investmoz-homologacao/releases/7ad187f9f0745245268e3ed5317547a96b4700f3-066618f1"
],
"active_or_previous_release_modified": false,
"source_data_backups_deleted": 0
},
"operational_delta": {
"status": "operational_delta_reconciled",
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
"cache": "queue:restart value/expiry and request-throttle counter/timer pair;no deleted cache rows",
"sessions": "anonymous sessions created by exact delivery verification user-agent",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-{hash}:timer",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true
},
{
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
"kind": "updated",
"fields": [
"value",
"expiration"
],
"key_pattern": "investemoz-cache-illuminate:queue:restart",
"is_queue_restart_key": true,
"expiration_unchanged": false,
"throttle_timer_pair": false
}
]
},
"sessions": {
"before_rows": 153,
"after_rows": 156,
"changes": [
{
"key_sha256": "9e2b645a40c93a4975977fd394b80496ecabd7a5b8ae17c259b4105f342e5937",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "1fbd25a79d44d1826aa3b95e1bf19c4268a56b0398ec74f3d4e5b7d5bc44c752",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
},
{
"key_sha256": "65497833fad3b62fd5f3982ff4c6c2770ffb0599616e57f917d38762b87cc59a",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true
}
]
}
},
"business_tables_unchanged": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"remaining_balance_reference": "l3-e-additional-coverage-qa-20261025.json:current_L3_balance_20261025"
}
@@ -116,14 +116,14 @@
]
},
"current_L3_balance_20261025": {
"base_installed": "7ad187f9",
"base_installed": "fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"QA_increment": "b189d0fa",
"items": [
{
"item": "Entrega do incremento b189d0fa",
"tipo": "disponibilização",
"estado": "QA demonstrada;não instalada",
"falta": "Entrega pelo processoGit existente,com comparação fresca do destino,backup/restauro e conferência do delta. Não repetir provas aceites sem alteração relevante."
"estado": "Entregue e conferido no activo em fa32a2b9e127da9c4d764dd99ef58ee43b770aa6",
"falta": "Nenhuma neste delta;backup/restauro fresco e conferência pública/protegida concluídos. Demais itensL3 mantidos com âmbitos próprios."
},
{
"item": "Mudança/anulação de dedução anterior e versões divergentes",
@@ -157,7 +157,9 @@
}
],
"scope_limit": "A prevenção de duplicação cobre os livros/históricos recuperados. Reconciliação central com aAT ou todos os dossiers não foi demonstrada;isto é limite técnico registado,não nova condição organizacional de fecho.",
"outside_L3": "L1:131entregues+P001residual+P058parcial/residual=133;P084/P085fechados. P001retomasócomnovoesclarecimentoconcreto;L2limitespróprios;estatísticas/IAadiadas."
"outside_L3": "L1:131entregues+P001residual+P058parcial/residual=133;P084/P085fechados. P001retomasócomnovoesclarecimentoconcreto;L2limitespróprios;estatísticas/IAadiadas.",
"prepared_candidate": "0f4df8a4d1cfd0d7b788e58d7f6af8d385384d82",
"delivered_increment": "0f4df8a4 + fa32a2b9(test-only)"
},
"P001_followup": {
"status": "residual_preserved_resume_only_on_concrete_clarification",
@@ -106,3 +106,89 @@ A pesquisa read-only no catálogo oficial da INM voltou a localizar o BR n.º 18
Fontes oficiais: [catálogo INM — BR 186/187 e aviso de indisponibilidade gratuita](https://inm.gov.mz/pt-br/bulletin?field_tipo_de_produto_tid_br=43), [ficha BR 186](https://inm.gov.mz/pt-br/content/br-n%C2%BA-186-de-300926-boletim-da-rep%C3%BAblica-i-serie), [ficha BR 187](https://inm.gov.mz/pt-br/content/br-n%C2%BA-187-de-011026-boletim-da-rep%C3%BAblica-i-serie).
Estado: confirmação oficial apenas de existência, datas e modalidade de acesso; textos, diplomas, artigos, vigência, transição e âmbito fiscal continuam por confirmar. Manter IRPC, IRPS, ISPC, IVA regulamentar, pautas/cálculos aduaneiros e regras contributivas sem activação até obtenção, análise e aprovação competente.
## 25/10/2026 — fontes adicionais dos residuais ISPC
Inventários oficiais AT guardados antes da selecção:39formulários,189documentos legislativos e4comunicados. O Comunicado9/2026 e os exemplares B–Geral/Modelo30 foram recuperados pela ligação pública do próprio portalAT. A republicaçãoIRPS19/2017 é exemplar do BR202/7.ºsuplemento,disponibilizado pelaOCAM;arts8/9naPDF4 e57naPDF13 foram conferidos visualmente,com alteração2026confrontada naLei11/2025. O código local mais antigo não foi usado para a numeração dos actos isolados. A aceitação oficial mantém-se,sem segunda validação de proveniência.
- `AT-Comunicado-9-2026-ISPC.pdf` — SHA256 `106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973`;original preservado emsource-archive,sem publicação/activação automática.
- `AT-Modelo-B-Geral.pdf` — SHA256 `bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57`;original preservado emsource-archive,sem publicação/activação automática.
- `AT-Modelo-30-ISPC.pdf` — SHA256 `6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c`;original preservado emsource-archive,sem publicação/activação automática.
- `Lei-19-2017-IRPS-BR-OCAM.pdf` — SHA256 `c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d`;original preservado emsource-archive,sem publicação/activação automática.
Uso:comunicadoATindicaB–Geraltransitório;campos correspondidos por quadro. Modelo30aindacontém75.000/3%antigos epermaneceexcluído dos cálculos2026. IRPS57(2k,4)suporta20%sobre rendimentoilíquido de acto isolado qualificado,nãotaxagenérica de compras excedentes. Citações,URLs ehashes completos no recibo ispc-residuals-qa-20261025.json. Scan/vigência global não foram certificados por esta importação privada.
## 25/10/2026 — L5 IRPC:fontes e limites concretos
Reutilizados os inventários de8143ficheiros locais e39formulários/189documentosAT. Código localIRPColectivas.pdféDecreto21/2002,revogadoLei34/2007,nãoaplicado2026. BR252/2022localé3.ºsuplemento turístico;Lei20/2022,p2731identificadaINM,nãoconstadesseexemplar. Sem repetirpesquisa genérica nemexigiroutraaprovaçãodafonte. Lei12/2025 jáaceite fornece62(5)/67(5),PDF19,p2180(19),conferidos visualmente;remissão67(7)→62(6)preservada,nãocorrigidanooriginal. MRFTA19/39AT,p1–2,conferidovisualmenteincluindoinstruções;fichas/códigos/CERnovosficamdelimitados.
- Lei-34-2007-BR52.pdf;SHA256`cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e`;https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei_34_2007.pdf_2063068952.pdf;Art67(3)/68 visually reviewed onPDF19;other text identified.
- Lei-4-2012-BR3.pdf;SHA256`b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121`;https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei-n-4.2012-de-23-de-Janeiro-de-2012.pdf_2063068952.pdf;Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy.
- Lei-19-2013-BR76.pdf;SHA256`bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76`;https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Lei-n_19.2013.pdf_2063068952.pdf;Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy.
- Decreto-9-2008-BR16.pdf;SHA256`96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697`;https://www.dlapiperafrica.com/export/sites/africa/mozambique/insights/legislation-series/tax/downloads/Decreto_9_2008.pdf_2063068952.pdf;Original inventoried/preserved;full article mapping not yet complete,no rate activated from this copy.
- AT-MRFTA-19-39.pdf;SHA256`8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b`;https://www.at.gov.mz/api/webdav?path=%2FFORMULARIOS%2FIMPOSTOS%20FISCAIS%2FIRPS%2FIRPS-IRPC%20MRFTA%20-%2019-39.pdf;MRFTA p1–2 visually reviewed;consultation/preparation,not submission.
Originaisprivadospreservados;sempublicação/activaçãoautomática,semdeclararscanoucertificaçãoefectuados. Lei4/2012,19/2013eRegulamento9/2008foramrecuperados/inventariados;correspondênciaintegralpendente,nãoforamusadosparaactivartaxasantigas. Recibo:irpc-l5-withholdings-qa-20261025.json.
## 25/10/2026 — L5: Lei 20/2022 recuperada e correspondência das taxas
O novo exemplar integral do BR 252/I, de 30/12/2022, foi recuperado em arquivo público do CIP. A Lei 20/2022 consta da primeira página, impressa 2731, conferida visualmente. O ficheiro anterior continua identificado como 3.º suplemento turístico; não foi substituído nem reinterpretado. As 268 páginas do novo original ficam inventariadas e preservadas; o restante PESOE não é usado para activar retenções.
Origem: https://www.cipmoz.org/wp-content/uploads/2023/financas/17F%29%20Lei%2029_2022%20Plano%20Economico%20Social%20Or%C3%A7amento%20do%20Estado%202023.pdf
SHA256: `1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d`. Exemplar: `docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf`. Lei19/2013 PDF2/p682(22) também conferida visualmente:62(3)liberatória20% e62(4)a–d10% específicos. Lei20/2022 mantém62(1/3/4) e termina medidas agrícolas em31/12/2025;Lei12/2025 estabelece62(5)digital/moeda electrónica. A fonte oficial permanece aceite; a nova leitura resolve uma lacuna de texto, sem revalidação genérica. Sem publicação/importação automática ou scan declarado. Recibo: `irpc-l5-grouped-qa-20261025.json`.
## 25/10/2026 — L5 dispensas e convenção PT–MZ
Inventários anteriores reutilizados; inventário completo dos29 originais fiscais em `irpc-l5-reliefs-qa-20261025.json`, incluindo27 anteriores preservados e2 novos. CIRPC Lei34/2007 art68(d/f), PDF19/p768(73), conferido visualmente; listas de alterações Lei4/2012 PDF1 e Lei19/2013 PDF1 não alteram68. Lei20/2022 e Lei12/2025 já correspondidas no recibo agrupado. Sem reutilizar código revogado2002.
CDT PT–MZ, RAR36/1992: original oficial no arquivo do Ministério Público português, arts1/4/12;PDF13–14 conferidas visualmente. Protocolo/RAR36/2009, original DR,PDF1–2/p2752–2753:IRPC/residência e definição12(3);art15 aplicabilidade temporal confrontado. DR apresenta os diplomas em vigor; vigência do Protocolo07/06/2009 documentada na ficha oficial do Ministério Público, efeitos na fonte a partir do ano seguinte. Recorte2026 não estende automaticamente a outras categorias ou tratados. A condição de aplicação12(2) não é confundida com cumprimento de formalidades externas;21-RFI português não imposto em Moçambique.
Novos originais privados preservados, sem publicação/importação automáticas, sem scan ou certificação declarados:
- docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf;SHA256`d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d`;origem:https://dcjri.ministeriopublico.pt/sites/default/files/documentos/instrumentos/rar36-1992.pdf.
- docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf;SHA256`f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b`;origem:https://files.dre.pt/1s/2009/05/08900/0275202756.pdf.
Referências oficiais adicionais: https://diariodarepublica.pt/dr/detalhe/resolucao-assembleia-republica/36-1992-408879 ; https://diariodarepublica.pt/dr/detalhe/resolucao-assembleia-republica/36-2009-607572 ; https://dcjri.ministeriopublico.pt/instrumento/protocolo-entre-republica-portuguesa-e-republica-de-mocambique-que-reve-convencao-para . A aceitação das fontes oficiais permanece, sem revalidação genérica.
## 25/10/2026 — MRFTA e juros compensatórios: correspondência concreta
Reutilizados os29 originais aceites,sem perdas por hash. MRFTA19/39AT,PDF1–2,semAcroForms:quadros1–7 e instruções conferidos visualmente,8/9 reservados. O incremento preenche um mapaHTML correspondente,sem alterar o original ou alegar submissão. Rubricas normais de capitais/prediais e liberatórias IRPC intelectuais/equipamento/capitais/serviços correspondidas pelo nome e natureza;digital/especiais não presumidos. CER permanece dado transcrito com referência,não número de campo da guia antiga.
Decreto9/2008,PDF6/p121,art25(1–3),ePDF8/p123,art35:juros compensatórios e distinção da natureza da retenção. A página oficial BM do Mercado Monetário explica a descontinuidade da MAIBOR em consequência do acordo de17/05/2017. Snapshot integral preservado em `source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html`,SHA256`00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063`. Origem:https://bancomoc.mz/pt/areas-de-actuacao/mercados/mercado-monetario/ . Não usar MIMO ou Prime como sucessor fiscal por inferência. Nenhuma taxa2026 genérica activada;liquidação documentada pode ser transcrita com período/data/prova. Sem nova validação de credibilidade oficial,sem publicação/importação automáticas,sem scan declarado. Inventário completo e hashes no recibo `irpc-juros-mrfta-qa-20261025.json`.
O snapshot HTML é versionado com `-text -diff` no caminho exacto de `.gitattributes`,conservando bytes e espaços do original em vez de normalizar linhas. Hash conferido também contra o blob Git antes de preparar o bundle final.
## 25/10/2026 — dois pontos restantes: parâmetros e correspondências
Reutilizados30originais aceites,sem alteração por hash. O seguimento não carrega taxa fiscal2026 nem novo CER. A aritmética exige fonte/fundamento,janela temporal,base anual e arredondamento explícitos do caso;ensaios usam parâmetros fictícios. Registo de montante liquidado e cálculo por perfil são vias distintas.
Inventário oficial AT189documentos recuperado em `outputs/irpc-interest-cer/at-legislation-inventory.json`,SHA256`d74e764224d97fdea2e6e6e3496614c9b0f94941e8f8757eed8e7847bda9508c`;escopo desta leitura:metadados/títulos,não revisão integral de novos PDFs. URL:https://www.at.gov.mz/api/documents?root=LEGISLACAO . Referências aoDecreto68/2014/desagregaçãoCER identificadas em pesquisa;sem correspondência detalhada aplicável recuperada para activação. Rascunhos sem diploma/número e agregados de receitas não usados como CER MRFTA. Sem revalidação genérica da credibilidade das fontes aceites,sem publicação/importação automática. As lacunas concretas permanecem no recibo `irpc-interest-cer-qa-20261025.json`.
## 25/10/2026 — L6, cadeia do primeiro acréscimo36(1)c
Reutilizados30originais aceites,sem alteração. Conferidos visualmenteLei34/2007PDF6/p768(60) ePDF10/p768(64);Lei4/2012PDF2/p34(5) ePDF3/p34(6);Lei19/2013PDF1/2,p682(21/22). Novo exemplar oficialAT,catálogo19/2009,conserva5páginas do4.ºsuplementoBR36,10/09/2009,incluindoLei20/2009. PDF4/p272(16)confirma36(1)a–i mantidas eaditamentosj–n;fonte original/hash/URL no reciboirpc-l6-adjustments-qa-20261025.json. Correspondência executável limitada36(1)c;demais artigos não declarados implementados. Lei20/2022altera61/62 eLei12/2025altera3/5/20/62/67/75,adita61-A/revogações próprias,conforme provas aceites. Nova consulta responde só à cadeia do acréscimoL6,não às pendênciasL5. Sem publicação/importação documental,scan ou certificação presumidos.
## 25/10/2026 — L6: conferência do recorte até lucro tributável
Sem novos originais:31exemplares da QA664c88c8 preservados por hash. Reutilizada a fonte oficial aceite Lei34/2007, PDF6/p768(60),17/18, e PDF7/p768(61),20/22; Lei20/2009, exemplar oficialAT já arquivado, PDF2/3,p272(14/15), alterações18/20/21/22/24, conferidas visualmente. A cláusula geral de custos indispensáveis e as receitas ordinárias aplicam-se mediante qualificação expressa do caso; não se presume dedutibilidade de todas as linhas de um plano. As demais alterações aceites são reutilizadas no âmbito já documentado. Variações/correcções conhecidas não zero,amortizações e juros financeiros remanescentes não ganham regra neste incremento. A abertura do webdav pela ferramenta web falhou; foi usado o exemplar oficial arquivado exacto, sem reconstrução secundária ou nova validação genérica. Nenhuma pesquisa das pendênciasL5 foi reaberta.
## 25/10/2026 — L6:deduções/perdas para matéria colectável
Reutilizados31originais sem alteração por hash. Lei34/2007PDF5/p768(59),15(1)a/15(2–4),ePDF12/p768(66),41(1–7),conferidos visualmente. Art15 distingue perdas/benefícios à base de outras fases;41 estabelece cinco exercícios posteriores e restrições concretas. O recorte suporta apenas exercícios anuais ordinários/perdas próprias do regime geral;períodos curtos41(5),restrições especiais41(4/6),métodos indirectos e transferências41-A conservam correspondência específica. Listas de alterações aceites reutilizadas;Lei20/2009adita41-A,não activa transmissão de perdas nesta entrega. Não inferir ordemFIFO,percentagem de dedução ou benefício positivo de valor digitado. Sem pesquisa/revalidação genérica das dúvidasL5 e sem novo original/importação/publicação.
## 25/10/2026 — L6:taxa geral para a colecta normal2026
Sem novos originais:31exemplares preservados por hash. Conferidos visualmenteCIRPC Lei34/2007PDF17/p768(71),61(1),taxa geral32%;Lei20/2022PDF1/p2731,61(1)mantido e61(2)temporário;Lei12/2025PDF18/p2180(18),lista de alterações,ePDF20/p2180(20),61-A/vigência. A alteração61(2)daLei4/2012 já aceite é reutilizada. Índice primárioINM confirmaLei20/2022,artigos61/62,p2731. Não se transportam medidas expiradas,casos autónomos ou taxas de retenção para a colecta normal. Enquadramento do caso/ano é expresso;nenhum aprovador ou revalidação genérica criado. Sem pesquisa das pendênciasL5. Retenções/pagamentos/créditos anuais permanecemL8.
@@ -2522,7 +2522,7 @@ As estimativas são **horas de trabalho técnico**, não calendário nem mediç
| L3 — IVA: saldo e fecho do Modelo A | Totais14–18 quando todas as parcelas estão determinadas | Campos19–27 aplicáveis, transporte de crédito, rectificações/substituição, imposto a entregar e pedido de reembolso; estados documentados e relação com tesouraria; via de restituição de bebidas13(2), identificada porG4D e ainda não apurada, conforme procedimento próprio | Execuções mensais, parcelas L1/L2, documentos e histórico | L1/L2 para apuramento integral; saldo anterior identificado e procedimento de reembolso aplicável. Pedido não significa deferimento/recebimento | 48–80 h |
| L4 — ISPC: elegibilidade e apuramento | Campos de enquadramento e motor genérico | Regime/actividade/volume elegível, opções/exclusões, escalões/taxas aplicáveis, mínimo, trimestre e retenções específicas; comparação só entre regimes admissíveis | Vendas por actividade, custos, NUIT, natureza jurídica e residência confirmada | Lei9/2025 e regulamentação/período; distinguir receita anual, trimestre e excesso | 40–64 h |
| L5 — retenções IRPC e guias | Documentos de compras/vendas e guia M/39 como exemplar | Rendimento pago/recebido, entidade que retém, residente/não residente/EP, evento temporal, excepções e casos digitais/e-money; guia e comprovativo ligados à operação | Contrapartes, facturas, pagamentos, período, moeda, oportunidade | Artigos aplicáveis por rendimento, taxa/convenção se invocada; corrigir remissões do exemplar. Sem submissão electrónica AT presumida | 32–56 h |
| L6 — IRPC anual: regime normal | Projecções, resultados financeiros, activos e custos | Ponte resultado contabilístico→matéria colectável, custos admitidos/não admitidos, amortizações, perdas fiscais e colecta; correspondência M/20/M/22 | Plano financeiro e dados comuns; L5 para retenções sofridas | Código IRPC e Lei12/2025; exercício fiscal, residência/EP, saldos/perdas com ano e prova; resolver diferenças PDF/XLSX | 48–80 h |
| L6 — IRPC anual: regime normal | Disponível2f684e59:resultado financeiro→ajustamentos demonstrados→lucro6700→base4400→colecta1408,com provas/persistência/histórico | Saldo concreto:outros ajustamentos ordinários,juros financeiros,amortizações,variações/periodização,perda actual,âmbitos normais adicionais,representação fiscal e correspondênciaM20/M22;ver secção «saldo concreto deL6» | Plano financeiro,dados comuns,activos/livros e histórico;retenções/pagamentos/créditos anuais reservadosL8 | CódigoIRPC/período/caso;benefícios e tratamentos especiais anuaisL7;sem dependência genérica do fechoL8 | Estimativa inicial48–80h;saldo não reestimado |
| L7 — IRPC: tratamentos específicos | Contexto sectorial/territorial e fontes cadastradas | Casos identificados: tributação autónoma de despesas e mais-valias, taxas reduzidas/cooperativas, isenções/benefícios e operações especiais com condições rastreadas | Base L6, despesas, activos, relação territorial documentada | Disposição e período por tratamento; localização por si só não concede benefício. Lista de tratamentos aplicáveis explicitada no lote | 48–80 h |
| L8 — IRPC: liquidação e pagamentos | Parcelas L5–L7 e formulários originais | PPC/PEC, deduções/créditos, dupla tributação quando aplicável, saldo anual a pagar/recuperar; calendário e reconciliação com pagamentos | Retenções, colecta, saldos anteriores, pagamentos/comprovativos | Base anterior para PPC/PEC, regras de limitação/transporte; não usar cinco anos ou compensação automática sem cotejo específico | 32–56 h |
| L9 — INSS: contribuição social | Massa salarial agregada e referência TCO3%+4% | Trabalhadores, remuneração/base contributiva, exclusões, empregador/trabalhador, TCO/TCP, declaração e encargos por período | Equipa/custos, entidade e calendário; cadastro de pessoa partilhado com L10 | Regulamento e alterações aplicáveis, natureza do vínculo; confirmar base antes da taxa. Contribuição social, distinta dos impostos | 24–40 h |
@@ -5754,3 +5754,324 @@ A identificação do exemplar e o critério deaceitação já foram definidos pe
DecisãoTempo:P001ficaresidual,provaspreservadasesematribuiçãoautomática06;retomaapenascomesclarecimentoconcretonovo.P058mantémâmbitoparcialdisponíveleexclusõesidentificadas.P084/P085mantêmfechooperacional.Avance:coberturaadicionalL3b189d0faQA,conferirapenasofaltanteepreparentregacompatível;reconciliarsaldoL3edepoisL4ISPCconformeplanoexistente.Semrepetirpesquisa/testesdosmesmospontossemnovainformação.Limitaçõesvisíveisnãoimpedempercursosindependentes.
CandidataisoladaemC:/laragon/www/portal-investidor-l3-qa-20261025,ramoscodex/l3-additional-delivery-20261025,baseb189d0fa/7ad187f9;provas43frontend/API1-105reutilizadas,nova conferência apenas dehashes,compatibilidadeecompilação. Preparação nãoéinstalação;execuçãoexigecomparaçãoautenticadaebackup/restauro fresco.
CandidataL3preparada:`0f4df8a4`,ramo`codex/l3-additional-delivery-20261025`. Buildetipos passaram;12ficheirosdedelta(10funcionaisjáaceites+2textosdelimitaçãoP001),7marcadorescompilados,schemas/PHP/configurações/dependênciassemalterações. Main/manifestopúblicoconferidosem7ad187f9;simuladorHTTP200. Scriptsprivadosdepreflight,backup/restauro,conferênciaprotegidaepúblicapreparadoscomguardasdenovoestado. Nenhumteste funcionalrepetido,nenhumaescritaactiva. Próximaexecuçãodaentrega:comparaçãoautenticadafresca,backup/restaurorealeconferênciadodelta. Não declararinstaladopelapreparação.
## 25/10/2026 — inícioL4-AISPCdepoisdapreparaçãoL3
L3candidata0f4df8a4preparada,provasaceitesreutilizadas;entregaefectivaexigepreflightautenticadoebackup/restaurofresco. SaldoL3mantémregularizaçõessequenciais/estornos,apuramentospróprios eformalidadesC/D/E;limitecontacentralATnãoénovacondiçãoorganizacional. NenhumresidualP001/P058bloqueiaL4.131fechosL1eP084/P085preservadosantesdosnovostestes. Acervofiscal/legislação/anexosacessíveisinventariadosemoutputs/ispc-l4a-20261025/preservation-before-tests.json.
L4-Aprimeiroincremento:enquadramentoelegibilidade2026,MZN,territórionacional,tipodepessoa,actividade,referênciaanual/prévisão,incompatibilidadesarts2–5,opçãoseparada.Reutilizarcamposválidosepreservarediçõesdeliberadas. Lei9/2025republicadaéfonteaceite;nenhumaaprovaçãogenéricaFiscalistaécriadacomoetapa. Apuramentotrimestral,escalões/excesso,mínimo/retençõeseformalidadescontinuamtrabalhopróprioL4seguinte;nenhumimpostocalculadoouregimeadoptadopelainventariação.
## 25/10/2026 — L4-A ISPC: primeiro incremento QA
Implementado enquadramento preliminar2026/MZN da actividade habitual pelos arts2–5 da Lei9/2025: referência anterior2025 ou previsão de início2026,limite4.000.000 inclusivo,incompatibilidades e dados concretos em falta. Regra183dias restrita aos serviços8(1)c. Opção permanece separada;seleccionarISPC não adopta regime. Perfil reutilizado com prévia e confirmação das divergências,edições deliberadas e outros livros preservados. Livro por contexto e histórico integrado no relatório existente.
Provas novas:12testesfrontend,tipos/build exit0. Não foram repetidos os testes aceites deL1/L2/L3/P001. Serialização/recuperação cobertas nos novos testes;transporte privado existente reutilizado. Demonstração visual integrada e gravação privada deste incremento continuam antes de propor entregaL4;nenhuma escrita activa. Recibo:ispc-l4a-eligibility-qa-20261025.json.
L4 continua aberto:apuramento trimestral,escalões e actividades mistas/excesso,mínimo500,retenção5%,percurso ocasional e formalidades próprias. As correspondências concretas serão tratadas no incremento seguinte,sem aprovação jurídica genérica ou bloqueio pelos residuaisP001/P058. L3 permanece aberto com candidata0f4df8a4 preparada e execução autenticada/backup-restauro por realizar. P084/P085 fechados;estatísticas/IA adiadas.
## 25/10/2026 — L4 ISPC: apuramento trimestral e percurso demonstrado em QA
O enquadramento e a opção guardados alimentam o apuramento trimestral de 2026 em MZN. O volume anual de acesso anterior, o volume anual do escalão e a base trimestral são distintos. Calculam-se as taxas de 3/4/5%, os serviços a 12/15%, a cumulação pela taxa maior e o excesso a 20%, com valores racionais exactos. O acumulado anterior impede repetir o excesso. O ano encerrado reconcilia os quatro trimestres; uma previsão permanece cenário. A prestação inferior a 500 MZN dispensa pagamento e conserva a declaração; exactamente 500 MZN mantém pagamento. A retenção de 5% nas aquisições ocasionais do artigo 12(3–4) tem livro e limite global de 2.500.000 MZN próprios, sem reduzir o imposto do adquirente.
Percurso demonstrado com componentes reais: elegibilidade/opção → cálculo → gravação → recuperação → relatório financeiro. Exemplo do T2: base de 200.000 MZN, taxa de 12%, imposto/prestação de 24.000 MZN e opção documentada em 01/01/2026. A API privada em QA passou 1 teste com 21 asserções, rollback e recusa de acesso a outra conta (404); os livros anteriores foram preservados exactamente. Passaram 13 testes novos (10 trimestrais e 3 de retenção), tipos e compilação. As fontes, provas aceites de L1/L2/L3/P001 e os 12 testes de L4-A foram reutilizados. Recibo: ispc-l4-quarterly-qa-20261025.json; provas: outputs/ispc-l4b-20261025.
O âmbito habitual trimestral está demonstrado em QA, ainda não instalado. O saldo de L4 fica delimitado às operações ocasionais próprias do artigo 3(3–4), às aquisições acima do limite global e à correspondência de formulários, instruções e regulamentação de 2026. O aviso primário do Governo sobre a aprovação de novo regulamento não fornece o articulado nem o modelo. Não se inventam formulários, prazos ou aprovadores; essas dependências não bloqueiam o cálculo habitual demonstrado. P001/P058 permanecem residuais e não interrompem a sequência; P084/P085 permanecem fechados.
## 25/10/2026 — entrega adicional de L3 com preservação conferida
O incremento de `0f4df8a4` foi instalado em `fa32a2b9`. Este descendente altera apenas a asserção de texto de um teste legado para o estado residual de P001 acordado; os cálculos e os 12 ficheiros runtime preparados mantêm os mesmos hashes. A referência de entrega conserva o candidato original e a correcção de compatibilidade. Backup fresco de 174 tabelas e 369 ficheiros, restauro isolado sem rede e comparação protegida com a mesma identidade confirmados. Nenhuma migração, importação de conteúdo ou alteração das 172 tabelas de negócio foi efectuada. Revisão/manifesto, sete marcadores compilados e simulador HTTP200 conferidos. As diferenças em cache correspondem ao reinício da fila e ao par contador/temporizador de limitação de pedidos; as sessões novas são anónimas e têm o agente das verificações de entrega.
A falta de espaço foi resolvida pela compactação verificada das dependências de construção de 11 versões antigas, conservadas em arquivo com hashes, ficheiros e ligações conferidos. A versão activa e a anterior não foram compactadas. Originais, código, backups, dados e recibos permaneceram disponíveis. O processo Git existente executou os seus controlos obrigatórios; não houve nova ronda manual dos casos funcionais aceites.
L3 continua aberto para regularizações sequenciais/reversões, apuramentos próprios de fornecimento/margem/viagens/eventos e formalidades C/D/E. Apenas esses casos dependentes ficam limitados. Preservam-se 16 MZN de IVA documental, zero de dedução nesta via, 12 reconhecidos, 7 recebidos e 5 por receber. P001 residual, P058 parcial e P084/P085 fechados mantêm os seus estados. L4 habitual trimestral está demonstrado em QA e não foi instalado. Recibo: l3-additional-delivery-20261025.json.
## 25/10/2026 — preparação Git da entrega L4 trimestral habitual
O candidato `6af7092e` foi preparado e publicado apenas no ramo `codex/ispc-l4-quarterly-qa-20261025`, sobre L3 instalado em `fa32a2b9`. O ramo principal e a revisão pública foram conferidos nesta base e não foram alterados. O bundle foi verificado. A comparação identificou nove ficheiros de aplicação: as três integrações existentes receberam apenas adições (6+6+1 linhas); onze ficheiros próprios de L3 e dezassete originais permanecem exactamente iguais. Os cinco marcadores compilados de L4 e os sete de L3 estão presentes. Não há delta de schema, PHP de aplicação, configuração ou dependências; o PHP acrescentado é apenas teste QA. O código experimental de P001 ficou excluído.
As provas QA aceites de cálculo, gravação privada, recuperação e relatório, assim como tipos e compilação da composição compatível, foram reutilizadas pelos respectivos hashes. Não houve nova ronda funcional. Prepararam-se os scripts guardados de comparação autenticada, backup, restauro isolado, integração Git sem force-push e conferência pública/protegida. Backup/restauro fresco e conferência de espaço continuam necessários na execução; o backup de L3 não foi apresentado como backup novo de L4. Esta preparação não instalou L4 nem alterou dados activos. Recibo: `ispc-l4-prepared-delivery-20261025.json`; pacote: `outputs/ispc-l4-delivery-20261025`.
L4 não fica integralmente concluído. Operações ocasionais próprias, aquisições acima do limite e formalidades de 2026 conservam os âmbitos e condições concretas registados. L3 mantém o saldo residual e a separação de 16 MZN documentais, zero de dedução nesta via, 12 reconhecidos, 7 recebidos e 5 por receber. P001/P058 aguardam os esclarecimentos previstos sem bloquear a entrega; P084/P085 permanecem fechados. Estatísticas e IA permanecem adiadas.
## 25/10/2026 — instalação do âmbito ISPC trimestral habitual
O candidato `6af7092e` foi integrado pelo Git e instalado sobre `fa32a2b9`. Foram conferidos backup/restauro fresco e isolado, nove ficheiros de aplicação de L4, onze ficheiros de L3 sem alteração, dezassete originais e os doze marcadores compilados de L4/L3. Os ficheiros persistentes e a configuração conservam os hashes do backup; as tabelas de negócio foram comparadas com a mesma identidade e contexto, sem inferir perda a partir de RLS. Diferenças operacionais de cache/sessões ficam explicitadas no recibo. Não houve migrações ou importações de conteúdo. As provas QA aceites foram reutilizadas; apenas os controlos obrigatórios do processo Git existente voltaram a executar, sem nova ronda manual.
Para assegurar espaço, dependências de construção de versões antigas foram compactadas em arquivo e verificadas antes de libertar a cópia descompactada. Versões activa e anterior, dados, originais, configurações e backups foram preservados. O recibo discrimina o arquivo e os respectivos controlos.
A equipa pode avaliar no portal o percurso habitual: elegibilidade/opção → cálculo trimestral → gravação → recuperação → relatório. O exemplo demonstrado mantém base de 200.000 MZN, taxa de 12% e imposto/prestação de 24.000 MZN. O ISPC não é apresentado como integralmente concluído: operações ocasionais próprias, aquisições acima do limite e formalidades de 2026 permanecem discriminadas. L3 e os seus residuais ficam preservados, incluindo 16 MZN documentais, zero de dedução nesta via, 12 reconhecidos, 7 recebidos e 5 por receber. P001/P058 aguardam os esclarecimentos previstos sem bloquear a sequência; P084/P085 permanecem fechados. Estatísticas e IA continuam adiadas. Recibo: `ispc-l4-delivery-20261025.json`.
## 25/10/2026 — inventário anterior ao delta residual ISPC
Antes dos testes novos, foram recuperadas as provas do percurso habitual instalado em6af7092e, L3 e os131fechos deL1; não há perdas confirmadas. P001/P058 eP084/P085 mantêm estados. O inventário local anterior foi reutilizado e os novos directórios oficiais daAT foram inventariados antes da selecção. O delta QA separa operações ocasionais próprias, cálculo das aquisições acima do limite e formalidades externas. Fontes novas: comunicadoAT9/2026 e exemplares B–Geral/Modelo30; republicaçãoIRPS19/2017 para incidência de actos isolados e taxa57(2)k, sem nova validação genérica. Não há alteração activa.
## 25/10/2026 — residuais ISPC agrupados em QA
Os três pontos foram tratados num delta compatível sobre o instalado `6af7092e`. Nas operações ocasionais próprias, o percurso distingue pessoa singular sem actividade habitual, acto imprevisível/não reiterado, operação nacional e famílias do artigo3(4); a correspondência positiva IRPS8(3h,4)/9 está identificada. A liquidação própria ISPC é separada da retenção liberatória comprovada: esta não gera segunda liquidação nem crédito duplicado. O exemplo próprio de100.000MZN a3%produz3.000MZN, mantendo opção documentada e pressupostos de projecção distintos.
Nas aquisições, acumulado de2.400.000MZN mais aquisição de200.000MZN separa100.000até ao limite e100.000excedentes. A primeira parcela conserva5.000MZN a5%. A parcela excedente não adquire taxa apenas pela ultrapassagem: o caso positivo implementado é acto isoladoIRPS57(2k), sem opçãoISPCaplicável e com rendimento ilíquido identificado, produzindo20.000MZN. As retenções são distintas e não reduzem o imposto próprio do adquirente. Enquadramento desconhecido ou fornecedor com opçãoISPC não recebem automaticamente5%ou20%. Vendedor/contexto376 e adquirente/contexto375 foram demonstrados separadamente.
As formalidades apoiam-se agora no ComunicadoAT9/2026 e no original B–Geral de duas páginas. Foram preparados os quadros1/2/3/5/6/8/10 e exportaçãoHTML, com identificadores de campo próprios de cada quadro; o Modelo30 ainda com75.000/3%antigos foi preservado e excluído do cálculo2026. O mês do período não é copiado do mês de pagamento. Submissão, recepção e pagamento ficam como actos externos declarados, com referências e histórico, sem os executar ou certificar.
O saldo separa cálculos de formalidades: juros compensatórios continuam sem fórmula por falta de regra/taxa/base/período aplicáveis; só montante documentado é conservado. Outros enquadramentos da parcela excedente exigem os seus dados e regra próprios, sem taxa genérica. Externamente faltam a correspondência concreta do período do quadro2, o modelo/código de entrega das retençõesISPC/IRPS e as instruções específicas2026 ainda não fornecidas. Identidade/NUIT/endereço/juros do caso sintético são dados da operação, não condição nova de acesso ao cálculo. Nenhuma dessas pendências bloqueia os casos positivos implementados.
Provas do delta:19testes novos distintos, APIprivadaQA1/22 comrollback, tipos e compilação, componentes reais com gravação/recuperação/relatório e preparaçãoHTML. O percurso habitual não foi recalculado: motores trimestral e de retenção existentes estão inalterados; o resultado de24.000MZN foi preservado exactamente. Conferiu-se apenas a visibilidade afectada: no modo ocasional os controlos habituais/do adquirente ficam ocultos com explicação e histórico; no contexto habitual continuam disponíveis. L3,17originais anteriores e131fechosL1foram preservados;P001/P058nãointerrompem eP084/P085permanecemfechados. QA não é instalação nem fecho integralISPC. Recibo:`ispc-residuals-qa-20261025.json`.
Na representação do B–Geral, a dispensa inferior a500MZN permanece uma correspondência formal específica: imposto calculado e prestação zero são mostrados separadamente, sem preencher o montante apurado como zero. O código não inventa a instrução de preenchimento. Este ponto não altera nem bloqueia o cálculo10-Ajá demonstrado.
Uma retenção liberatória documentada na mesma operação permanece no histórico e impede nova prestação própria sem referência concreta de correcção; mudar apenas a opção de liquidação não apaga o benefício anterior. Caso dirigido adicional aceite.
## 25/10/2026 — entrega conjunta dos residuais ISPC demonstrados
Instalado `5c0cb25c` pelo Git sobre `6af7092e`, com backup/restauro fresco isolado, conferência dos sete ficheiros afectados, dos ficheiros de preservação habitual/L3, de21originais, dos ficheiros persistentes/configuração e das tabelas com identidade equivalente. As provas funcionais aceites foram reutilizadas; apenas o processo Git existente executou os seus controlos obrigatórios. Sem migrações ou importações. Diferenças operacionais de cache/sessões estão delimitadas no recibo `ispc-residual-delivery-20261025.json`.
Disponível: operações ocasionais próprias no âmbito demonstrado, parcela excedente no caso IRPS qualificado e preparação/exportação B–Geral. A retenção liberatória anterior não é apagada ao mudar o percurso. Ainda por concluir: fórmula de juros, outros enquadramentos do excedente e correspondências/instruções de preenchimento2026 identificadas no recibo. Actos da AT permanecem externos: exportar não submete nem obtém aceitação. Este incremento não conclui todo o ISPC nem o IRPS. O habitual e L3 permanecem preservados, incluindo16documentais/0dedução nesta via/12reconhecidos/7recebidos/5por receber. P001/P058não bloqueiam;P084/P085fechados;estatísticas/IAadiadas.
## 25/10/2026 — inventário anterior a L5
Recuperadas as provas aceites de L3, ISPC instalado5c0cb25c e131fechosL1. Sem perdas confirmadas. IRPS continua limitado ao caso demonstrado; residuaisISPC não bloqueiam retençõesIRPC independentes. Acervo anterior inventariado é reutilizado antes da selecção; contrapartes/documentos/pagamentos serão ligados aos livros existentes sem os duplicar ou apagar. Não houve testes novos nem alteração activa neste inventário.
## 25/10/2026 — L5: primeiro incremento executável em QA
Preparado sobre o instalado `5c0cb25c`, com livros de retenções por contexto. Reutiliza fornecedores, documentos e linhas de aquisições e operações de venda existentes. As vendas não têm um cadastro próprio de contraparte: esse dado permanece por completar, sem ser inferido da localização. As edições deliberadas são conservadas; uma alteração na origem mostra os valores divergentes e permite reconciliar o vínculo sem sobrescrever essas edições.
O cálculo implementado corresponde aos 10% da Lei 12/2025 para bens e serviços digitais e comissões de agentes de moeda electrónica, no recorte não residente e não imputável a estabelecimento estável. Exige a qualificação do titular e devedor como sujeitos a IRPC, a incidência moçambicana e os factos ou pressupostos aplicáveis, sem convenção ou dispensa invocada. A data resulta dos eventos aplicáveis do artigo 67(5), incluindo o reconhecimento do custo; um pagamento posterior não desloca o evento anterior para outro período. A base do rendimento fica separada do IVA.
No exemplo sintético de rendimento pago, 100.000 MZN produzem retenção de 10.000 MZN; a entrega associada é de 6.000 MZN e o saldo por reconciliar é de 4.000 MZN. No exemplo de retenção sofrida, o cálculo é de 2.000 MZN, com comprovativo de 1.500 MZN e diferença de 500 MZN, sem crédito anual automático. Um comprovativo pode ser repartido entre operações e contextos, sem exceder o montante disponível. Alterações em contextos sem pagamentos partilhados não desactualizam o resultado. Pagamentos de IVA mantêm os vínculos anteriores.
O MRFTA 19/39 da AT foi conferido nas duas páginas, incluindo as instruções. O quadro 1 identifica retenção, o quadro 2 corresponde a um mês/ano único e o quadro 7 contém base, taxa e imposto. O CER e a correspondência das novas categorias digitais permanecem por esclarecer. A Lei 12/2025 contém uma remissão concreta do artigo 67(7) para 62(6), enquanto a nova taxa aparece em 62(5): essa diferença é preservada, sem renumerar o original ou bloquear o cálculo independente. As instruções do exemplar indicam o prazo nominal de dia 20 do mês seguinte à dedução; não foram presumidos ajustes de calendário, prorrogações ou instruções específicas de 2026. A exportação é um mapa de preparação, sem assinatura, submissão, recepção ou aceitação AT.
**Saldo de L5:** correspondência das taxas normais e especiais dos artigos 62(1–4), dispensas para residentes/EP, convenções invocadas, conversão cambial, juros, rectificações e guia agregada. A Lei 20/2022 está identificada pela INM na página 2731 do BR 252, mas o exemplar local com essa data/número contém apenas o 3.º suplemento turístico. A ausência desse texto específico não é um pedido de revalidação da sua credibilidade. O código local de 2002 foi identificado como revogado e não foi usado em cálculos de 2026. Cada lacuna afecta apenas o ramo dependente, sem taxa ou zero genéricos.
Provas do delta: 17 testes novos distintos; API privada em QA, 1 teste e 23 verificações com rollback; tipos e compilação; componente real com cálculo, gravação, recuperação, relatório, exportação e reutilização de uma aquisição anterior. A demonstração visual local em ficheiro é distinguida da prova da API privada. O controlo adicional de pagamentos partilhados foi conferido por caso dirigido, sem repetir as provas funcionais anteriores.
L3 e ISPC permanecem preservados, assim como os 21 originais anteriores e os 131 fechos de L1. Os residuais ISPC ficam na mesma matriz; o IRPS conserva apenas o caso anteriormente demonstrado. P001/P058 não bloqueiam e P084/P085 permanecem fechados. Estatísticas e IA continuam adiadas. L5, IRPC e IRPS não estão integralmente concluídos. Não houve instalação, migração, importação ou alteração activa. Recibo: `irpc-l5-withholdings-qa-20261025.json`.
## 25/10/2026 — inventário anterior ao agrupamento de L5
Recuperadas as provas aceites de `da0d8abb`, L3, ISPC instalado `5c0cb25c` e 131 fechos de L1. Sem perdas confirmadas. O selector cambial, a conversão e os históricos entregues foram identificados por hash antes do novo delta e serão reutilizados. O novo exemplar integral do BR 252/2022 contém a Lei 20/2022 na primeira página; as 268 páginas ficam preservadas e inventariadas, sem activar outras regras do PESOE. Dispensas, convenções, juros e MRFTA permanecem discriminados. Nenhum teste novo ou alteração activa neste inventário.
## 25/10/2026 — L5: agrupamento de taxas e reutilização do câmbio entregue
O conjunto preparado inclui `da0d8abb` e os novos enquadramentos compatíveis, sem instalar no portal. A Lei 20/2022 foi recuperada no exemplar completo do BR 252/I, página 2731, resolvendo a falta de texto que impedia o cotejo anterior. O original antigo, com o 3.º suplemento turístico, permanece identificado e preservado. Não se repetem pesquisas ou validações genéricas sem nova evidência.
Foram acrescentados os ramos qualificados de 20% para royalties, equipamentos, serviços e capitais não cotados de não residentes; royalties de residentes e rendas comuns conservam a natureza por conta quando aplicável. Os ramos dependentes das dispensas ficam separados. Os juros de bilhetes do Tesouro/dívida cotada e permutas de liquidez qualificadas de entidades com sede e direcção efectiva nacionais têm retenção liberatória de 20% pelo artigo 62(3), sem crédito anual automático.
As taxas especiais de 10% do artigo 62(4) ficam limitadas às condições demonstradas: telecomunicações, transportes internacionais, equipamentos conexos, manutenção/fretamento de aeronaves, infraestruturas eléctricas em projectos públicos de electrificação rural, afretamento marítimo de pesca/cabotagem e outros títulos cotados na Bolsa de Valores de Moçambique, com a exclusão da dívida/bilhetes abrangidos pelo número 3(a). Não se confundem com a taxa digital do número 5. Os benefícios agrícolas com termo em 31/12/2025 não foram transportados para 2026.
O câmbio reutiliza, sem alteração, `SimulationFxSelection`, `selectFx`, `fxSelectionKey` e `convertCents`. O adaptador de retenções liga a selecção existente à base ou ao comprovativo de retenção sofrida. Conserva montante/moeda originais, boletim, coluna, sentido e data; não usa taxa actual nem calcula uma média própria. A data cambial fica distinta do evento do artigo 67(5). Uma confirmação sem alteração conserva o vínculo à origem; uma edição deliberada passa a selecção para o controlo dessa linha, mantendo o histórico anterior. Uma origem alterada torna visível a divergência apenas nos resultados dependentes.
Exemplo de royalty: 1.000 USD, com taxa sintética 64 MZN/USD, produzem base de 64.000 MZN e retenção de 12.800 MZN a 20%; comprovativo AT de 5.000 MZN deixa 7.800 MZN por reconciliar. No exemplo de retenção sofrida, a base de 100 USD converte para 6.400 MZN, o imposto é de 1.280 MZN e o comprovativo de 10 USD corresponde a 640 MZN, com diferença de 640 MZN. A conversão não transforma o pagamento ao beneficiário em entrega à AT; esta conserva o montante MZN efectivamente documentado. Pagamentos e parcelas continuam ligados e não podem ser usados além do montante disponível, incluindo entre contextos.
Passaram 19 testes novos distintos, com casos dirigidos para natureza dos capitais, relatório e vínculo cambial; os 17 testes anteriores de L5 não foram repetidos. A API privada em QA passou 1 teste e 34 verificações com rollback e guardas contra a base activa. Tipos, compilação, conferência do selector existente dentro da retenção, cálculo, gravação, recuperação, relatório e exportação foram demonstrados. A página visual sintética grava apenas um ficheiro local; a prova da API privada é separada. Os resultados aceites de `da0d8abb` permanecem actuais quando não afectados e foram preservados no histórico do conjunto.
Permanecem separados: dispensas e casos residentes/EP que delas dependem, convenções invocadas, categorias/devedores/períodos fora deste recorte, juros, rectificações e correspondências/CER do MRFTA. Cada pendência identifica os dados e a condição de resolução no recibo `irpc-l5-grouped-qa-20261025.json`; não bloqueia casos independentes. Exportar a preparação não submete nem obtém aceitação AT. L5, IRPC e IRPS não estão integralmente concluídos.
O portal mantém `5c0cb25c`, com L3 e ISPC preservados. O saldo ISPC continua na mesma matriz e o IRPS conserva o caso anteriormente demonstrado. P001/P058 não bloqueiam; P084/P085 permanecem fechados; estatísticas e IA continuam adiadas. Foram conservados os 26 originais anteriores e acrescentado um novo original. A instalação futura exige a comparação autenticada do destino, backup/restauro fresco e conferência do delta pelo procedimento Git existente, sem repetir provas aceites.
## 25/10/2026 — L5: dispensas e convenção demonstradas em QA
Base de código `2b33a1c3`, ramo `codex/irpc-l5-reliefs-qa-20261025`. O último relatório de instalação mantém o portal nessa entrega; este candidato não executa instalação. O inventário anterior de L3, ISPC, câmbio, fontes e provas aceites é reutilizado. Comparação do delta: sem alteração nesses módulos, em schema/migrações, configuração ou permissões; sem escrita na base activa. As correcções de codificação que tinham atingido trechos históricos durante a preparação foram retiradas do delta; os registos anteriores são conservados.
**Executável:** dispensa 68(d) para serviços/uso de equipamento 67(1)b/g com natureza por conta, titular sujeito a IRPC relativamente ao rendimento; dispensa 68(f) para rendas de sociedade de gestão de imóveis próprios fora da transparência fiscal 6(1)c; limite convencional de 10% sobre royalties/uso de equipamento qualificados PT–MZ, não digitais, titular residente convencional em Portugal, beneficiário efectivo, sem EP em Moçambique, devedor residente em Moçambique e montante sem excesso por relações especiais. As condições são dados documentados do caso, sem aprovador adicional. A selecção de regra não é substituída por texto livre ou taxa manual. Outros ramos continuam separados.
Reutilizados contraparte, residência/EP, documento, qualificação, montante e conversão da linha. Diploma, artigo, período, documentos e condições ficam no mesmo livro e no histórico. Alterar a prova invalida apenas a correspondência do resultado afectado. A dispensa produz retenção zero justificada, apresentada como dispensa, sem isentar o rendimento nem gerar crédito anual. Informação insuficiente, negativa, período incompatível ou artigo divergente fica indeterminada, sem zero/taxa reduzida presumidos. A existência de prova de entrega numa linha dispensada pede reconciliação sem apagar o pagamento.
**Demonstração:** Wayfinder `wayfinder:generate --with-form`, pelo wrapper QA guardado `tools/irpc-reliefs-qa.php routes`; TypeScript passou; compilação completa QA passou. Nove testes novos e cinco verificações dirigidas de compatibilidade IRPC passaram. API privada: um teste/17 verificações, base `simulator_fiscal_delta_20261021_test`, loopback55441, transacção com rollback. Resultados 68(d),68(f), convenção e informação insuficiente recuperados com documentos/histórico. Relatório de retenções, exportação de preparação e dossier financeiro conferidos a partir da recuperação da API. Corrigida a associação da secção «IRPC — retenções» à secção financeira do dossier: a linha existia, mas era omitida nessa apresentação. UI sintética do componente real demonstra cálculo, gravação/recuperação local e relatório; esta prova local é distinta da API privada.
**Reprodução:** gerar routes/actions com `php tools/irpc-reliefs-qa.php routes`; executar `node --test tests/frontend/irpc-reliefs.test.mjs` (produz a amostra sintética); executar `php tools/irpc-reliefs-qa.php test`. Usar PHP8.5/Node24 e dependências existentes. `tsc --noEmit`; compilação `INVESTMOZ_QA_BUILD=1 vp build` no ramo QA. Os módulos gerados são artefactos locais, sem edição manual ou commit.
**Saldo na mesma matriz:** restantes alíneas68, categorias digitais/residentes não correspondidas, outras convenções/Estados e casos com EP, dividendos/juros ou excesso por relações especiais mantêm correspondência própria. Juros de mora, rectificações, agregação, rubricas/CER e preenchimento do MRFTA permanecem discriminados. O cálculo convencional não declara cumpridas as formalidades de accionamento, recepção ou aceitação AT. Não são transportados formulários portugueses21-RFI para obrigações moçambicanas. Pendências condicionam apenas os casos dependentes. L5, IRPC e IRPS não estão integralmente concluídos. L3/ISPC/câmbio não foram retestados; as suas provas são reutilizadas. Entrega conjunta preparada apenas para os recortes demonstrados. Instalação futura segue o procedimento Git e os controlos de destino/backup/restauro já existentes.
Recibo: `docs/investmoz/simulations/irpc-l5-reliefs-qa-20261025.json`; provas locais em `outputs/irpc-reliefs/`.
## 25/10/2026 — dispensas IRPC e convenção PT–MZ instaladas pelo Git
Instalada `ce746d88`, com `2b33a1c3` preservada como release anterior. Backup fresco2026-10-25T18:00:39Z:174 tabelas e369 ficheiros/configuração;restauro isolado em contentor sem rede/55441 passou. Quatro ficheiros de execução conferidos,28 protegidos L3/ISPC/câmbio e29 originais preservados. Schema,permissões e configuração iguais;zero migrações/importações. As172 tabelas de negócio mantêm checksums;apenas cache operacional e sessões anónimas das verificações foram reconciliadas. O mínimo de espaço do instalador foi reposto pelo arquivo e verificação de dependências de5 releases antigas,sem tocar na actual/anterior nem apagar dados/backups.
Manifesto público/revisão servida,8marcadores compilados e simuladorHTTP200 conferidos. Provas QA aceites reutilizadas;CI habitual do procedimento Git passou. Sem ampliar a cobertura:68(d/f) e royalties/uso de equipamento PT–MZ nos casos efectivamente demonstrados. Juros,MRFTA e restantes casos continuam na mesma matriz;L5 permanece parcial. Seguimento em QA separado,sem instalar novos cálculos. Recibo:`irpc-l5-reliefs-delivery-20261025.json`.
## 25/10/2026 — juros e preenchimento MRFTA: incremento QA após ce746d88
O portal mantém a entrega instalada `ce746d88`, com `2b33a1c3` preservada;recibo de instalação `irpc-l5-reliefs-delivery-20261025.json`. Seguimento isolado em `codex/irpc-juros-mrfta-qa-20261025`,sem nova instalação. Reutilizadas as provas aceites;29 originais e29 ficheiros protegidos conferidos por hash. Sem delta de schema,configuração ou permissões.
**Preenchimento:** quadros1–7 do MRFTA de preparação,um mês/ano;identidade fiscal reutilizável entre livros sem sobrescrever edições nem misturar NUIT distintos. Base,taxa,imposto,documentos e entregas vêm do cálculo IRPC guardado. Agrupamento apenas da mesma rubrica/taxa/CER. Retenções sofridas,dispensas e outros períodos ficam separados. CER requer referência aplicável;os números de campos do M/39 antigo não são convertidos em códigos de receita. Rubricas digitais/especiais desconhecidas e múltiplas taxas na mesma rubrica permanecem discriminadas. Quadros8/9 não são assinados/preenchidos pelo portal. Exportação HTML de preparação,não alteração do PDF oficial nem declaração submetida.
**Juros:** Decreto9/2008,25/35,PDF6/8,p121/123 identifica MAIBOR12meses+2p.p.;BM documenta a descontinuidade da publicação. Não foi obtido parâmetro fiscal sucessor aplicável2026;MIMO/Prime não o substituem. Implementada transcrição de juros compensatórios de liquidação documentada,com período,data,montante e referência;ou ausência de atraso quando entrega integral e datas/prazo documentados coincidem. Informação insuficiente não vira zero. Juros de mora continuam por implementar. O subtotal do principal permanece disponível;total do formulário fica indeterminado enquanto faltarem juros,CER,completude ou situação de outras rubricas (IRPS/autónoma),sem isenções ou créditos presumidos. A completude é um dado da preparação,não novo aprovador organizacional.
**Prova do delta:**12 testes novos+1 de apresentação IRPC;TypeScript e compilação QA passaram. API privada1teste/14verificações com rollback no55441;preparação→gravação→recuperação→relatório/dossier. UI real em exemplo sintético:preparação,gravação/recuperação local,informação insuficiente e download HTML;prova API separada. CER999 é fictício de teste,não taxa/código oficial activado. Exemplo:principal20000MZN,entrega3000,juros documentados500,total17500;alterar provas conserva histórico e desactualiza a preparação. Não foram repetidas manualmente suites L3/ISPC/câmbio.
**Saldo:**cálculo automático dos juros e taxa aplicável2026,juros de mora,catálogo CER integral,rubricas digitais/especiais,mistura de taxas e obrigações IRPS/autónomas fora do recorte. Limita apenas as parcelas dependentes;L5/IRPC/IRPS continuam parciais. Recibo `irpc-juros-mrfta-qa-20261025.json`;provas locais `outputs/irpc-mrfta/`.
Reprodução QA: `php tools/irpc-mrfta-qa.php routes`; `node --test tests/frontend/irpc-mrfta.test.mjs`; `php tools/irpc-mrfta-qa.php test`. PHP8.5,Node24,dependências existentes;alvo e identidadeQA guardados antes de fornecedores/testes.
## 25/10/2026 — entrega5fa64bc0 instalada;seguimento restrito a juros/CER em QA
Instalada pelo Git a revisão exacta `5fa64bc0`,com `ce746d88` preservada como release anterior. Backup fresco2026-10-25T18:28:38Z;174tabelas e369ficheiros/configuração;restauro isolado sem rede/55441 passou. Quatro ficheiros de execução,29protegidos e30originais conferidos. Schema,permissões e configuração iguais;zero migrações/importações. As172tabelas de negócio mantêm checksums;apenas cache operacional e sessões anónimas da instalação/verificação foram reconciliadas. Revisão/manifesto públicos,8marcadores compilados e simuladorHTTP200 passaram. Provas aceites reutilizadas,sem nova ronda manual;CI habitual do instalador passou.
Cobertura instalada:preparação por período,registo de juros documentados e relatório/exportação MRFTA. Registar não significa calcular automaticamente;CER/rubricas desconhecidos continuam identificados sem preenchimento presumido. Não houve submissão ou aceitação AT. Seguimento isolado apenas de juros automáticos eCER/rubricas;L5continua parcial,L3/ISPC/câmbio preservados. Recibo:`irpc-mrfta-delivery-20261025.json`.
## 25/10/2026 — seguimento QA restrito: juros automáticos e casos CER/rubricas
Portal instalado em `5fa64bc0`,com `ce746d88` preservada;recibo `irpc-mrfta-delivery-20261025.json`. Novo ramo `codex/irpc-interest-cer-qa-20261025`,sem instalação. Não foram reabertos outros saldos L5.
**Juros:** nova aritmética racional diária por parâmetros documentados do caso:taxa anual final,fonte/fundamento fiscal,vigência na data de liquidação,base anual,arredondamento do total e ocorrência. Nenhum valor vem pré-definido. Intervalos começam no dia posterior ao prazo documentado;entregas reduzem a base após o seu dia e o pagamento integral pára encargos. Contagem por ano/base365/366 e arredondamento só conforme convenção preenchida com referência. Definitiva e por conta retida cobertas neste recorte;por conta não retida e mora mantêm regra própria. Sem perfil completo,juros indeterminados e principal preservado. A taxa10%,base365 e convenções dos testes são fictícias,sem activação de parâmetro fiscal2026. O registo de liquidação documentada da entrega instalada mantém significado e histórico.
**CER/rubricas:** separação estável por período,rubrica,taxa e CER,com documentos e referências. Fichas de trabalhoHTML independentes conservam as pendências globais;não são declarações autónomas,anexos oficiais nem uma taxa média. Teste integrado distingue retenções20%/10% e CERfictícios999/998;juros por perfil permanecem demonstráveis,mas o total do formulário continua indeterminado pela transposição de rubricas distintas. Ausência de código ou referência continua identificada,sem preenchimento presumido. Nenhum catálogo CER oficial foi acrescentado.
**Compatibilidade/provas:** campos novos adicionais conservam os modos conhecidos pelo leitor5fa64bc0. Prova só de leitura/gravação exacta do novo payload nesse leitor:retenções actuais e nova preparação histórica,sem executar novamente cálculos antigos. Preservados31ficheiros de execução e30originais por hash. TypeScript,buildQA e13testes novos passaram;API1teste/19verificações com rollback em55441. UI:parâmetro fictício explícito,sem taxa→indeterminado,gravação/recuperação,relatório e download de casos20%/999 e10%/998. Relatório do dossier a partir da recuperação API. Provas aceites L3/ISPC/câmbio e5fa64bc0 reutilizadas;sem nova ronda manual das suites antigas.
**Saldo,apenas os mesmos dois pontos:** (1)corresponder fonte/parâmetro fiscal vigente2026 e convenções aplicáveis,além dos ramos mora/por conta não retida fora desta aritmética;(2)corresponder catálogo CER/rubricas ainda pendentes e procedimento oficial para taxas/códigos distintos. O inventário oficial AT189documentos foi consultado por metadados,não relido integralmente;nenhuma taxa/código foi inferido de rascunho,número de campo,agregado orçamental,MIMO ouPrime. L5 continua parcial. Recibo `irpc-interest-cer-qa-20261025.json`;provas em`outputs/irpc-interest-cer/`.
Reprodução do delta em QA: `php tools/irpc-interest-cer-qa.php routes`;`node --test tests/frontend/irpc-interest-cer.test.mjs`;`php tools/irpc-interest-cer-qa.php test`. Dependências existentes,PHP8.5/Node24;alvo QA guardado antes dos fornecedores/testes.
## 25/10/2026 — esclarecimentos concretos para a AT (AUD-SIM-INT02, L5 parcial)
Esta discriminação desenvolve os mesmos dois pontos; não cria outra matriz nem reabre provas aceites. Base instalada: `5fa64bc0`; funcionalidade demonstrada em QA: `acf8ec3c`. Os exemplos abaixo são perguntas de aplicação, não parâmetros ou códigos oficiais. Não foram enviados à AT por este registo.
| Dúvida na mesma matriz | Parâmetro ou correspondência exacta em falta / esclarecimento a obter | Exemplo para acompanhar o esclarecimento | Comportamento enquanto falta |
|---|---|---|---|
| J1 — taxa e vigência | Valor anual final aplicável na data de liquidação em 2026, incluindo eventual acréscimo; série/diploma sucessor da referência MAIBOR 12 meses + 2 p.p., fonte, início e fim de vigência (`annualRate`, `rateSource`, `fiscalBasis`, `validFrom`, `validTo`). | Retenção definitiva de 7 300 MZN, prazo documentado 20/11/2026 e liquidação em 30/11/2026: qual taxa anual final usar? Os 10% do ensaio são fictícios. | Sem taxa predefinida; não substituir por MIMO/Prime. Perfil completo permite apenas simulação pelos dados introduzidos. |
| J2 — contagem diária | Base anual aplicável: 365, 366 ou dias efectivos por ano (`dayBasis`, `dayBasisRef`); incidência do dia da entrega parcial e divisão de períodos entre anos. | Mesmo principal de 7 300 MZN, entrega de 3 650 em 25/11 e liquidação em 30/11: a redução começa em 26/11? Num intervalo 31/12/2027–02/01/2028, qual denominador em cada ano? | Motor demonstra dia posterior ao prazo, dia da entrega incluído e redução no dia seguinte; só usar como pressuposto de simulação até esclarecer a aplicação. |
| J3 — arredondamento | Método e momento oficiais: total ou parcela/dia, cêntimos, metade por excesso ou outra convenção (`rounding`, `roundingRef`). | 7 300 MZN × taxa fictícia 10,0025% × 10/365 = 20,005 MZN: declarar 20,00 ou 20,01? Arredondar só o total ou cada segmento? | As duas opções do motor são convenções explícitas de simulação; outra convenção mantém o caso por implementar. |
| J4 — retenção por conta não efectuada | Regra e datas específicas dependentes da declaração/liquidação anual, base e limite temporal; não equiparar a retenção efectuada ou definitiva (`retention`, `occurrenceRef`). | Retenção por conta de 7 300 MZN não efectuada em Novembro/2026: até que evento anual se contam juros e sobre que montante? | Ramo indeterminado; não herda a fórmula do ramo demonstrado. |
| J5 — mora | Taxa, fundamento, início/fim, base após pagamentos e articulação com juros compensatórios, evitando duplicação. | Liquidação documentada de compensatórios, com saldo de imposto de 3 650 MZN ainda não pago após o prazo: quando começa a mora e sobre que parcelas? | Mora não calculada; registo de liquidação documentada mantém-se independente. |
| C1 — CER de capitais e prediais por conta | Código CER exacto e referência/versão para cada rubrica “Taxa normal — Rendimentos de capitais e mais valias” e “Taxa normal — Rendimentos prediais”. | Dois pagamentos no mesmo mês: juros de financiamento e renda de imóvel, ambos com retenção por conta: quais CER respectivos? São códigos distintos? | CER por identificar; nome da rubrica já correspondido não prova o código. |
| C2 — CER das quatro rubricas liberatórias | Código CER exacto e referência/versão por rubrica: actividade intelectual/industrial e informações; uso de equipamento; aplicação de capitais e rendimentos prediais; comissões/intermediação/prestação de serviços. | No mesmo período, royalties, aluguer de equipamento, juros e comissão a não residentes: indicar o CER de cada natureza e eventual distinção adicional. | Cada natureza permanece separada; não reutilizar números de campos do M/39 como CER. |
| C3 — rendimentos digitais/especiais | Rubrica MRFTA e CER exactos para cada categoria não correspondida, conforme qualificação fiscal documentada; distinguir de serviços comuns. | Pagamento a não residente por serviço digital já qualificado no livro IRPC: em que rubrica/CER deve ser transcrito? Um serviço comum tem a mesma correspondência? | Categoria sem correspondência continua pendente; não copiar para serviços comuns por aproximação. |
| C4 — taxas diferentes na mesma rubrica | Forma oficial de transcrever várias taxas: linhas adicionais, anexo ou outro procedimento, com indicação dos campos; confirmar se o CER varia com regime/convenção. | Royalties de base 10 000 MZN à taxa interna de 20% e outros de 10 000 à taxa convencional demonstrada de 10%, no mesmo mês: como apresentar bases/impostos sem taxa média? | Duas fichas de trabalho; total oficial permanece indeterminado enquanto depender dessa transposição. |
| C5 — códigos diferentes na mesma rubrica | Forma oficial de conservar códigos distintos no mesmo período/rubrica e regra de totalização/entregas; obter os códigos reais antes de preencher. | Duas parcelas agrupáveis por rubrica mas com CER distintos segundo documentos do caso: uma ou várias linhas/guias? Nos ensaios, 999/998 são apenas marcadores fictícios. | Separar período/rubrica/taxa/CER; não inventar declarações autónomas nem reconhecer marcadores como oficiais. |
**Entrega funcional independente:** aritmética pelos pressupostos explicitados, reconciliação de entregas, gravação/recuperação/relatório e fichas separadas podem acompanhar a entrega. Interface e exportações identificam simulação e CER introduzido sem validação por catálogo; referência digitada não equivale a confirmação fiscal. Não activar taxa ou catálogo global por esta entrega. A ausência de dados conserva indeterminação e principal. As respostas da AT poderão completar apenas as células correspondentes, com fonte e vigência, sem outra pesquisa genérica ou nova aprovação inventada.
**Preservação:** L3, ISPC, câmbio, `ce746d88` e `5fa64bc0` conservam provas aceites; nenhum caso aceite foi reaberto. L5 permanece parcial. O presente delta de apresentação/documentação não altera schema, API, permissões, originais ou regras de retenção.
## 25/10/2026 — L5 operacional no âmbito demonstrado; entrega 7a11c4ef
Instalado pelo Git `7a11c4ef8f06ef149eb0488be3cd0749dc609bd0`, sobre `5fa64bc0`, sem força, migrações ou importações. Backup fresco em 25/10/2026 19:14:23 UTC, restaurado em PostgreSQL isolado (rede nenhuma/porta55441):174 tabelas por contagem/checksum. Conferidos4ficheiros do delta,31protegidos,30originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões conservados.172tabelas de negócio iguais;cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação. Versão5fa64bc0 conservada como anterior;L3,ISPC,câmbio e provas aceites preservados. Arquivadas e verificadas dependências de8versões antigas para respeitar espaço mínimo,sem eliminar fontes,dados ou backups nem modificar versões actual/anterior.
Revisão/manifest públicos,8marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,872testesfrontend,tipo/build;sem outra ronda manual das provas aceites. Recibo:`irpc-interest-cer-delivery-20261025.json`.
**L5 fica operacional apenas no âmbito demonstrado**, incluindo preparação por período,registo de juros documentados,simulação por pressupostos explícitos e fichas separadas porCER/rubrica/taxa. Não confirma fiscalmente juros nem converte códigos provisórios em correspondências oficiais. As dez dúvidas J1–J5/C1–C5 da secção anterior acompanham a reunião com a AT;permanecem pendentes e não foram enviadas por esta operação. Sem informação nova,não reabrir a pesquisa desses pontos. Não declararL5 integralmente concluído.
**Sequência autorizada:**L6—IRPC normal,começando pela ponte do resultado financeiro aos ajustamentos documentados. Retenções/créditos anuais,amortizações,perdas e colecta conservam desenvolvimento próprio;nenhuma pendênciaL5 bloqueia o primeiro recorte independenteL6.
## 25/10/2026 — L6 iniciado em QA: primeiros ajustamentos ao resultado financeiro
Base instalada7a11c4ef;L5 operacional apenas no âmbito demonstrado. Primeiro recorteL6 reutiliza a ponte financeira reconciliada por oportunidade,receitas/custos discriminados e resultado antes de imposto. Corresponde explicitamente12meses aJan–Dez2026,MZN,sujeito residente no regime geral fora de transparência/regimes especiais. Projecção com pressupostos,não demonstração contabilística confirmada. Art17(1)é enquadramento da ponte,não equivalência automática do resultado antes de imposto ao lucro tributável.
Implementados acréscimos integrais36(1)c de multas/encargos por infracções sem origem contratual e juros compensatórios já incluídos no custo de origem. Documento/linha,qualificação,montante e inclusão têm suporte/pressuposto expresso. Não classifica juros comerciais nem multas contratuais por aproximação,não importa juros simuladosL5 como despesa efectiva. Limites por custo da origem e duplicação documental previnem dupla contagem. Encargo já excluído não é acrescentado de novo. Lacuna limita a respectiva parcela;acréscimos independentes continuam disponíveis,resultado parcial agregado indeterminado se houver parcela não resolvida.
Exemplo sintético:resultado financeiro6480MZN,multa100 e juros compensatórios20 incluídos;acréscimos120,resultado parcial6600. Sem suporte da multa:apenas20 demonstrados,resultado parcial indeterminado. Lucro tributável,matéria colectável e imposto permanecem indeterminados em todos os casos. Outros ajustamentos,custos/variações patrimoniais,amortizações,perdas,deduções/colecta,créditos anuais eM20/M22 seguem por recortes próprios;EP/regimes especiais,outra moeda/exercício/horizonte não abrangidos.
Prova do delta:7testes novos;APIprivada1teste/19asserções comrollback naQA55441;routes/actions gerados pelo procedimentoWayfinder;TypeScript/buildQA passaram. UI real:cálculo,gravação/recuperação local,relatório,informação insuficiente e download;API demonstrada separadamente,dossier gerado da recuperaçãoAPI. LivroL6 separado mantém payloadL5 e restante histórico;alterar plano/entradas torna resultado histórico sem o apagar.32ficheiros anteriores protegidos e30originais sem alteração;integração mínima emsimulation-form/project-dossier/project-dossier-report. Provas aceites não repetidas. Recibo:`irpc-l6-adjustments-qa-20261025.json`;QA isolada,sem instalaçãoL6.
Fonte adicional necessária apenas paraL6:exemplar oficialAT intitulado19/2009 contém tambémLei20/2009;PDF4/p272(16),36(1)a–i mantidas ealíneasj–n aditadas,conferido visualmente. Lei4/2012PDF2/3 e19/2013PDF1/2 mantêm36(1)c. Não reabre as dez dúvidasL5,que ficam paraAT até informação nova. L5 eL6 não integralmente concluídos.
## 25/10/2026 — L6: percurso delimitado até ao lucro tributável demonstrado em QA
Base instalada `7a11c4ef`; primeiro recorte QA `664c88c8` preservado. A continuação reutiliza o plano reconciliado, o exercício, a oportunidade e os ajustamentos existentes. Não obriga a reintroduzir os montantes financeiros. Âmbito: projecção de Janeiro a Dezembro de 2026, MZN, sujeito residente no regime geral, com referência expressa de que o cenário cobre o sujeito passivo/exercício completo. Uma oportunidade parcial não se transforma automaticamente no total da empresa.
Cada linha do resultado exige qualificação ordinária e suporte: proveitos do exercício (18/20), custos remanescentes indispensáveis e documentados (22), sem outras exclusões/limites declarados. Os acréscimos 36(1)c reutilizam documentos e parcelas já registados. Seis grupos conservam a situação das variações patrimoniais positivas/negativas fora do resultado, outras correcções de rendimentos/custos, diferenças de periodização e operações especiais. **Valor conhecido (incluindo zero), ausência declarada com suporte e informação em falta são estados distintos.** Ausência não pode apagar uma origem financeira positiva ou descartar um montante já preenchido. Um valor conhecido não zero sem tratamento implementado permanece visível e impede apenas o fecho dependente, sem ser aplicado por presunção.
No caso ordinário delimitado, resultado financeiro + acréscimos fundamentados = lucro tributável simulado quando a conferência anual está completa e os outros efeitos são expressamente ausentes ou de valor conhecido zero. Exemplo sintético: 6480 + multa100 + juros compensatórios120 = 6700 MZN. Os 120 são um custo/pressuposto qualificado já incluído na origem; não são juros automaticamente calculados ou fiscalmente confirmados por L5. Falta de prova da variação patrimonial negativa mantém o lucro indeterminado, conservando resultado6480 e acréscimos220. Variação conhecida500, depreciação positiva ou juros financeiros remanescentes mantêm correspondência específica pendente. Sem acréscimos, uma conferência completa pode conservar o resultado financeiro; resultados negativos não são convertidos em zero nem em crédito/perda reportável.
Prova do delta: 9 testes novos; API privada 1 teste/38 verificações, criação → alteração com If-Match → recuperação, com rollback na QA isolada55441. Wayfinder gerou routes/actions; TypeScript e buildQA passaram. UI real: cálculo, gravação/recuperação local, valor conhecido zero, ausência, informação em falta, contradição e exportação HTML. Relatórios/dossiers dos casos conhecido e incompleto gerados a partir da recuperação efectiva da API. Versão2 adicional mantém o snapshot/resultado1 de664c88c8 legível e actual sem o recalcular; mudanças nas entradas desactualizam apenas o novo resultado e conservam histórico. Preservados33ficheiros anteriores de execução e31originais por hash;integrações anteriores de formulário/dossier não alteradas neste delta. Provas aceites L3/ISPC/câmbio/L5 reutilizadas, sem nova ronda manual.
**Preparação conjunta para entrega pelo Git:** primeiro recorte664c88c8 e continuação até lucro tributável, sobre7a11c4ef, com pacote/manifest e delta conferido. Não instalado nem integrado em main por esta preparação. Backup/restauro fresco e conferência do destino fazem parte da instalação posterior; não reutilizar como fresco o backup da entregaL5. Recibo `irpc-l6-taxable-profit-qa-20261025.json`; provas `outputs/irpc-l6-profit/` na QA isolada.
Matéria colectável, perdas reportadas, deduções, colecta, créditos de retenção e M20/M22 continuam fora deste percurso; L6 não está integralmente concluído. L5 permanece operacional no âmbito demonstrado; J1–J5/C1–C5 ficam para a AT e só limitam os casos efectivamente dependentes. Nenhuma nova pesquisa de taxas/CER de L5 foi feita.
## 25/10/2026 — entrega conjunta L6 até lucro tributável instalada:5e02c23a
Instalado pelo Git `5e02c23af863485f6881e409c8704ec7e7573cc9`, sobre `7a11c4ef`, incluindo o primeiro recorte664c88c8. Backup fresco de25/10/2026 19:38:10UTC,restauro isolado sem rede na porta55441:174tabelas conferidas por contagem/checksum. Conferidos6ficheiros do delta,33protegidos,31originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões iguais.172tabelas de negócio preservadas;cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação.7a11c4ef conservado como versão anterior. Arquivadas/verificadas dependências de4versões antigas para margem de espaço,sem eliminar fontes,dados ou backups nem modificar as versões actual/anterior.
Revisão/manifest servidos,10marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,888testesfrontend,tipo/build;sem outra ronda manual das provas aceites. Recibo:`irpc-l6-profit-delivery-20261025.json`.
**Disponível no âmbito demonstrado:**resultado financeiro6480+acréscimos220=lucro tributável simulado6700MZN;estados conhecidos,ausência declarada e informação em falta preservados. **6700MZN não é imposto a pagar.** Matéria colectável,deduções/perdas e colecta não são concluídas por esta instalação. L6 permanece parcial;dúvidasL5J1–J5/C1–C5 só limitam casos efectivamente dependentes. Continuação independente emQA para matéria colectável,sem repetir pesquisa ou provas aceitesL5/L3/ISPC/câmbio.
## 25/10/2026 — L6 matéria colectável: perdas próprias e deduções delimitadas em QA
Base instalada `5e02c23a`, com lucro tributável simulado6700MZN; não é imposto a pagar. A continuação reutiliza esse resultado e a identidade fiscal já disponível na mesma oportunidade, mediante acção expressa que conserva edições. Recorte: sujeito residente no regime geral,2026,método declarativo/directo,perdas fiscais próprias em exercícios anuais ordinários. CIRPC15(1)a/15(2–4) e41(1–7),PDF5/p768(59) ePDF12/p768(66),conferidos nos originais aceites;cadeia de alterações existente reutilizada. Sem novos originais ou pesquisa dos pontosL5.
Livro de perdas por exercício e sujeito:montante fiscal apurado/corrigido,utilizações anteriores,saldo disponível e utilização proposta deste ano,com documentos e completude. Não usa perda contabilística como fiscal. Confere cinco exercícios ordinários posteriores,manutenção/alteração da actividade/objecto no termo do exercício,regime geral e saldo corrigido. Métodos indirectos,períodos especiais/curtos,transparência/isenção parcial,transferências/fusão41-A e correcções pendentes ficam fora do recorte. Expiração/exclusão conhecidas não são apagadas;pedido positivo contra perda excluída exige reconciliação. Utilização proposta é expressa,sem FIFO obrigatório,percentagem inventada ou saldo negativo;excesso sobre saldo/lucro mantém base indeterminada. Simular/gravar não consome o saldo oficial nem actualiza utilizações anteriores.
Exemplo sintético:lucro6700;perda2021apurada1000/utilizada200/saldo800/proposta800;perda2024apurada3000/utilizada500/saldo2500/proposta1500. Dedução2300,**matéria colectável simulada4400MZN**,saldos aritméticos0/1000. **Imposto a pagar permanece indeterminado.** Perda ordinária2020 expira após2025;2021pode ser usada em2026 no recorte demonstrado. Sem perdas/benefícios,ausência expressa e suportada pode conservar base6700;informação em falta não ézero. Benefício conhecido positivo é conservado com referência,mas não subtraído sem regra/condições/limite específicos. Deduções à base15(4) são distintas de efeitos já conferidos no lucro e de créditos à colecta/retenções. Resultado actual negativo permanece conhecido,sem basezero ou reporte automático neste recorte.
Prova do delta:10testes novos;APIprivada1teste/42verificações,criação→alteração comIf-Match→recuperação,rollback naQA55441. Routes/actions peloWayfinder,tipo/buildQA passaram. UI:cálculo4400,gravação/recuperação local,alteração expressa de utilização para700→base4500,repetição sem consumo,sobreutilização recusada,download,informação em falta e benefício positivo conservado sem subtracção. Dossier/HTML gerados da recuperação efectiva daAPI. Versão3 opcional conserva resultado2 actual e históricos1/2;alteração de entradas desactualiza apenas o novo resultado.37ficheiros anteriores de execução e31originais preservados por hash. Provas aceites reutilizadas,sem nova ronda manual. Recibo:`irpc-l6-taxable-base-qa-20261025.json`;QA isolada,sem instalação deste incremento.
L6 continua parcial. Colecta/imposto,créditos anuais,M20/M22,benefícios positivos e casos fora do recorte mantêm desenvolvimento próprio. As dúvidasL5J1–J5/C1–C5 só limitam casos efectivamente dependentes;nenhuma taxa de juros ou CER provisório foi promovido a confirmação fiscal.
## 25/10/2026 — L6 colecta normal demonstrada em QA; entrega conjunta com a matéria colectável
Portal mantém `5e02c23a`. A continuação parte da QA `b8d45796` e reutiliza a matéria colectável actual, sem reintroduzir montantes. No recorte de sujeito residente em regime normal/MZN, exercício anual de01/01/2026 a31/12/2026, o enquadramento explícito do artigo61(1) aplica a taxa geral32%. A fonte/versão, período, classificação e suporte/pressuposto do caso são guardados. Campo por identificar ou caso especial não recebe taxa geral por aproximação; a matéria colectável conhecida permanece disponível.
**Sequência demonstrada:**lucro tributável simulado6700 → matéria colectável simulada4400 → colecta simulada4400×32%=1408MZN → **saldo final a pagar ou recuperar indeterminado, âmbitoL8**. Retenções, pagamentos e créditos do fecho anual não são abatidos nem reconciliados nesta etapa. Colecta não é saldo final. O campo legado `tax` continua nulo e o novo modelo guarda `colecta` separadamente; `finalBalance` mantém pagar/recuperar nulos, não zero.
Taxa32% conferida no CIRPC Lei34/2007,PDF17/p768(71). Lei4/2012 altera61(2); Lei20/2022PDF1/p2731 mantém61(1) e delimita medidas temporárias61(2) até31/12/2025; Lei12/2025PDF18/20 não altera61(1) e distingue61-A. Taxas reduzidas, benefícios, tributação autónoma e mais-valias continuam com tratamento próprio, mesmo se uma percentagem coincidir. Nenhuma extensão temporal/benefício foi inferida. A aritmética é racional exacta; eventual fracção de cêntimo é conservada sem arredondamento fiscal inventado. Não preenche/submeteM20/M22.
Prova do delta:8testes novos;APIprivada1teste/40verificações com criação→alteraçãoIf-Match→recuperação e rollback naQA55441. Wayfinder gerou routes/actions;TypeScript e buildQA passaram. UI real:base reutilizada,colecta1408,taxa/período/enquadramento visíveis,sequência ordenada,gravação/recuperação local,download e casos especiais/informação em falta sem taxa presumida. Dossier/HTML dos casos conhecido e incompleto gerados da recuperação efectiva daAPI. Versão4 opcional conserva versões1/2/3 e o resultado3 actual sem recálculo;mudanças nas entradas desactualizam só o novo resultado e conservam histórico.39ficheiros anteriores daQA e37do portal preservados,31originais sem alteração. Provas aceites reutilizadas,sem outra ronda manual. Recibo:`irpc-l6-colecta-qa-20261025.json`.
**Preparação conjunta compatível:**matéria colectávelb8d45796 e colecta normal neste candidato,base5e02c23a,6ficheiros de execução no delta conjunto. PacoteGit/provas/manifest conferidos apóscommit;sem integração emmain ou instalação nesta preparação. Instalação futura mantém procedimento de destino autenticado,backup/restauro fresco e conferência do delta. L6 continua parcial. Benefícios e casos especiais permanecem explícitos;L8 conserva o fecho anual e as dúvidasL5 só limitam os casos efectivamente dependentes.
## 25/10/2026 — entrega conjunta matéria colectável/colecta instalada:2f684e59
Instalado pelo Git `2f684e59846187f3fb8a338d9d6f6a08cadb4d0d`, incluindo a matéria colectávelb8d45796, sobre `5e02c23a`, sem força, migrações ou importações. Backup fresco de25/10/2026 20:05:19UTC;restauro em base isolada sem rede/porta55441:174tabelas conferidas por contagem/checksum. Conferidos6ficheiros do delta,37protegidos,31originais e369ficheiros/configuração persistentes. Schema,roles/grants e permissões iguais;172tabelas de negócio preservadas. Cache/sessões reconciliadas com reinício da fila,throttle e sessões anónimas da verificação.5e02c23a permanece disponível como versão anterior. Arquivadas/verificadas dependências de4versões antigas para margem de espaço,sem eliminar fontes,dados ou backups nem modificar as versões actual/anterior.
Revisão/manifest públicos,11marcadores compilados,4assets e simuladorHTTP200 conferidos. Pipeline normal:1teste/3106asserções,59testes/317asserções,906testesfrontend,tipo/build. Provas aceites reutilizadas,sem outra ronda manual. Recibo:`irpc-l6-colecta-delivery-20261025.json`.
**Disponível no âmbito demonstrado:**lucro tributável simulado6700→matéria colectável4400→colecta normal32%/2026=1408MZN. **1408MZN não é saldo final a pagar.** A pagar/a recuperar continuam indeterminados emL8. Benefícios/casos especiais anuais sãoL7. O saldo concreto deL6 que justifica «parcial» fica discriminado na secção seguinte;esta actualização substitui,para o estado actual,as pendências genéricas de lucro/base/colecta anteriores já entregues,preservando-as apenas como histórico.
## 25/10/2026 — saldo concreto de L6 após a entrega 2f684e59
Esta discriminação actualiza **AUD-SIM-INT02 na mesma matriz**, com o âmbito L6/L7/L8 já registado no plano consolidado e a leitura do código de `2f684e59`. Não cria outro lote, matriz ou backlog. O estado «L6 parcial» decorre das lacunas funcionais abaixo; **não decorre de faltar o saldo anual de L8 ou os tratamentos de L7**. Os exemplos são casos de fronteira para desenvolvimento, não novos cálculos fiscais confirmados.
**Concluído no âmbito demonstrado e a preservar:** plano financeiro reconciliado → acréscimos36(1)c → lucro tributável6700 → perdas próprias ordinárias2300 → matéria colectável4400 → colecta normal32%/2026=1408MZN. Inclui conhecido/zero/ausência/falta de informação, limites de utilização, gravação/recuperação, histórico, relatório/exportação e indeterminação dos casos dependentes. Não repetir estas provas para fechar os pontos seguintes, excepto se o delta os afectar.
| Saldo que continua em L6 | Evidência concreta no código entregue | Exemplo do caso ainda não coberto | Critério concreto de fecho |
|---|---|---|---|
| Outros ajustamentos ordinários: admissibilidade de custos e correcções aos proveitos | `irpc-normal.ts`, `NormalAdjustment.rule` e `calculateNormal`: apenas multas não contratuais e juros compensatórios36(1)c; `other` fica fora do recorte. `irpc-normal-profit.ts` não aplica `incomeCorrections`/`expenseCorrections` conhecidos não zero. | Encargo de terceiro de250MZN com qualificação36(1)b, ou despesa não documentada36(1)g, incluído no resultado; a correcção não tem regra executável neste livro. A eventual tributação autónoma é outra operação, emL7. | Corresponder a regra geral e condições de cada categoria incluída, calcular acréscimo/dedução/exclusão com sinal e origem, evitar dupla contagem e demonstrar reflexo no lucro, base e colecta. A tributação autónoma que possa coexistir pertence aL7. |
| Dedutibilidade dos juros financeiros ordinários | `irpc-normal-profit.ts`, `closeNormalProfit`: qualquer remanescente não zero de `interest_expense` mantém pendência; só os compensatórios integralmente acrescidos estão cobertos. | Juros de financiamento comercial de120MZN, distintos de juros compensatórios, com finalidade/custo documentados. | Qualificar a parcela ordinária, dedutibilidade e correcção aplicável, conservar os montantes reconhecidos/pagos separados e fechar o lucro sem a equiparar a infracção. Relações especiais/benefícios e regras especiais seguemL7; taxa de juros compensatóriosL5 só é dependência se esse cálculo for efectivamente usado. |
| Reintegrações/amortizações fiscais e diferença face à contabilidade | `irpc-normal-profit.ts`: `depreciation` positivo bloqueia o fecho; não existe mapa fiscal de activos/quotas nesta família de módulos. | Depreciação contabilística120MZN com quota fiscal do activo ainda por corresponder. | Reutilizar activo, base e datas; corresponder método/taxa/limites e afectação ordinários, calcular quota fiscal e diferença para o resultado; manter mapas por activo/exercício e histórico. Incentivos, majorações e regimes especiais de activos seguemL7. |
| Variações patrimoniais e periodização ordinárias de montante não zero | `irpc-normal-profit.ts`, `profitTopics`/`closeNormalProfit`: `positivePatrimonial`, `negativePatrimonial` e `timing` conhecidos não zero conservam valor e impedem o fecho; ausência/zero suportados são o caminho demonstrado. | Variação500MZN fora do resultado, ou diferença temporal300MZN entre reconhecimento contabilístico e exercício fiscal, com natureza concreta documentada. | Corresponder natureza/ano/regra ordinária e decidir inclusão, exclusão ou ajustamento com sinal; impedir reaplicação em dois exercícios; demonstrar cálculo→gravação→recuperação→relatório. Operações especiais/benefícios do tópico `special` não são saldo deL6. |
| Resultado fiscal negativo do próprio exercício | `irpc-normal-base.ts`, `calculateNormalBase`: lucro negativo é conservado, mas a base fica indeterminada; o livro de perdas só admite exercícios anteriores ao de utilização. | Resultado fiscal actual−500MZN conhecido; não é uma perda anterior dedutível a si própria. | Tratar a situação da base/colecta nesse exercício e preparar a perda fiscal própria com origem/ano para utilização futura, conforme regra aplicável, sem confundir ausência de lucro, falta de informação, crédito ou consumo do saldo oficial. Perdas anteriores ordinárias já demonstradas continuam aceites. |
| Extensões do âmbito normal previstas no L6 original | `irpc-normal.ts` fixa12meses/ano civil2026/residente/MZN; `irpc-normal-base.ts` exige exercícios anuais ordinários; a entrada deL6 no plano original inclui exercício fiscal e residência/EP. | Caso de estabelecimento estável sob regime geral, ou período fiscal normal diferente do calendário/horizonte do plano; plano noutra moeda ainda sem reconciliação fiscal anualMZN. | Delimitar os casos normais a admitir, imputação de resultados ao sujeito/EP, datas/períodos e reconciliaçãoMZN usando o câmbio já entregue; demonstrar o percurso dependente. Não reimplementar câmbio, exigir pesquisa de todos os anos históricos ou aplicar automaticamente32% fora do período correspondido. Benefícios/convenções/regimes específicos pertencem aos lotes próprios. |
| Representação fiscal da colecta com fracção de cêntimo | `irpc-normal-assessment.ts` conserva o racional e assinala `centExact:false`; não aplica regra fiscal de arredondamento/transcrição. | Base0,01MZN×32%=0,0032MZN exactos; o caso1408MZN não tem esta ambiguidade e continua válido. | Identificar e executar a convenção aplicável à colecta/representação do formulário, mantendo o exacto e a rastreabilidade do valor transcrito. Não importar por analogia arredondamento de prestações/pagamentosL8 nem criar uma regra por defeito. |
| Correspondência dos dados de L6 aos exemplares M/20/M/22 | A família `irpc-normal*` produz mapaHTML/dossier e exclui expressamente correspondência/transcrição oficial; o âmbito original deL6 inclui M/20/M/22 e diferenças de ediçãoPDF/XLSX. | Resultado, correcções, perdas, base4400 e colecta1408 existem no mapa de trabalho; os respectivos campos/anexos aplicáveis dos exemplares não estão correspondidos no motor. | Cotejar os exemplares já inventariados e mapear apenas os dados deL6 aos campos/versões efectivamente aplicáveis, com prova de preenchimento/recuperação. Os campos de retenções,pagamentos,créditos e saldo final sãoL8. Submissão electrónica/aceitaçãoAT não são presumidas como parte desta correspondência. |
**Encaminhado a L7, sem manter L6 parcial por essa razão:** benefícios/isenções da determinação anual do IRPC, taxas reduzidas/cooperativas, tributação autónoma de despesas e mais-valias61-A, operações especiais, perdas transmitidas/fusão41-A e segregação de regimes especiais. Uma dedução positiva de benefício à base continua sem aplicação no recorte entregue, mas o trabalho substantivo desse benefício éL7, não uma dedução livre nem um novo saldo genérico deL6. A integração posterior usa as interfaces/versionamento já existentes e afecta só os casos dependentes.
**Encaminhado a L8, sem manter L6 parcial por essa razão:** retenções sofridas a imputar ao fecho anual, PPC/PEC e outros pagamentos, créditos/deduções à colecta, dupla tributação quando aplicável, limites/transportes respectivos, reconciliação e saldo final a pagar ou recuperar/calendário. **1408MZN é colecta; pagar e recuperar continuam indeterminados.** Não abater parcelas L5 nem promover os seus códigos/taxas provisórios ao fecho anual nesta entrega.
**Informação do caso, distinta de desenvolvimento em falta:** falta de documento, NUIT, completude anual, montante, prova de saldo ou qualificação dentro de uma regra já implementada mantém o caso indeterminado, mas não constitui por si só outra tarefa deL6. O mesmo vale para a ausência de uma nova prova de uma funcionalidade já aceite. Não exigir nova aprovação genérica das fontes oficiais, novo aprovador ou repetição deL3/ISPC/câmbio/L5. Anos não incluídos no recorte temporal não se tornam automaticamente um projecto de cobertura histórica integral.
**Ordem de continuação delimitada:** ajustamentos ordinários/juros financeiros e amortizações; depois variações/periodização e resultado negativo; ampliar apenas os casos normais concretamente abrangidos e concluir a representação/correspondência dos dados deL6. Cada fecho deve demonstrar o delta e substituir a pendência correspondente nesta mesma linha/nota. Não há estimativa nova nem declaração deL6 integralmente concluído nesta revisão documental.
## 25/10/2026 — L6: três conjuntos compatíveis em QA sobre 2f684e59
Actualização de **AUD-SIM-INT02**, na matriz existente. O percurso instalado em `2f684e59` permanece aceite: lucro6700 → perdas2300 → matéria colectável4400 → colecta1408MZN; saldo anual continua indeterminado emL8. Este incremento é **QA, sem instalação**. Não repete as provas de L3, ISPC, câmbio ou L5; conserva a fotografia4 e o histórico sem recalcular a aceitação anterior.
| Conjunto | Delta executável demonstrado | Efeito e prova nova | Pendência concreta que subsiste |
|---|---|---|---|
| 1 — ajustamentos, juros, variações e periodização | Acréscimos36(1)a/b/g com parcela incluída e origem reconciliada; juros financeiros22c de exploração documentados, sem capitalização/relações/limites especiais; entradas de capital21a e distribuições24c externas ao resultado sem efeito fiscal; variações positivas21 e negativas22/24 ordinárias; especialização18(1) de custo/proveito entre exercício corrente e seguinte. Documento/linha únicos entre mapas, sinal e soma bruta por tema conferidos. | Resultado financeiro6240 + acréscimos anteriores220 + imposto de terceiro250 + variação positiva200 − negativa50 + custo de2027 contabilizado em2026 de100 + diferença de amortização20 = lucro6980. Juros reconhecidos240, compensatórios acrescidos120, remanescente ordinário120; pagamentos continuam separados. Informação insuficiente mantém os efeitos independentes visíveis e impede somente os totais dependentes. | Correcções ordinárias ainda sem regra: encargos e limites36(1)e/f/h/i/n, provisões28/29, operações plurianuais19 e componentes de exercícios anteriores18(2). Juros capitalizáveis/relações especiais e limites exigem o tratamento próprio; não são aceites por simples selecção de juros ordinários. A tributação autónoma que possa coexistir pertence aL7. |
| 2 — amortizações e perda corrente | Decreto72/2013: quotas anuais constantes, custo/residual/acumulado, limite do saldo e vida útil; tabelaII/grupo3/item9 computadores25% e9.1 servidores20%, sem taxa específica da tabelaI prevalecente. Soma da depreciação contabilística por activo reconciliada com o plano; nenhum efeito de mapa incompleto aplicado. Perda corrente separada das perdas anteriores, sem auto-reporte. | Servidor500 ×20%=100 fiscal, depreciação contabilística120 → acréscimo20. Alterar quota/categoria, exceder vida útil ou não reconciliar a origem mantém o lucro dependente indeterminado. Outro exemplo: resultado fiscal−3820 → perda corrente3820 → base0/colecta0 apenas com suporte e conferência completos, sem dedução de perdas anteriores a si própria nem criação de saldo oficial. | Restante catálogo sectorial/genérico de activos, taxas reduzidas dentro dos limites, duodécimos, quotas decrescentes, bens usados/reavaliados, activos intangíveis e recuperação de quotas contabilizadas em anos anteriores. Não declarar toda a amortização fiscal concluída por estes dois itens. |
| 3 — âmbitos, representação e M20/M22 | EP no regime geral, resultado completo exclusivamente imputável ao estabelecimento; ano civil ou período anual diferente autorizado7(2)/comunicado7(3), correspondência dos12 meses e termo em2026/MZN. Valores racionais exactos, sem arredondamento fiscal inventado. M22 campos259/260,269/270,276/277/278 e300 conforme aplicação; M20A.1 quadro4 contas6.1.1/6.2/6.5/6.9 com valores contabilísticos próprios. |6980 − perdas2300 = base4680; ×32%=colecta1497,60MZN, não saldo a pagar. EP com período01/07/2025–30/06/2026 demonstrado; período curto incompatível fica pendente. API privada recupera os quatro casos calculado/falta/perda/EP e os relatórios respectivos. M20 inteiro e M22 ao cêntimo apenas quando a representação é exacta; fracções conservadas e marcadas sem transcrição pronta. | Períodos curtos/transição/liquidação e reconciliação fiscal anual de planos noutra moeda (motor cambial aceite preservado). Representação fiscal de fracções de unidade/cêntimo por corresponder. No M20 faltam discriminação vendas/serviços, fornecimentos/outros gastos, imposto e resultado líquido; no M22 faltam a reconciliação do campo200 e detalhe dos restantes ajustamentos. Divergência delimitada de edições: folha M20A.1 do XLSX remete ao campo201/quadro8 do M22; PDF inventariado utiliza200/quadro10. Bloqueia esse transporte, não os outros campos. |
**Provas apenas do delta:** 14 testes frontend; API privada1 teste/78 asserções com transacção revertida na base QA127.0.0.1:55441; geração de routes/actions pelo procedimento existente, TypeScript e build; interface real com edição, taxa/categoria incompatível, falta de juros, gravação/recuperação, download e perda corrente; relatórios/dossier construídos a partir dos dados recuperados. Recibo `docs/investmoz/simulations/irpc-l6-compatible-sets-qa-20261025.json`; pacote/bundle em `outputs/irpc-l6-sets`. Sem alteração de schema, API, configuração, permissões ou dependências.
**Âmbitos próprios preservados:** L7 conserva benefícios, isenções, taxas reduzidas, tributações autónomas e operações especiais; L8 conserva retenções, pagamentos, créditos e saldo final. M22 campo302 não é preenchido só com a parcela normal300, nem os campos309–316 são preenchidos com zeros presumidos. As dez dúvidas deL5 continuam na mesma matriz, sem nova pesquisa e bloqueando apenas dependências efectivas. L6 continua parcial exclusivamente pelas pendências concretas da tabela; nenhum desses pontos reabre o percurso instalado.
File diff suppressed because one or more lines are too long
@@ -1,3 +1,9 @@
import {SimulationIrpcNormal} from '@/components/simulation-irpc-normal';
import {SimulationIrpcWithholdings} from '@/components/simulation-irpc-withholdings';
import {SimulationIspcResiduals} from '@/components/simulation-ispc-residuals';
import {SimulationIspcWithholding} from '@/components/simulation-ispc-withholding';
import {SimulationIspcQuarter} from '@/components/simulation-ispc-quarter';
import {SimulationIspcEligibility} from './simulation-ispc-eligibility';
import { simulationDraftEtag } from '@/lib/simulation-draft-etag';
import { SimulationPublishedIva, type PublishedIvaInput } from './simulation-published-iva';
import { SimulationMonthlyIva } from './simulation-monthly-iva';
@@ -3501,6 +3507,12 @@ export function SimulationForm() {
onCurrencyChange={(value) => change('currency', value)}
/></details>
)}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIspcEligibility draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIspcQuarter draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIspcWithholding draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIspcResiduals draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIrpcWithholdings draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationIrpcNormal draft={draft} onChange={change} />}
{(current.id === 'financial' || current.id === 'tax') && <SimulationMonthlyIva draft={draft} busy={isCalculating} onCalculate={runSimulation} onChange={change} />}
{current.id === 'financial' &&
(draft.detail_level === 'advanced' ||
@@ -0,0 +1,13 @@
import {newNormalAssessmentInput,type NormalAssessmentInput} from '@/lib/irpc-normal-assessment';
import type {NormalBook} from '@/lib/irpc-normal';
export function SimulationIrpcAssessment({book,save}:{book:NormalBook;save:(b:NormalBook)=>void}){
if(!book.base)return null;
const a=book.assessment,change=(p:Partial<NormalAssessmentInput>)=>save({...book,assessment:{...(a??newNormalAssessmentInput()),...p}});
if(!a)return<button type="button" onClick={()=>change({})}>Iniciar cálculo da colecta normal</button>;
return<fieldset aria-label="Colecta — regime normal" className="space-y-3 rounded border p-3"><legend>Matéria colectável → colecta</legend><p>Reutiliza a matéria colectável actual. Exercício:{book.year||'por identificar'};período anual correspondente à conferência financeira. A taxa geral identificada para2026 é32%,artigo61(1). Benefícios,taxas reduzidas,tributações autónomas e outros casos especiais permanecem separados.</p>
<label className="block">Enquadramento da colecta<select aria-label="Enquadramento da colecta" value={a.treatment} onChange={e=>change({treatment:e.target.value as NormalAssessmentInput['treatment']})}><option value="">Informação em falta</option><option value="general_61_1">Regime normal — taxa geral32%,artigo61(1)</option><option value="other">Benefício ou caso especial — correspondência própria</option></select></label>
<label className="block">Suporte ou pressuposto da taxa geral neste caso<input value={a.reference} onChange={e=>change({reference:e.target.value})}/></label>
<p>Lucro tributável → matéria colectável → colecta → saldo final a pagar ou recuperar. O saldo final pertence aL8:retenções,pagamentos e créditos anuais não são abatidos aqui. Uma colecta conhecida não significa saldo final conhecido.</p>
</fieldset>;
}
@@ -0,0 +1,31 @@
import {newIrpcInterestRule,type IrpcInterestRule} from '@/lib/irpc-interest';
import {mrftaCases,mrftaCaseHtml} from '@/lib/irpc-mrfta-cases';
import {useState} from 'react';
import {irpcCurrent,type IrpcBook} from '@/lib/irpc-withholdings';
import {newMrftaInput,recordMrfta,mrftaHtml,mrftaReportRows,mrftaCurrent,type MrftaInput} from '@/lib/irpc-mrfta';
export function SimulationIrpcMrfta({draft,book,save}:{draft:Record<string,unknown>;book:IrpcBook;save:(book:IrpcBook)=>void}){
const [error,setError]=useState(''),i=book.mrfta??newMrftaInput();
const change=(patch:Partial<MrftaInput>)=>save({...book,mrfta:{...i,...patch}});
const interestMode=i.interest.mode||(i.interest.calculation==='automatic'?'automatic':'');
const interest=(patch:Partial<MrftaInput['interest']>)=>change({interest:{...i.interest,...patch}});
const field=(key:'period'|'nuit'|'name'|'commercialName'|'taxArea'|'address'|'contact'|'completenessRef'|'otherRubricsRef',label:string,type='text')=><label className="block">{label}<input className="block rounded border p-2" type={type} value={i[key]} onChange={e=>change({[key]:e.target.value})}/></label>;
const select=(key:'declaration'|'timing'|'completeness'|'otherRubrics',label:string,options:Array<[string,string]>)=><label className="block">{label}<select value={i[key]} onChange={e=>change({[key]:e.target.value})}>{options.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>;
const periods=[...new Set(book.result?.rows.map(r=>r.period).filter(Boolean)??[])];
const identities=Object.entries((JSON.parse(String(draft.modelo_a_snapshot||'{}')).irpcWithholdings??{}) as Record<string,IrpcBook>).filter(([,b])=>b.mrfta?.nuit&&b.mrfta?.name&&(!i.nuit.trim()||i.nuit===b.mrfta.nuit)&&(!i.name.trim()||i.name===b.mrfta.name)&&(['nuit','name','commercialName','taxArea','address','contact'] as const).some(key=>!i[key].trim()&&b.mrfta![key].trim()));
return <fieldset aria-label="Preparação MRFTA e juros" className="space-y-3 rounded border p-4"><legend>MRFTA — preenchimento e juros compensatórios</legend><p>Reutiliza o cálculo guardado, documentos e entregas IRPC. Um mês/ano por declaração. A retenção sofrida e as dispensas ficam separadas. Quadros 8/9 reservados à assinatura e aos serviços; não há submissão ou aceitação AT.</p>
{identities.map(([scope,b])=><button key={scope} type="button" onClick={()=>{const p:Partial<MrftaInput>={};for(const key of ['nuit','name','commercialName','taxArea','address','contact']as const)if(!i[key].trim())p[key]=b.mrfta![key];change(p);}}>Reutilizar identidade fiscal {b.mrfta!.name} ({scope}) nos campos vazios</button>)}
<div className="grid gap-3 md:grid-cols-2">{field('period','Quadro 2 — mês/ano','month')}<label>Período existente<select value="" onChange={e=>{if(e.target.value)change({period:e.target.value});}}><option value="">Seleccione</option>{periods.map(p=><option key={p} value={p}>{p}</option>)}</select></label>{select('declaration','Quadro 1 — retenção na fonte',[['','Por identificar'],['initial','Inicial'],['replacement','Substituição']])}{select('timing','Quadro 2 — situação do prazo',[['','Por esclarecer'],['within','Dentro do prazo'],['late','Fora do prazo']])}{field('nuit','Quadro 3 — NUIT')}{field('taxArea','Quadro 3 — área fiscal')}{field('name','Quadro 4 — nome do sujeito passivo')}{field('commercialName','Quadro 5 — nome comercial')}{field('address','Quadro 6 — domicílio fiscal')}{field('contact','Quadro 6 — contacto')}{select('completeness','Retenções do sujeito passivo neste período conferidas, incluindo demais livros',[['','Por esclarecer'],['yes','Sim'],['no','Ainda não']])}{field('completenessRef','Referência da reconciliação do período')}{select('otherRubrics','IRPS, tributação autónoma e outras rubricas fora deste recorte',[['','Por esclarecer'],['none','Ausência de outros valores devidos documentada'],['pending','Existem ou estão por apurar']])}{field('otherRubricsRef','Documento da situação das outras rubricas')}</div>
<h5>Quadro 7 — CER das rubricas correspondidas</h5><p>Base, taxa e imposto vêm do cálculo guardado. O CER é transcrito da referência aplicável; os números de campos da guia antiga não são automaticamente códigos de receita. Códigos introduzidos não são validados por catálogo oficial; códigos provisórios ou de simulação não são correspondências oficiais.</p>
{book.result?.inputs.filter(r=>r.direction==='paid'&&book.result?.rows.some(v=>v.id===r.id&&v.period===i.period&&v.status==='calculated'&&v.treatment!=='dispensed')).map(r=>{const code=i.codes.find(c=>c.rowId===r.id)??{rowId:r.id,cer:'',reference:''};const update=(p:Partial<typeof code>)=>change({codes:[...i.codes.filter(c=>c.rowId!==r.id),{...code,...p}]});return <div key={r.id} className="grid gap-2 md:grid-cols-3"><span>{r.documentRef} — {r.counterparty}</span><label>CER<input value={code.cer} onChange={e=>update({cer:e.target.value})}/></label><label>Documento / referência do CER<input value={code.reference} onChange={e=>update({reference:e.target.value})}/></label></div>;})}
<h5>Juros compensatórios — separados do principal</h5><p>Regulamento IRPC, artigos 25/35: a taxa refere MAIBOR de 12 meses + 2 pontos. O Banco de Moçambique documenta a descontinuidade da MAIBOR. O portal não adopta MIMO ou Prime como substituto nem calcula juros de mora.</p>
<label>Tratamento dos juros<select value={interestMode} onChange={e=>interest(e.target.value==='automatic'?{mode:'',calculation:'automatic'}:{mode:e.target.value as MrftaInput['interest']['mode'],calculation:undefined})}><option value="">Informação insuficiente / cálculo automático por resolver</option><option value="assessment">Transcrever liquidação documentada de juros compensatórios</option><option value="automatic">Cálculo com taxa e regra documentadas — sem parâmetro pré-definido</option><option value="timely">Conferir entrega integral dentro do prazo documentado</option></select></label>
{interestMode&&<><label>Período documentado dos juros / entregas<input type="month" value={i.interest.period} onChange={e=>interest({period:e.target.value})}/></label><label>Documento da liquidação / reconciliação<input value={i.interest.reference} onChange={e=>interest({reference:e.target.value})}/></label></>}
{['assessment','automatic'].includes(interestMode)&&<>{i.interest.mode==='assessment'&&<label>Montante dos juros em MZN<input value={i.interest.amount} onChange={e=>interest({amount:e.target.value})}/></label>}<label>Data da liquidação<input type="date" value={i.interest.date} onChange={e=>interest({date:e.target.value})}/></label></>}
{['timely','automatic'].includes(interestMode)&&<><label>Prazo aplicável documentado<input type="date" value={i.interest.dueDate} onChange={e=>interest({dueDate:e.target.value})}/></label><label>Fonte do prazo, incluindo eventual ajuste de calendário<input value={i.interest.dueReference} onChange={e=>interest({dueReference:e.target.value})}/></label></>}
{interestMode==='automatic'&&<fieldset className="space-y-2 rounded border p-2"><legend>Parâmetros documentados do cálculo — sem taxa fiscal de2026 pré-definida</legend><p>Simulação pelos pressupostos introduzidos, sem confirmação fiscal dos juros. Preencha apenas a regra aplicável ao caso. Sem parâmetro completo, os juros continuam indeterminados. A taxa bancária actual não é adoptada por substituição. Imposto por conta não retido e juros de mora mantêm regra própria.</p>{(['annualRate','rateSource','fiscalBasis','validFrom','validTo','dayBasisRef','roundingRef','occurrenceRef']as const).map(k=><label key={k} className="block">{({annualRate:'Taxa anual final (%) documentada, incluindo acréscimos aplicáveis',rateSource:'Documento e citação da taxa',fiscalBasis:'Fundamento da aplicação fiscal ao caso',validFrom:'Parâmetro aplicável desde',validTo:'Parâmetro aplicável até',dayBasisRef:'Documento da base anual e contagem diária',roundingRef:'Documento do arredondamento do total',occurrenceRef:'Documento da retenção e ocorrência'})[k]}<input type={k==='validFrom'||k==='validTo'?'date':'text'} value={i.interest.automatic?.[k]??''} onChange={e=>interest({automatic:{...(i.interest.automatic??newIrpcInterestRule()),[k]:e.target.value}})}/></label>)}{(['dayBasis','rounding','retention']as const).map(k=><label key={k} className="block">{({dayBasis:'Base anual conforme documento',rounding:'Arredondamento do total conforme documento',retention:'Retenção efectuada'})[k]}<select value={i.interest.automatic?.[k]??''} onChange={e=>interest({automatic:{...(i.interest.automatic??newIrpcInterestRule()),[k]:e.target.value} as IrpcInterestRule})}>{(k==='dayBasis'?[['','Por identificar'],['365','365 dias'],['366','366 dias'],['actual_year','Dias efectivos de cada ano']]:k==='rounding'?[['','Por identificar'],['total_cent_half_up','Total aos cêntimos — metade por excesso'],['total_cent_down','Total aos cêntimos — por defeito']]:[['','Por identificar'],['withheld','Sim, documentada'],['not_withheld','Não efectuada, documentado']]).map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>)}</fieldset>}
<button type="button" className="rounded border p-2" onClick={()=>{try{save(recordMrfta(book,irpcCurrent(draft,book)));setError('');}catch(e){setError(String(e));}}}>Preparar e guardar MRFTA</button><button type="button" className="rounded border p-2" onClick={()=>{try{const html=mrftaHtml(book,irpcCurrent(draft,book)),u=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=u;a.download='MRFTA-'+(i.period||'periodo')+'-preparacao.html';a.click();URL.revokeObjectURL(u);setError('');}catch(e){setError(String(e));}}}>Exportar preenchimento MRFTA</button>
{book.mrftaResult&&<fieldset className="space-y-2 rounded border p-2"><legend>Casos de trabalho separados por período, rubrica, taxa e CER</legend><p>Estas fichas conservam as pendências do período. Não são declarações autónomas, anexos oficiais ou uma autorização para fundir taxas.</p>{mrftaCases(book.mrftaResult.model).map(c=><div key={c.key}><span>{c.period}; {c.rubric}; {c.rate}%; CER:{c.cer||'por corresponder'}; documentos:{c.documents.join('; ')}.</span><button type="button" onClick={()=>{try{if(!irpcCurrent(draft,book)||!mrftaCurrent(book,true))throw Error('Reprepare as entradas actuais antes de exportar o caso.');const html=mrftaCaseHtml(book.mrftaResult!.model,c.key),u=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=u;a.download='MRFTA-caso-'+c.key+'.html';a.click();URL.revokeObjectURL(u);setError('');}catch(e){setError(String(e));}}}>Exportar ficha de trabalho {c.rate}% / {c.cer||'CER pendente'}</button></div>)}</fieldset>}
{error&&<p role="alert">{error}</p>}{mrftaReportRows(book,irpcCurrent(draft,book)).map((r,n)=><p key={n}><strong>{r[1]}</strong>: {r[2]}<small>{r[3]}</small></p>)}
</fieldset>;
}
@@ -0,0 +1,40 @@
import {SimulationIrpcSchedules} from '@/components/simulation-irpc-schedules';
import {SimulationIrpcAssessment} from '@/components/simulation-irpc-assessment';
import {useState} from 'react';
import {SimulationIrpcTaxableBase} from '@/components/simulation-irpc-taxable-base';
import {newNormalProfitInput,profitTopics,type NormalProfitInput,type ProfitEvidence} from '@/lib/irpc-normal-profit';
import {normalBook,saveNormalBook,normalFinancialSource,newNormalAdjustment,recordNormal,normalHtml,normalReportRows,type NormalBook,type NormalAdjustment} from '@/lib/irpc-normal';
export function SimulationIrpcNormal({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');if(draft.fiscal_component!=='irpc')return null;
try{
const b=normalBook(draft),source=normalFinancialSource(draft);
const save=(next:NormalBook)=>{try{onChange('modelo_a_snapshot',saveNormalBook(draft,next));setError('');}catch(e){setError(String(e));}};
const patch=(id:string,p:Partial<NormalAdjustment>)=>save({...b,rows:b.rows.map(r=>r.id===id?{...r,...p}:r)});
const profit=(patch:Partial<NormalProfitInput>)=>save({...b,profit:{...(b.profit??newNormalProfitInput()),...patch}});
const field=(r:NormalAdjustment,k:'document'|'line'|'amount'|'reference',label:string)=><label className="block">{label}<input value={r[k]} onChange={e=>patch(r.id,{[k]:e.target.value})}/></label>;
return<section aria-label="IRPC normal — ajustamentos" className="space-y-3 rounded border p-4"><h4>L6 — IRPC normal: ajustamentos ao resultado financeiro</h4><p>Acréscimos de multas sem origem contratual e juros compensatórios incluídos nos custos do plano, artigo 36(1)c. A conferência anual pode determinar o lucro tributável simulado no recorte ordinário documentado. A matéria colectável exige conferência específica de deduções e perdas; a colecta tem cálculo próprio e o saldo final a pagar ou recuperar pertence aL8. Não reutiliza automaticamente juros simulados de L5.</p>{error&&<p role="alert">{error}</p>}
{source?<p>Origem: plano financeiro desta oportunidade; {source.periods} meses; {source.currency}; resultado antes de imposto: {source.accountingProfitBeforeTax}. Cobranças, pagamentos e reembolso de capital ficam fora do resultado.</p>:<p>Prepare o plano financeiro para reutilizar o resultado e os custos reconciliados.</p>}
<label className="block">Exercício fiscal<input value={b.year} onChange={e=>save({...b,year:e.target.value})}/></label>
<label className="block">{b.schedules?'Correspondência dos12 meses do plano ao período anual documentado':'Correspondência dos 12 meses do plano a Janeiro–Dezembro de 2026'}<input value={b.mappingReference} onChange={e=>save({...b,mappingReference:e.target.value})}/></label>
<label className="block">Âmbito<select value={b.scope} onChange={e=>save({...b,scope:e.target.value as NormalBook['scope']})}><option value="">Por identificar</option><option value="resident_general">Sujeito residente — regime geral, fora de transparência e regimes especiais</option><option value="ep_general">Não residente com estabelecimento estável — regime geral, só resultado imputável ao EP (mapas complementares)</option><option value="other">Outro âmbito — por corresponder</option></select></label>
<label className="block">Suporte do âmbito e da imputação integral do resultado ao sujeito/EP<input value={b.scopeReference} onChange={e=>save({...b,scopeReference:e.target.value})}/></label>
<button type="button" onClick={()=>save({...b,rows:[...b.rows,newNormalAdjustment(crypto.randomUUID())]})}>Acrescentar ajustamento ao resultado</button>
{b.rows.map(r=><fieldset key={r.id} className="space-y-2 rounded border p-3"><legend>{r.document||'Ajustamento por identificar'}</legend><label className="block">Custo de origem na ponte<select value={r.sourceCode} onChange={e=>patch(r.id,{sourceCode:e.target.value})}><option value="">Seleccione</option>{source?.accountingLines.filter(l=>l.accountingEffect==='expense').map(l=><option key={l.code} value={l.code}>{l.origin}: {l.total} {source.currency}</option>)}</select></label>{field(r,'document','Documento ou pressuposto identificado')}{field(r,'line','Linha distinta do documento')}{field(r,'amount','Parcela do custo em MZN')}
<label className="block">Natureza documentada<select value={r.rule} onChange={e=>patch(r.id,{rule:e.target.value as NormalAdjustment['rule']})}><option value="">Por classificar</option><option value="noncontractual_fine">Multa/encargo por infracção sem origem contratual — 36(1)c</option><option value="compensatory_interest">Juros compensatórios — 36(1)c</option><option value="other">Outro ajustamento — por corresponder</option></select></label>
<label className="block">Parcela incluída nos custos do resultado de partida<select value={r.included} onChange={e=>patch(r.id,{included:e.target.value as NormalAdjustment['included']})}><option value="">Por demonstrar</option><option value="yes">Sim, reconciliada com a linha de origem</option><option value="no">Não — não acrescentar novamente</option></select></label>{field(r,'reference','Suporte da qualificação, ocorrência e inclusão contabilística')}<p>Juros bancários e penalidades contratuais não são classificados automaticamente como infracções.</p></fieldset>)}
{!b.profit?<button type="button" onClick={()=>profit({})}>Iniciar conferência até ao lucro tributável</button>:<fieldset aria-label="Conferência do lucro tributável" className="space-y-3 rounded border p-3"><legend>Resultado financeiro → ajustamentos → lucro tributável simulado</legend><p>Conferência do sujeito passivo/exercício completo. Cada receita remanescente deve ser ordinária do exercício;cada custo remanescente deve estar documentado e ser indispensável à fonte produtora,sem outras exclusões ou limites. Outras situações conhecidas permanecem discriminadas. Ausência declarada exige suporte e não é informação em falta.</p>
<label className="block">Suporte da completude do sujeito passivo no exercício<input value={b.profit.completenessReference} onChange={e=>profit({completenessReference:e.target.value})}/></label>
{source?.accountingLines.map(l=>{const review=b.profit!.lines.find(r=>r.code===l.code)??{code:l.code,state:'' as const,reference:''};const change=(p:Partial<typeof review>)=>profit({lines:[...b.profit!.lines.filter(r=>r.code!==l.code),{...review,...p}]});return<fieldset key={l.code} className="rounded border p-2"><legend>{l.origin} — {l.total} {source.currency}</legend><label className="block">Estado fiscal — {l.origin}<select aria-label={'Estado fiscal — '+l.origin} value={review.state} onChange={e=>change({state:e.target.value as ProfitEvidence['state']})}><option value="">Informação em falta</option><option value="known">Valor conhecido e qualificação ordinária documentada</option><option value="absent">Ausência declarada — conferir origem zero</option></select></label><label className="block">Suporte fiscal — {l.origin}<input value={review.reference} onChange={e=>change({reference:e.target.value})}/></label></fieldset>;})}
<p>Depreciação positiva e juros financeiros não integralmente acrescidos exigem correspondência própria;uma declaração de ausência não apaga os valores do plano.</p>
{profitTopics.map(([k,label])=>{const t=b.profit!.topics[k];const change=(p:Partial<ProfitEvidence>)=>profit({topics:{...b.profit!.topics,[k]:{...t,...p}}});return<fieldset key={k} className="rounded border p-2"><legend>{label}</legend><label className="block">Estado — {label}<select aria-label={'Estado — '+label} value={t.state} onChange={e=>change({state:e.target.value as ProfitEvidence['state']})}><option value="">Informação em falta</option><option value="known">Valor conhecido</option><option value="absent">Ausência declarada com suporte</option></select></label>{(t.state==='known'||t.amount!=='')&&<label className="block">Montante conhecido — {label}<input value={t.amount} onChange={e=>change({amount:e.target.value})}/></label>}<label className="block">Suporte — {label}<input value={t.reference} onChange={e=>change({reference:e.target.value})}/></label></fieldset>;})}
</fieldset>}
<SimulationIrpcSchedules book={b} save={save}/>
<SimulationIrpcTaxableBase draft={draft} book={b} save={save}/>
<SimulationIrpcAssessment book={b} save={save}/>
<button type="button" onClick={()=>{try{save(recordNormal(draft,b));}catch(e){setError(String(e));}}}>Calcular e guardar ajustamentos L6</button>
<button type="button" onClick={()=>{try{const html=normalHtml(draft),url=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=url;a.download='IRPC-normal-ajustamentos.html';a.click();URL.revokeObjectURL(url);setError('');}catch(e){setError(String(e));}}}>Exportar mapa parcial L6</button>
{normalReportRows(draft).map((r,n)=><p key={n}>{r[1]} — {r[2]} — {r[3]}</p>)}
</section>;
}catch(e){return<p role="alert">Preparação L6 não recuperável: {String(e)}. Originais e histórico conservados.</p>;}
}
@@ -0,0 +1,29 @@
import {newNormalSchedules,newScheduleRow,newNormalAsset,scheduleRules,type NormalSchedules,type ScheduleRow,type NormalAsset} from '@/lib/irpc-normal-schedules';
import type {NormalBook} from '@/lib/irpc-normal';
export function SimulationIrpcSchedules({book,save}:{book:NormalBook;save:(b:NormalBook)=>void}){
const s=book.schedules;if(!s)return<button type="button" onClick={()=>save({...book,schedules:newNormalSchedules()})}>Iniciar mapas complementares L6</button>;
const patch=(p:Partial<NormalSchedules>)=>save({...book,schedules:{...s,...p}});
const row=(id:string,p:Partial<ScheduleRow>)=>patch({rows:s.rows.map(r=>r.id===id?{...r,...p}:r)});
const asset=(id:string,p:Partial<NormalAsset>)=>patch({assets:s.assets.map(a=>a.id===id?{...a,...p}:a)});
return<fieldset aria-label="Mapas complementares L6" className="space-y-3 rounded border p-3"><legend>Mapas complementares — regras ordinárias documentadas</legend>
<p>Reutiliza o resultado e as linhas do plano. As somas brutas de cada tema devem corresponder à conferência do lucro tributável. Os efeitos com sinal ficam discriminados; uma dúvida não apaga as parcelas independentes. L7 conserva benefícios e casos especiais; L8 conserva o fecho anual.</p>
<fieldset><legend>Período anual e correspondência dos meses</legend><label>Tipo de período<select aria-label="Tipo de período L6" value={s.period.kind} onChange={e=>patch({period:{...s.period,kind:e.target.value as NormalSchedules['period']['kind']}})}><option value="">Por identificar</option><option value="calendar">Ano civil — artigo7(1)</option><option value="authorised_annual">Anual diferente — autorização artigo7(2)</option><option value="ep_annual">Anual diferente de EP — comunicação artigo7(3)</option></select></label>{(['from','to','reference']as const).map(k=><label key={k} className="block">{({from:'Início do período AAAA-MM-DD',to:'Termo do período AAAA-MM-DD',reference:'Suporte do período e da correspondência mensal'})[k]}<input aria-label={'Período L6 '+k} value={s.period[k]} onChange={e=>patch({period:{...s.period,[k]:e.target.value}})}/></label>)}<p>Período anual diferente: documente autorização do artigo7(2) ou comunicação do EP do artigo7(3), início de aplicação e manutenção por cinco exercícios. O plano representa o período completo com termo em2026, emMZN. Períodos curtos e conversão fiscal anual de outra moeda ficam por corresponder.</p></fieldset>
<button type="button" onClick={()=>patch({rows:[...s.rows,newScheduleRow(crypto.randomUUID())]})}>Acrescentar regra complementar</button>
{s.rows.map((r,n)=><fieldset key={r.id} className="rounded border p-2"><legend>Regra complementar {n+1}</legend>
<label>Tratamento<select aria-label={'Tratamento complementar '+(n+1)} value={r.rule} onChange={e=>row(r.id,{rule:e.target.value as ScheduleRow['rule']})}><option value="">Por identificar</option>{Object.entries(scheduleRules).map(([k,v])=><option key={k} value={k}>{v[0]} — {v[2]}</option>)}</select></label>
{([['amount','Montante MZN'],['sourceCode','Código da linha de origem (custos/proveitos já incluídos)'],['document','Documento'],['line','Linha distinta'],['reference','Suporte da regra e dos factos'],['fiscalYear','Exercício de imputação (periodização)']]as const).map(([k,label])=><label key={k} className="block">{label}<input aria-label={label+' complementar '+(n+1)} value={r[k]} onChange={e=>row(r.id,{[k]:e.target.value})}/></label>)}
<p>Entradas/distribuições de capital e variações patrimoniais são externas ao resultado. Variação negativa ordinária: indispensável à actividade sujeita, sem liberalidade, menos-valia latente ou distribuição; sem gratificações especiais. Periodização: operação ordinária e exercício de realização documentados; sem obra plurianual ou correcção de exercício anterior.</p>
<label>Condições demonstradas<select aria-label={'Condições complementar '+(n+1)} value={r.conditions} onChange={e=>row(r.id,{conditions:e.target.value as ''|'yes'})}><option value="">Informação em falta</option><option value="yes">Sim, nos documentos identificados</option></select></label>
<button type="button" onClick={()=>patch({rows:s.rows.filter(q=>q.id!==r.id)})}>Retirar regra {n+1} das entradas actuais</button></fieldset>)}
<fieldset><legend>Juros financeiros ordinários — artigo22c</legend><p>Somente capitais alheios aplicados na exploração, encargos documentados, não capitalizáveis, sem partes relacionadas, subcapitalização ou outra limitação especial. Identifique o remanescente após os juros compensatórios acrescidos no mapa anterior. Outros juros permanecem pendentes neste caso.</p>
<label className="block">Juros ordinários remanescentes MZN<input value={s.interest.amount} onChange={e=>patch({interest:{...s.interest,amount:e.target.value}})}/></label>
<label className="block">Suporte dos juros e condições<input value={s.interest.reference} onChange={e=>patch({interest:{...s.interest,reference:e.target.value}})}/></label>
<label>Condições dos juros<select aria-label="Condições dos juros ordinários" value={s.interest.conditions} onChange={e=>patch({interest:{...s.interest,conditions:e.target.value as ''|'yes'}})}><option value="">Informação em falta</option><option value="yes">Demonstradas no recorte ordinário</option></select></label></fieldset>
<fieldset><legend>Amortizações fiscais — quotas constantes anuais</legend><p>Decreto72/2013, artigos3–7. Activo próprio sujeito a deperecimento, custo histórico, uso no início de2026, método uniforme, vida útil fiscal não excedida. Documente que não há regra sectorial específica prevalecente ou limitação especial. A categoria exige qualificação documentada; os itens genéricos9/9.1 só se aplicam quando não há taxa específica da tabelaI. Duodécimos, reavaliação, bens usados e recuperação de quotas antes tributadas ficam separados.</p>
<label className="block">Reconciliação de todos os activos com a depreciação do plano<input value={s.assetsReference} onChange={e=>patch({assetsReference:e.target.value})}/></label>
<button type="button" onClick={()=>patch({assets:[...s.assets,newNormalAsset(crypto.randomUUID())]})}>Acrescentar activo fiscal</button>
{s.assets.map((a,n)=><fieldset key={a.id} className="rounded border p-2"><legend>Activo {n+1}</legend><label>Categoria fiscal<select aria-label={'Categoria activo '+(n+1)} value={a.category} onChange={e=>asset(a.id,{category:e.target.value as NormalAsset['category'],rate:e.target.value==='computer'?'25':e.target.value==='server'?'20':'',tableReference:e.target.value==='computer'?'Decreto72/2013 tabelaII grupo3 item9':e.target.value==='server'?'Decreto72/2013 tabelaII grupo3 item9.1':''})}><option value="">Por identificar</option><option value="computer">Computador, impressora, UPS — II/3/9 — 25%</option><option value="server">Servidor — II/3/9.1 — 20%</option><option value="other">Outra categoria — correspondência pendente</option></select></label>{([['description','Descrição'],['cost','Custo fiscal documentado MZN'],['residual','Valor residual MZN'],['rate','Taxa anual documentada %'],['accounting','Depreciação contabilística de2026 MZN'],['previousFiscal','Amortização fiscal acumulada anterior MZN'],['inUseFrom','Data de entrada em uso AAAA-MM-DD'],['tableReference','Diploma, tabela, código e taxa aplicáveis'],['reference','Documentos e condições do activo']]as const).map(([k,label])=><label key={k} className="block">{label}<input aria-label={label+' activo '+(n+1)} value={a[k]} onChange={e=>asset(a.id,{[k]:e.target.value})}/></label>)}
<label>Condições do activo<select aria-label={'Condições activo '+(n+1)} value={a.conditions} onChange={e=>asset(a.id,{conditions:e.target.value as ''|'yes'})}><option value="">Informação em falta</option><option value="yes">Demonstradas no recorte anual constante</option></select></label><button type="button" onClick={()=>patch({assets:s.assets.filter(q=>q.id!==a.id)})}>Retirar activo {n+1} das entradas actuais</button></fieldset>)}</fieldset>
<label className="block">Suporte da perda fiscal do próprio exercício, se apurada<input value={s.currentLossReference} onChange={e=>patch({currentLossReference:e.target.value})}/></label><p>Perda actual conhecida: matéria colectável e colecta zero apenas depois de conferidas as restantes condições. Não é dedução a si própria nem saldo oficial de reporte. Informação insuficiente mantém os totais dependentes indeterminados.</p>
</fieldset>;
}
@@ -0,0 +1,30 @@
import {irpcBook} from '@/lib/irpc-withholdings';
import {newNormalBaseInput,newNormalLoss,type NormalBaseInput,type NormalLoss} from '@/lib/irpc-normal-base';
import type {NormalBook} from '@/lib/irpc-normal';
export function SimulationIrpcTaxableBase({draft,book,save}:{draft:Record<string,unknown>;book:NormalBook;save:(b:NormalBook)=>void}){
if(!book.profit)return null;
const b=book.base;const change=(p:Partial<NormalBaseInput>)=>save({...book,base:{...(b??newNormalBaseInput()),...p}});
let identity:{nuit:string;name:string}|null=null;try{const m=irpcBook(draft).mrfta;if(m&&/^\d{9}$/.test(m.nuit))identity={nuit:m.nuit,name:m.name};}catch{/* A missing withholding book does not block this independent path. */}
if(!b)return<button type="button" onClick={()=>change({})}>Iniciar determinação da matéria colectável</button>;
const loss=(id:string,p:Partial<NormalLoss>)=>change({losses:b.losses.map(l=>l.id===id?{...l,...p}:l)});
const choices:Array<[string,string]>=[['','Por esclarecer'],['yes','Sim, documentado'],['no','Não, documentado']];
return<fieldset aria-label="Matéria colectável — perdas e deduções" className="space-y-3 rounded border p-3"><legend>Lucro tributável → matéria colectável simulada</legend><p>Reutiliza o lucro tributável do cálculo actual, sem introduzir novamente os montantes. Esse lucro e a matéria colectável não são imposto a pagar. Recorte: regime geral, método declarativo, perdas fiscais próprias em exercícios anuais ordinários, com saldo e utilização propostos expressos. Não aplica benefícios positivos sem regra específica nem créditos de retenção.</p>
{identity&&(!b.subjectNuit||b.subjectNuit===identity.nuit)&&<button type="button" onClick={()=>{if(!b.subjectNuit||b.subjectNuit===identity!.nuit)change({subjectNuit:identity!.nuit,identityReference:b.identityReference||'Identidade reutilizada da preparação MRFTA desta oportunidade: '+identity!.name});}}>Reutilizar NUIT da preparação existente {identity.nuit}</button>}
<label className="block">NUIT do sujeito passivo da matéria colectável<input value={b.subjectNuit} onChange={e=>change({subjectNuit:e.target.value})}/></label>
<label className="block">Suporte da identidade e correspondência com o lucro<input value={b.identityReference} onChange={e=>change({identityReference:e.target.value})}/></label>
<label className="block">Método de determinação<select aria-label="Método de determinação" value={b.method} onChange={e=>change({method:e.target.value as NormalBaseInput['method']})}><option value="">Por esclarecer</option><option value="direct">Declarativo/directo, documentado</option><option value="indirect">Métodos indirectos — fora deste recorte</option></select></label>
<label className="block">Suporte do método de determinação<input value={b.methodReference} onChange={e=>change({methodReference:e.target.value})}/></label>
<label className="block">Situação das perdas fiscais anteriores<select aria-label="Situação das perdas fiscais anteriores" value={b.lossesState} onChange={e=>change({lossesState:e.target.value as NormalBaseInput['lossesState']})}><option value="">Informação em falta</option><option value="known">Perdas/saldos conhecidos — discriminar</option><option value="absent">Ausência declarada com suporte</option></select></label>
<label className="block">Suporte e completude dos saldos de perdas<input value={b.lossesReference} onChange={e=>change({lossesReference:e.target.value})}/></label>
{(b.lossesState==='known'||b.losses.length>0)&&<><button type="button" onClick={()=>change({losses:[...b.losses,{...newNormalLoss(crypto.randomUUID()),subjectNuit:b.subjectNuit}]})}>Acrescentar perda fiscal por exercício</button>
<label className="block">Objecto social e natureza da actividade mantidos no termo do exercício<select aria-label="Objecto social e natureza da actividade mantidos no termo do exercício" value={b.unchangedObject} onChange={e=>change({unchangedObject:e.target.value as NormalBaseInput['unchangedObject']})}>{choices.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label><label className="block">Suporte da manutenção ou alteração da actividade<input value={b.objectReference} onChange={e=>change({objectReference:e.target.value})}/></label>
{b.losses.map((l,n)=><fieldset key={l.id} className="space-y-2 rounded border p-2"><legend>Perda {n+1} — {l.year||'exercício por identificar'}</legend>{(['year','subjectNuit','assessed','previouslyUsed','requested','reference']as const).map(k=><label className="block" key={k}>{({year:'Exercício da perda',subjectNuit:'NUIT da perda',assessed:'Perda fiscal apurada ou corrigida em MZN',previouslyUsed:'Utilizações anteriores em MZN, incluindo zero conhecido',requested:'Utilização proposta neste exercício em MZN',reference:'Documento do apuramento fiscal, correcções e saldo'})[k]}<input value={l[k]} onChange={e=>loss(l.id,{[k]:e.target.value})}/></label>)}
<label className="block">Origem da perda<select aria-label={'Origem da perda '+(n+1)} value={l.kind} onChange={e=>loss(l.id,{kind:e.target.value as NormalLoss['kind']})}><option value="">Por esclarecer</option><option value="ordinary">Perda própria ordinária do mesmo sujeito</option><option value="transfer">Transmitida/fusão — tratamento próprio</option><option value="other">Outra origem — por corresponder</option></select></label>
{(['annualPeriods','generalActivity','balanceConfirmed']as const).map(k=><label className="block" key={k}>{({annualPeriods:'Exercícios anuais ordinários, sem períodos curtos especiais',generalActivity:'Perda do regime geral, fora de transparência/isenção parcial/actividade reduzida',balanceConfirmed:'Saldo fiscal, correcções e utilizações anteriores reconciliados'})[k]}<select aria-label={k+' '+(n+1)} value={l[k]} onChange={e=>loss(l.id,{[k]:e.target.value as NormalLoss['annualPeriods']})}>{choices.map(([v,label])=><option key={v} value={v}>{label}</option>)}</select></label>)}
</fieldset>)}<p>A utilização é escolhida explicitamente. O portal não presume ordem FIFO, não ultrapassa saldo ou lucro e não consome o saldo oficial ao simular ou guardar.</p></>}
<label className="block">Benefícios/deduções à matéria colectável<select aria-label="Benefícios/deduções à matéria colectável" value={b.benefits.state} onChange={e=>change({benefits:{...b.benefits,state:e.target.value as NormalBaseInput['benefits']['state']}})}><option value="">Informação em falta</option><option value="known">Valor conhecido — identificar</option><option value="absent">Ausência declarada com suporte</option></select></label>
{(b.benefits.state==='known'||b.benefits.amount!=='')&&<label className="block">Montante conhecido de benefícios/deduções em MZN<input value={b.benefits.amount} onChange={e=>change({benefits:{...b.benefits,amount:e.target.value}})}/></label>}
<label className="block">Suporte dos benefícios/deduções, regra e exercício<input value={b.benefits.reference} onChange={e=>change({benefits:{...b.benefits,reference:e.target.value}})}/></label><p>Um benefício positivo conhecido permanece por corresponder; a referência não autoriza subtracção livre. Créditos à colecta, retenções sofridas e imposto a pagar seguem etapa própria.</p>
</fieldset>;
}
@@ -0,0 +1,34 @@
import {SimulationIrpcMrfta} from '@/components/simulation-irpc-mrfta';
import {irpcReliefRules,newIrpcReliefPreparation,prepareIrpcRelief} from '@/lib/irpc-relief-preparation';
import {SimulationFxSelection} from '@/components/simulation-fx-selection';
import {irpcFxSources,irpcFxRow,updateIrpcFx,type IrpcFxAmount} from '@/lib/irpc-fx';
import {useState} from 'react';
import {irpcBook,saveIrpcBook,reuseIrpcSources,irpcSources,newIrpcRow,recordIrpc,irpcKinds,emptyIrpcOrdinaryFacts,irpcReportRows,irpcPreparationHtml,type IrpcBook,type IrpcRow,type IrpcEvent,type IrpcPayment,type IrpcOrdinaryFacts} from '@/lib/irpc-withholdings';
export function SimulationIrpcWithholdings({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');if(draft.fiscal_component!=='irpc'&&draft.fiscal_component!=='withholding')return null;
try{const book=irpcBook(draft),sources=irpcSources(draft),save=(b:IrpcBook)=>{try{onChange('modelo_a_snapshot',saveIrpcBook(draft,b));setError('');}catch(e){setError(String(e));}},change=(id:string,p:Partial<IrpcRow>)=>save({...book,rows:book.rows.map(r=>r.id===id?{...r,...p}:r)}),uid=()=>crypto.randomUUID();
const field=(r:IrpcRow,k:keyof IrpcRow,label:string,type='text')=><label className="block">{label}<input className="block rounded border p-2" type={type} value={String(r[k]??'')} onChange={e=>change(r.id,{[k]:e.target.value})}/></label>;
const select=(r:IrpcRow,k:keyof IrpcRow,label:string,options:Array<[string,string]>)=><label className="block">{label}<select className="block rounded border p-2" value={String(r[k]??'')} onChange={e=>change(r.id,{[k]:e.target.value})}>{options.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>;
const yn:Array<[string,string]>=[['','Por esclarecer'],['yes','Sim'],['no','Não']];
const eventLabels:Array<[IrpcEvent['kind'],string]>=[['cost','Reconhecimento do custo'],['payment','Pagamento do rendimento'],['maturity','Vencimento, ainda que presumido'],['availability','Colocação à disposição'],['liquidation','Liquidação'],['quantification','Apuramento do quantitativo']];
const fxSources=irpcFxSources(draft);
const renderFx=(id:string,input:IrpcFxAmount,apply:(patch:Partial<IrpcFxAmount>)=>void)=><div className="space-y-2"><p>A base/comprovativo conserva a moeda e o montante originais. A conversão reutiliza o selector e a aritmética entregues; a data cambial fica distinta do evento da retenção.</p>{fxSources.map(src=><div key={src.id}><span>{src.label};data:{src.selection.applied?.date||'por confirmar'};selecção actual:{input.fxSelection?.applied?.rate||'nenhuma'}.</span><button type="button" className="rounded border p-2" onClick={()=>{if(window.confirm(`Substituir a selecção cambial desta linha (${input.fxSelection?.applied?.rate||'vazia'}) pela origem ${src.label},data ${src.selection.applied?.date||'por confirmar'}? O montante e a moeda originais são conservados;resultado anterior permanece no histórico até novo cálculo.`))apply({fxSelection:structuredClone(src.selection),fxLink:{id:src.id,fingerprint:src.fingerprint}});}}>Reutilizar selecção cambial {src.id}</button></div>)}<SimulationFxSelection row={irpcFxRow(id,input)} onChange={patch=>{if(patch.fxSelection)apply(updateIrpcFx(input,patch.fxSelection));}}/></div>;
const ordinarySelect=(r:IrpcRow,k:keyof IrpcOrdinaryFacts,label:string,options:Array<[string,string]>)=><label className="block">{label}<select value={String((r.ordinary??emptyIrpcOrdinaryFacts())[k]??'')} onChange={e=>change(r.id,{ordinary:{...(r.ordinary??emptyIrpcOrdinaryFacts()),[k]:e.target.value}})}>{options.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>;
const paymentChange=(id:string,p:Partial<IrpcPayment>)=>save({...book,payments:book.payments.map(v=>v.id===id?{...v,...p}:v)});
return<section aria-label="Retenções de IRPC" className="space-y-4 rounded border p-4"><h4>IRPC — retenções e preparação documental</h4><p>Reutilize documentos e contrapartes existentes. Classifique o rendimento e o evento aplicável:facturar,pagar e reconhecer o custo são factos distintos. O conjunto calcula os casos digitais de 10%, as taxas normais de 20% e as taxas especiais do artigo 62(4) nos âmbitos identificados. Dispensas dos artigos 68(d/f) e limite convencional de royalties Portugal–Moçambique são calculados nos casos documentados. Informação insuficiente condiciona apenas o respectivo rendimento.</p>{error&&<p role="alert">{error}</p>}
<button type="button" className="rounded border p-2" onClick={()=>{try{save(reuseIrpcSources(draft,book));}catch(e){setError(String(e));}}}>Reutilizar contrapartes e documentos existentes</button><button type="button" className="rounded border p-2" onClick={()=>save({...book,rows:[...book.rows,newIrpcRow(uid())]})}>Acrescentar rendimento IRPC</button>
{book.rows.map(r=><fieldset key={r.id} className="space-y-3 rounded border p-3"><legend>{r.description||r.documentRef||'Rendimento por identificar'}</legend>{r.source&&<p>Origem:{r.source.id}. Entradas deliberadamente editadas são conservadas. {sources.find(s=>s.id===r.source!.id)?.key!==r.source.key&&<><strong>Origem alterada ou indisponível.</strong>{sources.find(s=>s.id===r.source!.id)&&<><span> Base actual:{r.base};base na origem:{sources.find(s=>s.id===r.source!.id)?.amount||'desconhecida'};documento actual:{r.documentRef};origem:{sources.find(s=>s.id===r.source!.id)?.documentRef||'desconhecido'}.</span><button type="button" className="rounded border p-2" onClick={()=>{const s=sources.find(s=>s.id===r.source!.id)!;if(window.confirm('Confirma a reconciliação da origem indicada, conservando as entradas deliberadas e os resultados anteriores no histórico?'))change(r.id,{source:{...r.source!,key:s.key}});}}>Conservar edições e reconciliar origem</button></>}</>}</p>}
<div className="grid gap-3 md:grid-cols-2">{select(r,'direction','Perspectiva',[['paid','Rendimento pago — retenção a entregar'],['received','Rendimento recebido — retenção sofrida']])}{field(r,'counterparty','Contraparte')}{field(r,'documentRef','Documento / operação / linha distinta')}{field(r,'description','Descrição')}{select(r,'origin','Origem',[['projected','Projecção com pressupostos'],['effective','Factos documentados']])}{select(r,'kind','Natureza do rendimento',irpcKinds)}{field(r,'base','Base do rendimento, separada do IVA')}{field(r,'currency','Moeda da base')}{select(r,'recipientIrpc','Titular sujeito a IRPC neste rendimento',yn)}{select(r,'payerIrpc','Devedor sujeito a IRPC',yn)}{select(r,'residence','Residência do titular',[['','Por esclarecer'],['resident','Residente'],['nonresident','Não residente']])}{r.residence==='nonresident'&&<>{select(r,'permanentEstablishment','Existe estabelecimento estável em Moçambique',yn)}{r.permanentEstablishment==='yes'&&select(r,'attributable','Rendimento imputável ao estabelecimento',yn)}</>}{select(r,'mozambique','Rendimento obtido em Moçambique, conforme qualificação legal',yn)}{field(r,'qualificationRef','Suporte / pressuposto da qualificação, residência e incidência')}{select(r,'specialRelief','Convenção, isenção ou dispensa aplicável',[['','Por esclarecer'],['none','Não invocada neste caso qualificado'],['claimed','Invocada — identificar regra e condições']])}{r.specialRelief==='claimed'&&field(r,'reliefRef','Artigo, condições, período e prova invocados')}</div>
{r.specialRelief==='claimed'&&<fieldset className="space-y-2 rounded border p-2"><legend>Preparação de dispensa ou convenção</legend><p>Reutiliza contraparte, residência, estabelecimento estável e documento deste rendimento.</p><label>Enquadramento<select value={r.reliefPreparation?.kind??'dispensation'} onChange={e=>change(r.id,{reliefPreparation:{...(r.reliefPreparation??newIrpcReliefPreparation()),kind:e.target.value as 'dispensation'|'exemption'|'treaty'}})}><option value="dispensation">Dispensa de retenção</option><option value="exemption">Isenção</option><option value="treaty">Convenção</option></select></label>{(['instrument','article','country','residenceDocument','validFrom','validTo','conditions','evidence'] as const).filter(k=>!['country','residenceDocument'].includes(k)||r.reliefPreparation?.kind==='treaty').map(k=><label key={k} className="block">{({instrument:'Diploma / convenção',article:'Artigo',country:'Estado contratante',residenceDocument:'Referência do documento de residência fiscal',validFrom:'Aplicável desde',validTo:'Aplicável até',conditions:'Condições do benefício',evidence:'Referências dos documentos existentes'})[k]}<input type={k==='validFrom'||k==='validTo'?'date':'text'} value={r.reliefPreparation?.[k]??''} onChange={e=>change(r.id,{reliefPreparation:{...(r.reliefPreparation??newIrpcReliefPreparation()),[k]:e.target.value}})}/></label>)}<label>Regra aplicável<select value={r.reliefPreparation?.rule??''} onChange={e=>change(r.id,{reliefPreparation:{...(r.reliefPreparation??newIrpcReliefPreparation()),rule:e.target.value as NonNullable<IrpcRow['reliefPreparation']>['rule']}})}>{irpcReliefRules.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>{(r.reliefPreparation?.rule==='ptMz12'?(['treatyResident','beneficialOwner','payerResidentMz','armLength','royaltyDefinition'] as const):r.reliefPreparation?.rule==='cirpc68f'?(['subjectToIrpc','notTransparent'] as const):r.reliefPreparation?.rule==='cirpc68d'?(['subjectToIrpc'] as const):[]).map(k=><label key={k} className="block">{({subjectToIrpc:'Titular sujeito a IRPC relativamente a este rendimento (ainda que isento)',notTransparent:'Sociedade fora da transparência fiscal — 6(1)c',treatyResident:'Residência em Portugal nos termos do artigo 4 documentada',beneficialOwner:'Titular é beneficiário efectivo das royalties',payerResidentMz:'Devedor residente em Moçambique; origem do rendimento conforme 12(5)',armLength:'Montante sem excesso por relações especiais — 12(6)',royaltyDefinition:'Rendimento corresponde à definição de royalties — 12(3), versão 2009'})[k]}<select value={r.reliefPreparation?.facts?.[k]??''} onChange={e=>change(r.id,{reliefPreparation:{...(r.reliefPreparation??newIrpcReliefPreparation()),facts:{...r.reliefPreparation?.facts,[k]:e.target.value as ''|'yes'|'no'}}})}>{yn.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>)}<p>{prepareIrpcRelief(r,r.reliefPreparation??newIrpcReliefPreparation()).missing.length?'Faltam elementos documentais; confira artigo, período e provas.':'Documentos registados; calcule para conferir as condições da regra seleccionada.'}</p></fieldset>}
{r.currency!=='MZN'&&renderFx(r.id,r,patch=>change(r.id,patch))}
{r.kind&&!['digital_goods','digital_services','emoney_commission','other'].includes(r.kind)&&<fieldset className="space-y-2 rounded border p-2"><legend>Factos específicos do rendimento</legend>{ordinarySelect(r,'nonDigital','Rendimento fora do âmbito digital/moeda electrónica do artigo62(5)',yn)}{r.kind==='capital'&&ordinarySelect(r,'capitalType','Categoria dos capitais',[['','Por esclarecer'],['unlisted_interest','Juros não cotados, fora das permutas de liquidez'],['unlisted_dividend','Dividendos não cotados'],['listed_debt_mz','Juros de bilhetes do Tesouro/títulos de dívida cotados em bolsa —62(3)a'],['listed_other_mz','Outros títulos cotados na Bolsa de Valores de Moçambique —62(4)d'],['liquidity_repo','Juros de permutas de liquidez em bancos,com ou sem garantia —62(3)b'],['other','Outra categoria']])}{r.kind==='capital'&&r.residence==='resident'&&['listed_debt_mz','liquidity_repo'].includes(r.ordinary?.capitalType??'')&&ordinarySelect(r,'capitalSeatAndManagement','Titular com sede e direcção efectiva nacionais —62(3)',yn)}{r.kind==='rent'&&ordinarySelect(r,'rentOwnPropertyManagement','Titular é sociedade com objecto de gestão de imóveis próprios',yn)}{(['telecom','international_transport','connected_installation','aircraft_maintenance_charter','rural_public_electrification','maritime_fishing_cabotage'].includes(r.kind)||r.kind==='capital'&&r.ordinary?.capitalType==='listed_other_mz')&&ordinarySelect(r,'specialFacts','Factos exactos da categoria62(4) identificados no suporte — não apenas actividade semelhante',yn)}<label className="block">Suporte ou pressuposto específico da classificação<input value={r.ordinary?.reference??''} onChange={e=>change(r.id,{ordinary:{...(r.ordinary??emptyIrpcOrdinaryFacts()),reference:e.target.value}})}/></label></fieldset>}
<h5>Eventos aplicáveis — artigo67(5), versão2026</h5>{r.events.map((e,n)=><div key={n} className="grid gap-2 md:grid-cols-3"><label>Evento<select value={e.kind} onChange={ev=>change(r.id,{events:r.events.map((v,j)=>j===n?{...v,kind:ev.target.value as IrpcEvent['kind']}:v)})}>{eventLabels.map(([k,l])=><option key={k} value={k}>{l}</option>)}</select></label><label>Data<input type="date" value={e.date} onChange={ev=>change(r.id,{events:r.events.map((v,j)=>j===n?{...v,date:ev.target.value}:v)})}/></label><label>Suporte / pressuposto<input value={e.reference} onChange={ev=>change(r.id,{events:r.events.map((v,j)=>j===n?{...v,reference:ev.target.value}:v)})}/></label></div>)}<button type="button" onClick={()=>change(r.id,{events:[...r.events,{kind:'cost',date:'',reference:''}]})}>Acrescentar evento aplicável</button>{select(r,'eventsComplete','Todos os eventos aplicáveis identificados, incluindo custo quando aplicável',yn)}
{select(r,'settlement','Reconciliação da entrega / prova de retenção sofrida',[['','Por esclarecer'],['none','Ainda sem entrega / prova'],['complete','Pagamentos / provas associados completos']])}{field(r,'settlementRef','Referência da situação declarada')}
{r.allocations.map((a,n)=><div key={n}><label>Pagamento / prova existente<select value={a.paymentId} onChange={e=>change(r.id,{allocations:r.allocations.map((v,j)=>j===n?{...v,paymentId:e.target.value}:v)})}><option value="">Seleccione</option>{book.payments.map(p=><option key={p.id} value={p.id}>{p.reference} — {p.amount} {p.currency} — {p.kind}</option>)}</select></label><label>Parcela usada em MZN<input value={a.amount} onChange={e=>change(r.id,{allocations:r.allocations.map((v,j)=>j===n?{...v,amount:e.target.value}:v)})}/></label></div>)}{r.settlement==='complete'&&<button type="button" onClick={()=>change(r.id,{allocations:[...r.allocations,{paymentId:'',amount:''}]})}>Associar pagamento/prova existente</button>}
</fieldset>)}
<h5>Pagamentos e comprovativos reutilizáveis neste livro</h5><p>Uma referência é registada uma vez e repartida entre rendimentos sem exceder o montante. Pagamento ao fornecedor não é entrega à AT; pagamentos de IVA conservam o seu vínculo anterior e não são automaticamente usados em IRPC.</p>{book.payments.map(p=><fieldset key={p.id} className="grid gap-2 rounded border p-2 md:grid-cols-3"><label>Natureza<select value={p.kind} onChange={e=>paymentChange(p.id,{kind:e.target.value as IrpcPayment['kind']})}><option value="remittance">Entrega IRPC à AT</option><option value="withholding_proof">Comprovativo de retenção sofrida</option><option value="beneficiary">Pagamento ao beneficiário</option></select></label>{(['reference','date','amount','currency']as const).map(k=><label key={k}>{({reference:'Referência',date:'Data',amount:'Montante',currency:'Moeda'})[k]}<input type={k==='date'?'date':'text'} value={p[k]} onChange={e=>paymentChange(p.id,{[k]:e.target.value})}/></label>)}{p.currency!=='MZN'&&(p.kind==='withholding_proof'?renderFx(p.id,p,patch=>paymentChange(p.id,patch)):<p>A entrega IRPC à AT requer o montante MZN do comprovativo; converter o pagamento ao beneficiário não prova entrega do imposto.</p>)}</fieldset>)}<button type="button" onClick={()=>save({...book,payments:[...book.payments,{id:uid(),kind:'remittance',reference:'',date:'',amount:'',currency:'MZN'}]})}>Registar pagamento/prova para reutilização</button>
<div className="space-x-3"><button type="button" className="rounded border p-2" onClick={()=>{try{save(recordIrpc(draft,book));}catch(e){setError(String(e));}}}>Calcular e guardar retenções IRPC</button><button type="button" className="rounded border p-2" onClick={()=>{try{const html=irpcPreparationHtml(draft),u=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=u;a.download='IRPC-L5-preparacao.html';a.click();URL.revokeObjectURL(u);setError('');}catch(e){setError(String(e));}}}>Exportar preparação IRPC</button></div>
<SimulationIrpcMrfta draft={draft} book={book} save={save}/>
{irpcReportRows(draft).slice(0,book.result?.rows.length??0).map((r,n)=><p key={n}><strong>{r[1]}</strong>: {r[2]}<small className="block">{r[3]}</small></p>)}<p>Formalidades externas:MRFTA19/39 e guia M/39 preservados. CER/rubricas digitais e remissão67(7)→62(6) por corresponder. Exportar não submete nem obtém aceitação AT. L5 continua aberto;ISPC e IRPS conservam os seus limites anteriores.</p></section>;
}catch(e){return<p role="alert">{String(e)}</p>;}
}
@@ -0,0 +1,30 @@
import {useState} from 'react';
import {ispcActivities,ispcEligibilityBook,saveIspcEligibilityBook,recordIspcEligibility,ispcEligibilityCurrent,ispcReuseDiff,ispcEligibilityReportRows,type IspcEligibilityInput,type IspcEligibilityBook} from '@/lib/ispc-eligibility';
const factLabels:Partial<Record<keyof IspcEligibilityInput,string>>={territory:'Exerce a actividade em território nacional',organizedRequired:'Está obrigado a possuir contabilidade organizada para os impostos sobre o rendimento',sharesInIspc:'Tem participações noutras sociedades comerciais em ISPC',sharesAnonymous:'Tem participações em sociedades anónimas ou sociedades cujos sócios não são identificáveis',otherActivities:'Exerce outras actividades fora dos âmbitos identificados',unlistedServices:'Presta serviços fora dos previstos na Lei',forecastConfirmed:'Previsão da declaração de início confirmada pela AT (ou pressuposto expresso na simulação)',generalRegimeChosen:'Optou pela aplicação de IVA/IRPS/IRPC com permanência mínima de três anos',generalThreeYearsCompleted:'Já cumpriu o período mínimo de três anos dessa opção'};
export function SimulationIspcEligibility({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState(''),[reusePreview,setReusePreview]=useState<ReturnType<typeof ispcReuseDiff>|null>(null);if(draft.fiscal_component!=='ispc')return null;
let book:IspcEligibilityBook;try{book=ispcEligibilityBook(draft);}catch(e){return<p role="alert">{String(e)}</p>;}
const i=book.input,save=(next:IspcEligibilityBook)=>{try{onChange('modelo_a_snapshot',saveIspcEligibilityBook(draft,next));setError('');}catch(e){setError(String(e));}},change=(patch:Partial<IspcEligibilityInput>)=>save({...book,input:{...i,...patch}}),diff=ispcReuseDiff(draft,book),service=i.activities.some(a=>['services12','liberal15'].includes(a)),liberal=i.activities.includes('liberal15'),earlyOutside=i.activities.includes('other')||i.territory==='no'||i.mode==='occasional';
const fact=(field:keyof typeof factLabels)=><label className="block" key={field}>{factLabels[field]}<select className="block rounded border p-2" value={String(i[field])} onChange={e=>change({[field]:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>;
const text=(field:keyof IspcEligibilityInput,label:string,type='text')=><label className="block" key={field}>{label}<input className="block rounded border p-2" type={type} value={String(i[field])} onChange={e=>change({[field]:e.target.value})}/></label>;
return<section aria-label="ISPC — enquadramento e opção" className="space-y-3 rounded border p-4"><h4 className="font-semibold">ISPC — enquadramento e opção</h4>
<p>Avaliação preliminar para 2026, em MZN, segundo a Lei 9/2025. Distingue condições de acesso, opção e cálculo do imposto. Guarde esta avaliação e prossiga no apuramento trimestral abaixo.</p>
{error&&<p role="alert">{error}</p>}
{diff.length>0&&<button type="button" className="underline" onClick={()=>setReusePreview(diff)}>Conferir dados do perfil e da actividade para reutilizar</button>}
{reusePreview&&<aside className="rounded border p-3"><p>A adopção altera as entradas deste cenário. O resultado guardado passa a histórico até novo cálculo; os outros livros e a opção registada são preservados.</p>{reusePreview.map(v=><p key={v.field}>{({personType:'Tipo de pessoa',establishments:'Estabelecimentos',activityDescription:'Actividade',entityRef:'Entidade'} as Record<string,string>)[v.field]??v.field}: {v.before||'Por preencher'} → {v.after}</p>)}<button type="button" onClick={()=>{change(Object.fromEntries(reusePreview.map(v=>[v.field,v.after])));setReusePreview(null);}}>Confirmar adopção destes dados</button><button type="button" onClick={()=>setReusePreview(null)}>Manter as minhas entradas</button></aside>}
<div className="grid gap-3 md:grid-cols-2">{text('entityRef','Entidade de referência (reutilizável; sem NUIT obrigatório para preparar)')}
<label>Tipo de pessoa<select className="block rounded border p-2" value={i.personType} onChange={e=>change({personType:e.target.value as IspcEligibilityInput['personType']})}><option value="">Por identificar</option><option value="singular">Pessoa singular</option><option value="collective">Pessoa colectiva</option></select></label>
{text('assessmentDate','Data de avaliação','date')}
<label>Natureza dos dados<select className="block rounded border p-2" value={i.origin} onChange={e=>change({origin:e.target.value as IspcEligibilityInput['origin']})}><option value="projected">Pressupostos da simulação</option><option value="effective">Dados efectivos declarados</option></select></label>
<label>Moeda dos valores ISPC<select className="block rounded border p-2" value={i.currency} onChange={e=>change({currency:e.target.value})}><option value="">Por identificar</option><option value="MZN">MZN</option>{i.currency&&i.currency!=='MZN'&&<option value={i.currency}>{i.currency} — fora da cobertura deste cálculo</option>}</select></label>
<label>Âmbito da preparação<select className="block rounded border p-2" value={i.mode} onChange={e=>change({mode:e.target.value as IspcEligibilityInput['mode']})}><option value="regular">Actividade habitual</option><option value="occasional">Operação ocasional — percurso próprio</option></select></label>
{fact('territory')}</div>
<fieldset className="space-y-2 rounded border p-3"><legend>Actividades do contribuinte</legend><p>Identifique todas as actividades, incluindo as exercidas fora desta oportunidade. Não inferimos o regime pelo sector ou pela nacionalidade.</p>{ispcActivities.map(([kind,label])=><label className="block" key={kind}><input type="checkbox" checked={i.activities.includes(kind)} onChange={e=>change({activities:e.target.checked?[...i.activities,kind]:i.activities.filter(a=>a!==kind)})}/> {label}</label>)}{text('activityDescription','Descrição da actividade e natureza dos serviços, quando existam')}</fieldset>
{!earlyOutside&&<><fieldset className="grid gap-3 rounded border p-3 md:grid-cols-2"><legend>Volume anual de referência</legend><label>Referência de acesso<select className="block rounded border p-2" value={i.basis} onChange={e=>change({basis:e.target.value as IspcEligibilityInput['basis'],...(!i.referenceYear?{referenceYear:e.target.value==='previous_year'?'2025':e.target.value==='start_forecast'?'2026':''}:{})})}><option value="">Por identificar</option><option value="previous_year">Volume de negócios do ano anterior</option><option value="start_forecast">Previsão da declaração de início de actividade</option></select></label>{text('referenceYear','Ano do valor de referência')}{text('annualReference','Volume anual de referência em MZN')}{text('annualReferenceRef','Origem do valor ou pressuposto (opcional)')}<p className="md:col-span-2">Não copiar receita trimestral ou do ano em curso como receita do ano anterior. Alterar a origem não reinterpreta o valor já editado; reveja o montante e o ano.</p>{i.basis==='start_forecast'&&<>{fact('forecastConfirmed')}{text('forecastConfirmationRef','Referência da confirmação da previsão, se efectiva')}</>}</fieldset>
<fieldset className="space-y-3 rounded border p-3"><legend>Condições aplicáveis ao contribuinte</legend>{text('establishments','Número de estabelecimentos da actividade, incluindo fora deste dossier')}{fact('organizedRequired')}{fact('sharesInIspc')}{fact('sharesAnonymous')}{fact('otherActivities')}{service&&fact('unlistedServices')}{liberal&&<>{text('liberalDaysSameEntity','Maior duração anual dos serviços à mesma entidade, em dias')}{text('liberalClientRef','Referência do cliente/contrato ou pressuposto da duração')}<p>O limite de 183 dias refere-se aos serviços do artigo 8(1)c. A permanência liberal tem limite próprio de cinco anos; a contagem transitória começa em 2026.</p></>}{fact('generalRegimeChosen')}{i.generalRegimeChosen==='yes'&&<>{fact('generalThreeYearsCompleted')}{text('generalRegimeRef','Referência da opção e do cumprimento dos três anos')}</>}</fieldset>
<fieldset className="space-y-2 rounded border p-3"><legend>Opção — separada da compatibilidade</legend><label>Situação da opção<select className="block rounded border p-2" value={i.option} onChange={e=>change({option:e.target.value as IspcEligibilityInput['option']})}><option value="preparation">Em preparação — sem adesão automática</option><option value="opted">Opção registada no documento/cenário</option><option value="not_opted">Não optou pelo ISPC</option></select></label>{i.option==='opted'&&<>{text('optionReference','Referência da opção')}{text('optionDate','Data da opção','date')}</>}</fieldset></>}
<button type="button" className="rounded bg-emerald-800 p-2 text-white" onClick={()=>{try{save(recordIspcEligibility(draft,book));}catch(e){setError(String(e));}}}>Avaliar e guardar enquadramento ISPC</button>
{book.result&&<p role="status">{ispcEligibilityCurrent(draft,book)?'Resultado correspondente às entradas guardadas.':'Entradas alteradas; resultado histórico preservado. Reveja e guarde nova avaliação.'}</p>}
{ispcEligibilityReportRows(draft).map((r,index)=><p key={index}><strong>{r[1]}:</strong> {r[2]}<small className="block">{r[3]}</small></p>)}
</section>;
}
@@ -0,0 +1,18 @@
import {useState} from 'react';
import {ispcEligibilityBook,ispcEligibilityCurrent} from '@/lib/ispc-eligibility';
import {ispcQuarterBook,saveIspcQuarterBook,recordIspcQuarter,ispcQuarterReportRows,type IspcQuarterInput,type IspcQuarterBook} from '@/lib/ispc-quarter';
export function SimulationIspcQuarter({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');if(draft.fiscal_component!=='ispc')return null;
try{if(ispcEligibilityBook(draft).input.mode==='occasional')return<p>Actividade habitual:campos trimestrais conservados no histórico. Use o percurso de operações ocasionais próprias abaixo.</p>;}catch{/* Preserve the existing explicit recovery error below. */}
let book:IspcQuarterBook;try{book=ispcQuarterBook(draft);}catch(e){return<p role="alert">{String(e)}</p>;}
const i=book.input,save=(b:IspcQuarterBook)=>{try{onChange('modelo_a_snapshot',saveIspcQuarterBook(draft,b));setError('');}catch(e){setError(String(e));}},change=(patch:Partial<IspcQuarterInput>)=>save({...book,input:{...i,...patch}});
let service=false,ready=false;try{const e=ispcEligibilityBook(draft);ready=ispcEligibilityCurrent(draft,e)&&e.result?.status==='compatible';service=e.input.activities.some(a=>['services12','liberal15'].includes(a));}catch{/* Show explicit preparation issue below, never fabricate eligibility. */}
return<section aria-label="Apuramento trimestral ISPC" className="space-y-3 rounded border p-4"><h4>ISPC — apuramento trimestral</h4><p>Reutiliza o enquadramento e a opção guardados. Declare o volume de todas as actividades do sujeito passivo em MZN; custos e IVA de aquisições não reduzem esta base. Dados em falta permanecem indeterminados.</p>{!ready&&<p>Reveja e guarde primeiro a avaliação de enquadramento acima. As entradas trimestrais e o histórico ficam conservados.</p>}{error&&<p role="alert">{error}</p>}
<label className="block">Ano<input className="block rounded border p-2" value={i.year} onChange={e=>change({year:e.target.value})}/></label><label className="block">Trimestre<select className="block rounded border p-2" value={i.quarter} onChange={e=>change({quarter:e.target.value})}>{['1','2','3','4'].map(q=><option key={q} value={q}>{q} — {['Janeiro a Março','Abril a Junho','Julho a Setembro','Outubro a Dezembro'][Number(q)-1]}</option>)}</select></label>
<label className="block">Âmbito do volume<select className="block rounded border p-2" value={i.coverage} onChange={e=>change({coverage:e.target.value as IspcQuarterInput['coverage']})}><option value="">Por confirmar</option><option value="all_taxpayer_activity">Todas as actividades do sujeito passivo, sem repetir oportunidades</option></select></label>
<div className="grid gap-3 md:grid-cols-2">{i.sales.map((v,n)=>(n<Number(i.quarter)||i.annualBandOrigin==='closed_year'&&!service)&&<fieldset key={n} className="space-y-2 rounded border p-2"><legend>Trimestre {n+1}{n+1===Number(i.quarter)?' — a apurar':' — acumulado anterior'}</legend><label className="block">Volume T{n+1} em MZN<input className="block rounded border p-2" inputMode="decimal" value={v} onChange={e=>{const a=[...i.sales] as IspcQuarterInput['sales'];a[n]=e.target.value;change({sales:a});}}/></label><label className="block">Suporte ou pressuposto T{n+1}<input className="block rounded border p-2" value={i.salesRefs[n]} onChange={e=>{const a=[...i.salesRefs] as IspcQuarterInput['salesRefs'];a[n]=e.target.value;change({salesRefs:a});}}/></label></fieldset>)}</div>
{!service&&<fieldset className="space-y-2 rounded border p-3"><legend>Escalão anual da actividade — distinto do volume de acesso</legend><p>Os limites de 1.000.000 / 2.500.000 / 4.000.000 MZN são anuais. A taxa do escalão é aplicada à base do trimestre; não dividir os limites por quatro. O excesso anual tem taxa própria de 20%.</p><label className="block">Volume anual 2026 para o escalão<input className="block rounded border p-2" value={i.annualBandVolume} onChange={e=>change({annualBandVolume:e.target.value})}/></label><label className="block">Origem da referência anual<select className="block rounded border p-2" value={i.annualBandOrigin} onChange={e=>change({annualBandOrigin:e.target.value as IspcQuarterInput['annualBandOrigin']})}><option value="">Por identificar</option><option value="forecast">Previsão expressa — simulação</option><option value="closed_year">Ano encerrado — reconciliar quatro trimestres</option></select></label><label className="block">Suporte da referência anual<input className="block rounded border p-2" value={i.annualBandRef} onChange={e=>change({annualBandRef:e.target.value})}/></label></fieldset>}
<button type="button" className="rounded bg-emerald-800 p-2 text-white" onClick={()=>{try{save(recordIspcQuarter(draft,book));}catch(e){setError(String(e));}}}>Calcular e guardar apuramento trimestral ISPC</button>
{ispcQuarterReportRows(draft).map((r,n)=><p key={n}><strong>{r[1]}:</strong> {r[2]}<small className="block">{r[3]}</small></p>)}
<p>Preparação para a declaração periódica dos artigos 10/11. Este cálculo não submete formulários nem efectua pagamentos. Retenção na fonte em aquisições ocasionais tem registo e base próprios.</p></section>;
}
@@ -0,0 +1,28 @@
import {useState} from 'react';
import {ispcEligibilityBook} from '@/lib/ispc-eligibility';
import {ispcWithholdingBook} from '@/lib/ispc-withholding';
import {decimalFraction,addFractions} from '@/lib/fiscal-rational';
import {ispcResidualBook,saveIspcResidualBook,recordIspcResidual,priorOccasionalSettlement,ispcResidualReportRows,ispcFormalPreparationHtml,type ResidualKind} from '@/lib/ispc-residuals';
export function SimulationIspcResiduals({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');if(draft.fiscal_component!=='ispc')return null;
try{
const own=ispcResidualBook(draft,'occasional'),acq=ispcResidualBook(draft,'acquisitions'),formal=ispcResidualBook(draft,'formalities'),e=ispcEligibilityBook(draft),w=ispcWithholdingBook(draft);let above=false;try{const sum=addFractions([decimalFraction(w.input.base),decimalFraction(w.input.priorAnnualPurchases)]);above=BigInt(sum.numerator)>2500000n*BigInt(sum.denominator);}catch{/* Unknown is still handled in existing acquisition panel. */}
const book=(k:ResidualKind)=>k==='occasional'?own:k==='acquisitions'?acq:formal;
const change=(k:ResidualKind,p:Record<string,string>)=>{const b=book(k);onChange('modelo_a_snapshot',saveIspcResidualBook(draft,{...b,input:{...b.input,...p}}));};
const field=(k:ResidualKind,n:string,label:string,type='text')=><label key={n} className="block">{label}<input className="block rounded border p-2" type={type} value={book(k).input[n]??''} onChange={ev=>change(k,{[n]:ev.target.value})}/></label>;
const select=(k:ResidualKind,n:string,label:string,options:Array<[string,string]>)=><label key={n} className="block">{label}<select className="block rounded border p-2" value={book(k).input[n]??''} onChange={ev=>change(k,{[n]:ev.target.value})}>{options.map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label>;
const yesno=(k:ResidualKind,n:string,label:string)=>select(k,n,label,[['','Por esclarecer'],['yes','Sim'],['no','Não']]);
const save=(k:ResidualKind)=>{try{onChange('modelo_a_snapshot',saveIspcResidualBook(draft,recordIspcResidual(draft,book(k))));setError('');}catch(err){setError(String(err));}};
const activities:Array<[string,string]>=[['','Por identificar'],['forestry','Silvícola'],['fishery','Pesqueira'],['livestock','Pecuária'],['agriculture','Agrícola'],['poultry','Avícola'],['beekeeping','Apícola'],['other','Outra—fora do recorte ocasional']];
return<section aria-label="ISPC — operações ocasionais, limite e formalidades" className="space-y-4">{error&&<p role="alert">{error}</p>}
{e.input.mode==='occasional'&&<section className="space-y-3 rounded border p-4"><h4>Operações ocasionais próprias</h4><p>Percurso do vendedor ocasional, distinto da retenção feita pelo comprador. Uma retenção liberatória comprovada não gera segunda liquidação própria.</p>{select('occasional','personType','Tipo de pessoa destas operações',[['','Por identificar'],['singular','Pessoa singular'],['collective','Pessoa colectiva']])}{select('occasional','origin','Natureza dos dados',[['projected','Pressupostos de simulação'],['effective','Factos efectivos declarados']])}{field('occasional','currency','Moeda—MZN')}{field('occasional','operationDate','Data das operações','date')}{select('occasional','quarter','Trimestre2026',[['','Por identificar'],['1','1'],['2','2'],['3','3'],['4','4']])}{yesno('occasional','territory','Operação realizada em território nacional')}{yesno('occasional','noHabitual','Não exerce actividade habitual')}{yesno('occasional','sporadic','Acto não previsível nem reiterado')}{select('occasional','activity','Natureza da operação',activities)}{field('occasional','reference','Documentos ou pressupostos da operação')}{field('occasional','amount','Volume de todas estas operações do trimestre em MZN')}{select('occasional','settlement','Via aplicável',[['','Por identificar'],['self','Liquidação própria por opção ISPC'],['withheld','Retenção liberatória documentada pelo adquirente']])}
{own.input.settlement==='self'&&<>{yesno('occasional','allQuarterOperations','Inclui todas as operações ocasionais do sujeito passivo no trimestre')}{field('occasional','priorYearTurnover','Volume de referência2025 para acesso, incluindo zero expresso')}{field('occasional','priorYearRef','Suporte da referência2025')}{yesno('occasional','organizedRequired','Obrigado a contabilidade organizada para impostos sobre rendimento')}{select('occasional','option','Opção para estas operações',[['preparation','Em preparação—apenas cenário'],['opted','Opção documentada'],['not_opted','Não optou']])}{own.input.option==='opted'&&<>{field('occasional','optionRef','Referência da opção')}{field('occasional','optionDate','Data da opção','date')}</>}{field('occasional','annual2026','Volume anual2026 para escalão')}{select('occasional','annualOrigin','Origem do volume anual2026',[['','Por identificar'],['forecast','Previsão—cenário'],['closed_year','Volume anual encerrado documentado']])}{field('occasional','annualRef','Suporte ou pressuposto do volume anual2026')}{field('occasional','priorInYear','Volume de operações anteriores no ano2026')}{priorOccasionalSettlement(own)&&<><p>Existe retenção liberatória guardada para esta operação. A mudança de via não a apaga nem gera uma segunda prestação.</p>{yesno('occasional','withholdingCorrected','Retenção anterior corrigida/anulada segundo documento externo')}{field('occasional','withholdingCorrectionRef','Referência externa da correcção da retenção anterior')}</>}</>}
{own.input.settlement==='withheld'&&<>{yesno('occasional','buyerIspc','Adquirente sujeito passivo ISPC')}{yesno('occasional','unregistered','Vendedor não inscrito para tributação')}{field('occasional','buyerAnnualPurchases','Aquisições globais anuais do adquirente, incluindo estas operações')}{field('occasional','withheldActual','Montante efectivamente retido em MZN')}{field('occasional','withheldRef','Documento da retenção liberatória')}</>}
<button type="button" className="rounded border p-2" onClick={()=>save('occasional')}>Calcular e guardar operações ocasionais</button></section>}
{(above||acq.result)&&<section className="space-y-3 rounded border p-4"><h4>Aquisições acima do limite global</h4><p>Reutiliza a aquisição, os seus documentos e o acumulado global guardados acima. A parcela excedente não recebe automaticamente a taxa de 5% nem a taxa de 20% do excesso de vendas ISPC.</p>{select('acquisitions','route','Tratamento próprio da parcela excedente',[['unknown','Por identificar—mostrar parcelas sem total presumido'],['ispc_supplier','Fornecedor com opção ISPC aplicável'],['irps_isolated','Acto isolado sujeito a IRPS57(2)k']])}{acq.input.route==='ispc_supplier'&&field('acquisitions','supplierOptionRef','Referência da opção/registo do fornecedor e operações abrangidas')}{acq.input.route==='irps_isolated'&&<>{yesno('acquisitions','noIspcOnExcess','Sem opção ISPC aplicável a esta parcela, segundo documento indicado')}{yesno('acquisitions','isolatedAct','Acto isolado qualificado pelo artigo8(3h,4)doIRPS')}{yesno('acquisitions','incomeInMoz','Rendimento obtido em Moçambique')}{field('acquisitions','grossExcess','Rendimento ilíquido da parcela excedente em MZN—sem dedução de custos ou IVA')}{field('acquisitions','grossRef','Suporte da base ilíquida')}{field('acquisitions','reference','Suporte da classificação IRPS desta parcela')}</>}<button type="button" className="rounded border p-2" onClick={()=>save('acquisitions')}>Calcular e guardar parcela excedente</button></section>}
<section className="space-y-3 rounded border p-4"><h4>Formalidades de2026—preparação do B–Geral</h4><p>O Comunicado AT9/2026indica o B–Geral durante a adaptação do sistema, com pagamentos em Janeiro, Abril, Julho e Outubro. O Modelo30disponível conserva campos antigos; não os aplicamos a2026. Esta preparação não submete nem paga à AT.</p>{select('formalities','sourceKind','Cálculo a preparar',[['quarter','Trimestral habitual'],['occasional','Operações ocasionais próprias'],['acquisitions','Retenção da parcela excedente qualificada']])}{formal.input.sourceKind==='acquisitions'&&field('formalities','retentionFormRef','Modelo/código e instrução para entrega das retenções ISPC/IRPS, separados do imposto próprio')}{field('formalities','name','Nome/designação social—quadro5')}{field('formalities','nuit','NUIT—quadro3')}{field('formalities','fiscalArea','Área Fiscal/UGC—quadro3')}{field('formalities','address','Domicílio fiscal—quadro6')}{select('formalities','declaration','Tipo de declaração—quadro1',[['initial','Inicial'],['substitution','Substituição']])}{field('formalities','formMonth','Mês a inscrever no quadro2—não presumido pelo mês de pagamento')}{field('formalities','formYear','Ano a inscrever no quadro2')}{field('formalities','formPeriodRef','Instrução/correspondência usada para o período do quadro2')}{select('formalities','interestSituation','Juros compensatórios—quadro10',[['','Por esclarecer'],['none','Sem juros, segundo suporte indicado'],['amount','Montante documentado']])}{formal.input.interestSituation==='amount'&&field('formalities','interestAmount','Montante de juros documentado')}{field('formalities','interestRef','Suporte da situação dos juros')}{select('formalities','externalStatus','Histórico externo declarado',[['preparation','Em preparação'],['submitted','Submetido'],['received','Recebido pela AT'],['paid','Pagamento efectuado']])}{formal.input.externalStatus!=='preparation'&&<>{field('formalities','externalRef','Referência externa')}{field('formalities','externalDate','Data do acto externo','date')}</>}
<button type="button" className="rounded border p-2" onClick={()=>save('formalities')}>Preparar e guardar campos B–Geral</button><button type="button" className="rounded border p-2" onClick={()=>{try{const html=ispcFormalPreparationHtml(draft),url=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=url;a.download='ISPC-preparacao-B-Geral.html';a.click();URL.revokeObjectURL(url);setError('');}catch(err){setError(String(err));}}}>Descarregar preparação B–Geral</button></section>
{ispcResidualReportRows(draft).map((r,n)=><p key={n}><strong>{r[1]}:</strong> {r[2]}<small className="block">{r[3]}</small></p>)}
</section>;
}catch(err){return<p role="alert">{String(err)}</p>;}
}
@@ -0,0 +1,7 @@
import {ispcEligibilityBook} from '@/lib/ispc-eligibility';
import {ispcWithholdingBook,saveIspcWithholdingBook,recordIspcWithholding,ispcWithholdingReportRows,type IspcWithholdingInput} from '@/lib/ispc-withholding';
export function SimulationIspcWithholding({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
if(draft.fiscal_component!=='ispc')return null;
try{if(ispcEligibilityBook(draft).input.mode==='occasional')return<p>Retenções do adquirente:entradas preservadas. Neste percurso de vendedor ocasional,registe a retenção recebida no quadro próprio abaixo.</p>;}catch{/* Existing recovery error stays explicit. */}
try{const b=ispcWithholdingBook(draft),i=b.input,change=(p:Partial<IspcWithholdingInput>)=>onChange('modelo_a_snapshot',saveIspcWithholdingBook(draft,{...b,input:{...i,...p}}));return<section aria-label="Retenções ISPC" className="space-y-3 rounded border p-4"><h4>ISPC — retenção em aquisições ocasionais</h4><label className="block">Existem aquisições abrangidas pelo artigo 12(3–4)?<select value={i.applicable} onChange={e=>change({applicable:e.target.value as IspcWithholdingInput['applicable']})}><option value="">Por esclarecer</option><option value="no">Não</option><option value="yes">Sim — conferir condições</option></select></label>{i.applicable==='yes'&&<><p>Registe apenas aquisições do mesmo trimestre. O acumulado anterior cobre todas as aquisições desta via no ano e evita reutilizar o limite por fornecedor ou oportunidade.</p>{(['quarter','base','priorAnnualPurchases','reference'] as const).map(k=><label className="block" key={k}>{{quarter:'Trimestre de 2026',base:'Base de aquisições deste trimestre em MZN',priorAnnualPurchases:'Aquisições globais anteriores de 2026 em MZN',reference:'Suporte das aquisições e condições'}[k]}<input className="block rounded border p-2" value={i[k]} onChange={e=>change({[k]:e.target.value})}/></label>)}{(['naturalOccasional','unregistered','related']as const).map(k=><label className="block" key={k}>{{naturalOccasional:'Fornecedor pessoa singular ocasional abrangido por 3(3–4)',unregistered:'Fornecedor não inscrito para tributação',related:'Bens relacionados com a actividade do adquirente'}[k]}<select value={i[k]} onChange={e=>change({[k]:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>)}<label className="block">Actividade da operação ocasional<select value={i.activity} onChange={e=>change({activity:e.target.value as IspcWithholdingInput['activity']})}>{[['','Por identificar'],['forestry','Silvícola'],['fishery','Pesqueira'],['livestock','Pecuária'],['agriculture','Agrícola'],['poultry','Avícola'],['beekeeping','Apícola'],['other','Outra']].map(([v,l])=><option key={v} value={v}>{l}</option>)}</select></label></>}<button type="button" className="rounded border p-2" onClick={()=>onChange('modelo_a_snapshot',saveIspcWithholdingBook(draft,recordIspcWithholding(draft,b)))}>Conferir e guardar retenção ISPC</button>{ispcWithholdingReportRows(draft).map((r,n)=><p key={n}><strong>{r[1]}:</strong> {r[2]}<small className="block">{r[3]}</small></p>)}</section>;}catch(e){return<p role="alert">{String(e)}</p>;}
}
+31
View File
@@ -0,0 +1,31 @@
import {selectFx,fxSelectionKey,type FxSelection} from './iva-fx-selection.ts';
import {currencyEventBook,newCurrencyEvent} from './iva-currency-events.ts';
import {convertCents} from './business-financial-plan.ts';
import {decimalFraction,fraction,type FiscalFraction} from './fiscal-rational.ts';
import {closureFingerprint} from './iva-closure.ts';
export type IrpcFxLink={id:string;fingerprint:string};
export type IrpcFxAmount={currency:string;fxSelection?:FxSelection;fxLink?:IrpcFxLink};
export type IrpcFxEvidence={originalAmount:string;originalCurrency:string;convertedCurrency:'MZN';column:string;rate:string;date:string;direction:string;source:string;selectionKey:string;rounding:string};
export function irpcFxSources(d:Record<string,unknown>){return currencyEventBook(d).rows.filter(r=>r.fxSelection).map(r=>({id:r.id,label:`${r.description||r.id} — ${r.sourceCurrency} — ${r.fxSelection?.applied?.rate??'por aplicar'}`,fingerprint:closureFingerprint(r),selection:structuredClone(r.fxSelection!)}));}
export function irpcFxDependency(d:Record<string,unknown>,input:IrpcFxAmount):string{
if(input.currency==='MZN'||!input.fxLink)return'';
const source=irpcFxSources(d).find(s=>s.id===input.fxLink!.id);
return !source?'Selecção cambial de origem indisponível;vínculo e histórico conservados.':source.fingerprint!==input.fxLink.fingerprint?'Selecção cambial de origem alterada;compare a nova selecção antes de a aplicar às retenções.':'';
}
export function irpcFxRow(id:string,input:IrpcFxAmount){const s=input.fxSelection,a=s?.applied;return{...newCurrencyEvent(id,'MZN'),sourceCurrency:input.currency,fxSelection:s,fxDirection:s?.direction??'',fxRate:a?.rate??'',fxDate:a?.date??'',fxSource:a?.source??''};}
export function convertIrpcAmount(d:Record<string,unknown>,amount:string,input:IrpcFxAmount):{value:FiscalFraction;evidence:IrpcFxEvidence|null}{
const original=decimalFraction(amount);if(input.currency==='MZN')return{value:original,evidence:null};
const issue=irpcFxDependency(d,input);if(issue)throw Error(issue);
const s=input.fxSelection;if(!s)throw Error('Reutilize ou aplique a selecção cambial já entregue:moeda original,boletim,coluna,data e sentido;sem taxa actual por defeito.');
const selected=selectFx(s),a=s.applied;
if(!a||a.selectionKey!==fxSelectionKey(s)||a.rate!==selected.rate||a.date!==selected.date||a.source!==selected.source||a.column!==selected.column||s.sourceCurrency!==input.currency)throw Error('Selecção cambial alterada,não confirmada ou de outra moeda;use a conferência e confirmação existentes,sem recalcular históricos.');
const [whole,places='']=selected.rate.split('.'),rate=BigInt(whole+places.padEnd(8,'0')),scale=100000000n;
const micro=BigInt(original.numerator)*1000000n/BigInt(original.denominator);
const converted=s.direction==='mzn_per_unit'?convertCents(micro,rate,scale):convertCents(micro,scale,rate);
return{value:fraction(converted,1000000n),evidence:{originalAmount:amount,originalCurrency:input.currency,convertedCurrency:'MZN',column:selected.column,rate:selected.rate,date:selected.date,direction:s.direction,source:selected.source,selectionKey:a.selectionKey,rounding:'Mesmo convertCents entregue;conversão à unidade de0,000001MZN;apresentação separada,não regra nova de arredondamento do imposto.'}};
}
export function irpcFxEvidenceLabel(e:IrpcFxEvidence):string{const column=({buy:'Compra',sell:'Venda',mean:'Média de referência BM',exception:'Excepção fiscal identificada'} as Record<string,string>)[e.column]??e.column;const direction=e.direction==='mzn_per_unit'?'MZN por '+e.originalCurrency:e.originalCurrency+' por MZN';return`Original: ${e.originalAmount} ${e.originalCurrency}; coluna: ${column}; taxa: ${e.rate}; cotação: ${direction}; data cambial: ${e.date}; fonte: ${e.source.split(';perspectiva:')[0]}. Montante e selecção originais conservados.`;}
export function updateIrpcFx(input:IrpcFxAmount,selection:FxSelection):Partial<IrpcFxAmount>{return{fxSelection:selection,fxLink:input.fxSelection&&fxSelectionKey(input.fxSelection)===fxSelectionKey(selection)?input.fxLink:undefined};}
+69
View File
@@ -0,0 +1,69 @@
import type {IrpcBook} from './irpc-withholdings.ts';
import {addFractions,decimalFraction,fraction,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export type IrpcInterestRule={
annualRate:string;rateSource:string;fiscalBasis:string;validFrom:string;validTo:string;
dayBasis:''|'365'|'366'|'actual_year';dayBasisRef:string;
rounding:''|'total_cent_half_up'|'total_cent_down';roundingRef:string;
retention:''|'withheld'|'not_withheld';occurrenceRef:string;
};
export const newIrpcInterestRule=():IrpcInterestRule=>({annualRate:'',rateSource:'',fiscalBasis:'',validFrom:'',validTo:'',dayBasis:'',dayBasisRef:'',rounding:'',roundingRef:'',retention:'',occurrenceRef:''});
export const irpcInterestVersion='IRPC-interest/1';
export type IrpcInterestSegment={from:string;to:string;days:number;denominator:number;principal:FiscalFraction;interest:FiscalFraction};
export type IrpcInterestCalculation={version:string;rows:Array<{id:string;document:string;segments:IrpcInterestSegment[];exact:FiscalFraction}>;pending:string[];exact:FiscalFraction|null;total:FiscalFraction|null;rule:IrpcInterestRule;dueDate:string;liquidationDate:string;source:string};
const validDate=(s:string)=>/^20\d{2}-\d{2}-\d{2}$/.test(s)&&Number.isFinite(Date.parse(s))&&new Date(s).toISOString().slice(0,10)===s;
const next=(s:string)=>new Date(Date.parse(s)+86400000).toISOString().slice(0,10);
const less=(a:FiscalFraction,b:FiscalFraction)=>BigInt(a.numerator)*BigInt(b.denominator)<BigInt(b.numerator)*BigInt(a.denominator);
const zero=()=>fraction(0n,1n);
export function validateIrpcInterestRule(r:IrpcInterestRule){
if(!r||Object.keys(newIrpcInterestRule()).some(k=>typeof r[k as keyof IrpcInterestRule]!=='string')||!['','365','366','actual_year'].includes(r.dayBasis)||!['','total_cent_half_up','total_cent_down'].includes(r.rounding)||!['','withheld','not_withheld'].includes(r.retention))throw Error('Parâmetros de juros não recuperáveis;originais conservados.');
}
// No fiscal rate, annual day basis or rounding convention is supplied by default.
// Complete references describe the parameters of this case, not a global 2026 rate.
export function calculateIrpcInterest(b:IrpcBook,current:boolean,period:string,dueDate:string,dueReference:string,liquidationDate:string,r:IrpcInterestRule):IrpcInterestCalculation{
validateIrpcInterestRule(r);
const pending:string[]=[],rows:IrpcInterestCalculation['rows']=[];
const result=(exact:FiscalFraction|null=null,total:FiscalFraction|null=null):IrpcInterestCalculation=>({version:irpcInterestVersion,rows,pending,exact,total,rule:structuredClone(r),dueDate,liquidationDate,source:'Decreto9/2008 art35(1/2):dia imediato ao prazo até pagamento/liquidação;25(1):parâmetro na data da liquidação. Taxa,base anual e arredondamento apenas conforme referências do caso. Sem parâmetro fiscal2026 pré-definido,sem MIMO/Prime presumidos. Mora e retenção por conta não efectuada conservam regra própria.'});
if(!current||!b.result)pending.push('Retenções sem cálculo actual.');
if(!/^2026-(0[1-9]|1[0-2])$/.test(period)||!validDate(dueDate)||!dueReference.trim()||!validDate(liquidationDate)||liquidationDate<=dueDate||dueDate<period+'-01')pending.push('Identifique período,prazo documentado e data de liquidação posterior ao prazo;sem prazo/calendário presumidos.');
if(!validDate(r.validFrom)||!validDate(r.validTo)||r.validFrom>r.validTo||liquidationDate<r.validFrom||liquidationDate>r.validTo)pending.push('Parâmetro fora da versão/período aplicável à data de liquidação.');
const labels:Record<string,string>={rateSource:'fonte da taxa anual final',fiscalBasis:'fundamento fiscal aplicável',dayBasisRef:'fonte da base anual',roundingRef:'fonte do arredondamento',occurrenceRef:'documento da retenção/ocorrência'};
for(const[k,label]of Object.entries(labels))if(!r[k as keyof IrpcInterestRule].trim())pending.push('Falta '+label+'.');
if(!r.dayBasis||!r.rounding||!r.retention)pending.push('Regra de base anual,arredondamento e situação da retenção por identificar.');
let rate:FiscalFraction;
try{rate=decimalFraction(r.annualRate);if(!less(zero(),rate))throw Error();}catch{pending.push('Taxa anual final aplicável por identificar;sem zero ou taxa bancária de substituição.');return result();}
if(pending.length)return result();
const selected=b.result!.rows.filter(v=>v.direction==='paid'&&v.period===period&&v.treatment!=='dispensed');
if(!selected.length){pending.push('Sem retenções a entregar seleccionadas para este período.');return result();}
for(const v of selected){
const input=b.result!.inputs.find(i=>i.id===v.id);
if(!input||v.status!=='calculated'||!v.tax||less(v.tax,zero())||v.settled===null||!['none','complete'].includes(input.settlement)||!input.settlementRef.trim()||!v.nature){pending.push(v.id+': retenção/entregas não reconciliadas.');continue;}
if(v.nature==='on_account'&&r.retention!=='withheld'){pending.push(input.documentRef+': imposto por conta não retido exige o termo da declaração anual e responsabilidade correspondentes;fora deste cálculo.');continue;}
let payments:Array<{date:string;amount:FiscalFraction}>=[];
try{
const seen=new Set<string>();
payments=input.allocations.map(a=>{const p=b.result!.payments.find(p=>p.id===a.paymentId);if(!p||seen.has(p.id)||p.kind!=='remittance'||p.currency!=='MZN'||!validDate(p.date)||p.date<v.eventDate||!p.reference.trim()||p.date>liquidationDate)throw Error();seen.add(p.id);const amount=decimalFraction(a.amount);if(!less(zero(),amount))throw Error();return{date:p.date,amount};});
const allocated=addFractions(payments.map(p=>p.amount));if(less(v.tax,allocated)||!isEqual(allocated,v.settled))throw Error();
}catch{pending.push(input.documentRef+': comprovativos incoerentes ou posteriores à data de liquidação;conserve e reconcilie.');continue;}
let principal=subtractFractions(v.tax,addFractions(payments.filter(p=>p.date<=dueDate).map(p=>p.amount))),cursor=next(dueDate);
const segments:IrpcInterestSegment[]=[];
const charge=(to:string)=>{
if(cursor>to||!less(zero(),principal))return;
while(cursor<=to){
const year=Number(cursor.slice(0,4)),yearEnd=year+'-12-31',end=r.dayBasis==='actual_year'&&yearEnd<to?yearEnd:to;
const denominator=r.dayBasis==='actual_year'?(year%4===0&&(year%100!==0||year%400===0)?366:365):Number(r.dayBasis);
const days=(Date.parse(end)-Date.parse(cursor))/86400000+1;
const interest=fraction(BigInt(principal.numerator)*BigInt(rate.numerator)*BigInt(days),BigInt(principal.denominator)*BigInt(rate.denominator)*100n*BigInt(denominator));
segments.push({from:cursor,to:end,days,denominator,principal,interest});cursor=next(end);
}
};
const grouped=new Map<string,FiscalFraction[]>();for(const p of payments.filter(p=>p.date>dueDate))grouped.set(p.date,[...(grouped.get(p.date)??[]),p.amount]);
for(const[day,parts]of [...grouped].sort(([a],[c])=>a.localeCompare(c))){charge(day);principal=subtractFractions(principal,addFractions(parts));cursor=next(day);}
charge(liquidationDate);rows.push({id:v.id,document:input.documentRef,segments,exact:addFractions(segments.map(s=>s.interest))});
}
if(pending.length)return result();
const exact=addFractions(rows.map(r=>r.exact)),scaled=BigInt(exact.numerator)*100n,d=BigInt(exact.denominator);
let cents=scaled/d;if(r.rounding==='total_cent_half_up'&&scaled%d*2n>=d)cents++;
return result(exact,fraction(cents,100n));
}
function isEqual(a:FiscalFraction,b:FiscalFraction){return BigInt(a.numerator)*BigInt(b.denominator)===BigInt(b.numerator)*BigInt(a.denominator);}
+18
View File
@@ -0,0 +1,18 @@
import type {MrftaModel} from './irpc-mrfta.ts';
import {closureFingerprint} from './iva-closure.ts';
import {fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
// Groups are working sheets, never a decision to split an official declaration.
export function mrftaCases(m:MrftaModel){return m.lines.map(line=>({
key:closureFingerprint([m.period,line.rubric,line.rate,line.cer]),period:m.period,
rubric:line.rubric,rate:line.rate,cer:line.cer,ids:[...line.ids],documents:[...line.documents],references:[...line.references],
base:structuredClone(line.base),tax:structuredClone(line.tax),paid:structuredClone(line.paid),
pending:!line.cer||!/^\d+$/.test(line.cer)||!line.ids.every(id=>m.input.codes.find(c=>c.rowId===id)?.reference.trim())?'CER ou referência por corresponder;sem preenchimento presumido.':'CER transcrito com referência do caso;sem validação por catálogo oficial. Código provisório ou de simulação não é correspondência oficial.',
officialSeparation:'A correspondência de linhas/anexos/declaração oficial permanece por resolver quando há taxas/CER distintos na mesma rubrica.',
}));}
export function mrftaCaseHtml(m:MrftaModel,key:string):string{
const c=mrftaCases(m).find(c=>c.key===key);if(!c)throw Error('Caso MRFTA não encontrado;reprepare as entradas actuais.');
const esc=(v:unknown)=>String(v).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]!));
const money=(v:FiscalFraction|null)=>{if(!v)return'Indeterminado';const p=fractionPresentation(v);return(p.approximate?'≈':'')+p.decimal+' MZN';};
return `<!doctype html><html lang="pt"><meta charset="utf-8"><title>MRFTA — ficha de caso</title><body><h1>MRFTA — ficha de trabalho por caso</h1><p>Não é uma declaração autónoma,guia,anexo oficial ou submissão. Não funde taxas nem substitui o total do período.</p><p>Período:${esc(c.period)};rubrica:${esc(c.rubric)};taxa:${c.rate}%;CER:${esc(c.cer||'Por corresponder')}.</p><p>Base:${esc(money(c.base))};imposto:${esc(money(c.tax))};entregas:${esc(money(c.paid))}.</p><p>Documentos:${esc(c.documents.join(';'))};origens:${esc(c.ids.join(';'))}.</p><p>${esc(c.references.join(' | '))}</p><p>${esc(c.pending)}</p><p>${esc(c.officialSeparation)}</p><h2>Pendências do período — conservadas</h2><ul>${m.pending.map(p=>'<li>'+esc(p)+'</li>').join('')}</ul><small>${esc(m.source)}</small></body></html>`;
}
+96
View File
@@ -0,0 +1,96 @@
import {irpcInterestVersion,calculateIrpcInterest,validateIrpcInterestRule,type IrpcInterestRule,type IrpcInterestCalculation} from './irpc-interest.ts';
import type {IrpcBook, IrpcResult, IrpcRow} from './irpc-withholdings.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export type MrftaInput = {
version:1; period:string; declaration:''|'initial'|'replacement'; timing:''|'within'|'late';
nuit:string; name:string; commercialName:string; taxArea:string; address:string; contact:string;
completeness:''|'yes'|'no'; completenessRef:string;
otherRubrics:''|'none'|'pending'; otherRubricsRef:string;
codes:Array<{rowId:string;cer:string;reference:string}>;
interest:{mode:''|'assessment'|'timely';calculation?:'automatic';automatic?:IrpcInterestRule;period:string;amount:string;reference:string;date:string;dueDate:string;dueReference:string};
};
type MrftaLine={ids:string[];documents:string[];references:string[];rubric:string;cer:string;rate:number;base:FiscalFraction;tax:FiscalFraction;paid:FiscalFraction|null};
export type MrftaModel={automatic?:IrpcInterestCalculation;period:string;input:MrftaInput;lines:MrftaLine[];excluded:Array<{id:string;reason:string}>;pending:string[];principal:FiscalFraction;paid:FiscalFraction|null;interest:FiscalFraction|null;total:FiscalFraction|null;interestReason:string;source:string};
export type MrftaRecord={key:string;createdAt:string;model:MrftaModel};
export type MrftaStore={mrfta?:MrftaInput;mrftaResult?:MrftaRecord;mrftaHistory?:MrftaRecord[]};
export const newMrftaInput=():MrftaInput=>({version:1,period:'',declaration:'',timing:'',nuit:'',name:'',commercialName:'',taxArea:'',address:'',contact:'',completeness:'',completenessRef:'',otherRubrics:'',otherRubricsRef:'',codes:[],interest:{mode:'',period:'',amount:'',reference:'',date:'',dueDate:'',dueReference:''}});
export const mrftaSource='AT MRFTA19/39,PDF1–2:quadros1–7;um mês/ano por declaração. Decreto9/2008 arts25/35,PDF6/8,p121/123:juros compensatórios separados. MAIBOR12meses+2p.p.na data da liquidação;publicação MAIBOR descontinuada segundo BM. Sem substituir por MIMO/Prime nem presumir zero. CER exige referência específica;remissões antigas do M/39 não renumeradas no original.';
const date=(s:string)=>/^20\d{2}-\d{2}-\d{2}$/.test(s)&&Number.isFinite(Date.parse(s))&&new Date(s).toISOString().slice(0,10)===s;
const zero=()=>fraction(0n,1n);
const isZero=(v:FiscalFraction)=>BigInt(v.numerator)===0n;
const negative=(v:FiscalFraction)=>BigInt(v.numerator)<0n;
const labels:Record<string,string>={period:'mês/ano',declaration:'tipo de declaração',timing:'dentro/fora do prazo',nuit:'NUIT',name:'nome do sujeito passivo',taxArea:'área fiscal',address:'domicílio fiscal'};
export function validateMrfta(b:MrftaStore){
const i=b.mrfta;
if(i?.interest?.calculation!==undefined&&i.interest.calculation!=='automatic')throw Error('Método de cálculo de juros não recuperável.');
if(i?.interest?.automatic!==undefined)validateIrpcInterestRule(i.interest.automatic);
if(i&&(!['','none','pending'].includes(i.otherRubrics)||typeof i.otherRubricsRef!=='string'))throw Error('Âmbito de outras rubricas MRFTA não recuperável.');
if(i&&(i.version!==1||!['','initial','replacement'].includes(i.declaration)||!['','within','late'].includes(i.timing)||!['','yes','no'].includes(i.completeness)||['period','nuit','name','commercialName','taxArea','address','contact','completenessRef'].some(k=>typeof i[k as keyof MrftaInput]!=='string')||!Array.isArray(i.codes)||i.codes.some(c=>!c||['rowId','cer','reference'].some(k=>typeof c[k as keyof typeof c]!=='string'))||new Set(i.codes.map(c=>c.rowId)).size!==i.codes.length||!i.interest||!['','assessment','timely'].includes(i.interest.mode)||['period','amount','reference','date','dueDate','dueReference'].some(k=>typeof i.interest[k as keyof typeof i.interest]!=='string')))throw Error('Preparação MRFTA não recuperável;originais conservados.');
if(b.mrftaResult&&(!b.mrftaResult.model||typeof b.mrftaResult.key!=='string'||!Array.isArray(b.mrftaResult.model.lines)||!Array.isArray(b.mrftaResult.model.pending))||b.mrftaHistory!==undefined&&!Array.isArray(b.mrftaHistory))throw Error('Histórico MRFTA não recuperável.');
}
function rubric(r:IrpcRow,v:IrpcResult){
if(v.nature==='on_account')return r.kind==='rent'?'Taxa normal — Rendimentos prediais':r.kind==='capital'?'Taxa normal — Rendimentos de capitais e mais valias':null;
if(v.nature!=='definitive')return null;
return ({royalty:'IRPC liberatório — Actividade intelectual ou industrial / prestação de informações',equipment:'IRPC liberatório — Uso ou concessão do uso de equipamento',capital:'IRPC liberatório — Aplicação de capitais e rendimentos prediais',services:'IRPC liberatório — Comissões por intermediação de contratos ou prestação de serviços'} as Record<string,string>)[r.kind]??null;
}
function key(b:IrpcBook&MrftaStore,current:boolean){return JSON.stringify(['MRFTA-L5/1',b.result,b.mrfta,current,...(b.mrfta?.interest.mode===''&&b.mrfta?.interest.calculation==='automatic'?[irpcInterestVersion]:[])]);}
export function mrftaCurrent(b:IrpcBook&MrftaStore,current:boolean){return !!b.mrftaResult&&b.mrftaResult.key===key(b,current);}
export function prepareMrfta(b:IrpcBook&MrftaStore,current:boolean):MrftaModel{
validateMrfta(b);const i=b.mrfta??newMrftaInput(),pending:string[]=[],excluded:MrftaModel['excluded']=[],lines:MrftaLine[]=[];
for(const k of Object.keys(labels))if(!String(i[k as keyof MrftaInput]).trim())pending.push('Falta '+labels[k]+'.');
if(!/^2026-(0[1-9]|1[0-2])$/.test(i.period))pending.push('Mês/ano inválido ou fora do recorte2026.');
if(i.nuit&&!/^\d{9}$/.test(i.nuit))pending.push('NUIT deve ter nove algarismos;confira a identidade fiscal.');
if(i.completeness!=='yes'||!i.completenessRef.trim())pending.push('Conferir completude das retenções deste sujeito passivo/período, incluindo os demais livros;este contexto não é automaticamente a declaração completa.');
if(i.otherRubrics!=='none'||!i.otherRubricsRef.trim())pending.push('IRPS,tributação autónoma e outras rubricas fora deste recorte não são zero presumido;documente a ausência de outros valores devidos ou mantenha o total indeterminado.');
if(!current||!b.result)pending.push('Cálculo das retenções desactualizado ou inexistente;guarde o cálculo actual antes da preparação.');
for(const v of b.result?.rows??[]){
const r=b.result!.inputs.find(r=>r.id===v.id);
if(!r){pending.push('Entrada do resultado ausente: '+v.id);continue;}
if(r.direction==='received'){excluded.push({id:r.id,reason:'Retenção sofrida; não é imposto a entregar pelo titular.'});continue;}
if(v.period&&v.period!==i.period){excluded.push({id:r.id,reason:'Outro período: '+v.period});continue;}
if(v.treatment==='dispensed'&&v.status==='calculated'){excluded.push({id:r.id,reason:'Dispensa documentada;sem imposto a transcrever.'});continue;}
if(v.status!=='calculated'||!v.tax||!v.base||v.rate===null||!v.period){pending.push(`${r.documentRef}: rendimento indeterminado;${v.reason}`);continue;}
const name=rubric(r,v);if(!name){pending.push(`${r.documentRef}: rubrica MRFTA por corresponder;categoria digital/especial não copiada para serviços comuns.`);continue;}
const code=i.codes.find(c=>c.rowId===r.id);if(!code?.cer.trim()||!/^\d+$/.test(code.cer.trim())||!code.reference.trim())pending.push(`${r.documentRef}: CER numérico e referência aplicável por identificar;sem código presumido.`);
const cer=code?.cer.trim()??'',line=lines.find(l=>l.rubric===name&&l.rate===v.rate&&l.cer===cer);
const reference=`CER:${code?.reference??''};contraparte:${r.counterparty};qualificação:${r.qualificationRef};benefício:${r.reliefPreparation?.evidence??r.reliefRef};residência fiscal:${r.reliefPreparation?.residenceDocument??''}`;
if(line){line.ids.push(r.id);line.documents.push(r.documentRef);line.references.push(reference);line.base=addFractions([line.base,v.base]);line.tax=addFractions([line.tax,v.tax]);line.paid=line.paid&&v.settled?addFractions([line.paid,v.settled]):null;}
else lines.push({ids:[r.id],documents:[r.documentRef],references:[reference],rubric:name,cer,rate:v.rate,base:v.base,tax:v.tax,paid:v.settled});
}
for(const line of lines)if(lines.some(other=>other!==line&&other.rubric===line.rubric))pending.push(line.rubric+': taxas ou CER distintos na mesma rubrica;conferir transcrição sem fundir taxas nem perder parcelas.');
const principal=addFractions(lines.map(l=>l.tax)),paid=lines.every(l=>l.paid!==null)?addFractions(lines.map(l=>l.paid!)):null;
if(paid===null)pending.push('Valor já pago não reconciliado;pagamento ao fornecedor não é entrega à AT.');
let interest:FiscalFraction|null=null,interestReason='Juros compensatórios indeterminados: taxa aplicável, âmbito e período por resolver;sem MAIBOR2026 nem substituição automática por MIMO/Prime. Juros de mora e tributação autónoma não apurados.';
if(i.interest.mode==='assessment'){
try{const a=decimalFraction(i.interest.amount);if(negative(a)||i.interest.period!==i.period||!i.interest.reference.trim()||!date(i.interest.date)||i.interest.date.slice(0,7)<i.period)throw Error();interest=a;interestReason=`Juros compensatórios transcritos de liquidação documentada:${i.interest.reference};data:${i.interest.date};período:${i.interest.period};montante original em MZN:${i.interest.amount}. Não são juros calculados pelo portal.`;}catch{interestReason='Liquidação de juros incompleta,negativa ou incoerente;identifique montante,data e documento do mesmo período.';}
}else if(i.interest.mode==='timely'){
const ids=lines.flatMap(l=>l.ids),inputs=(b.result?.inputs??[]).filter(r=>ids.includes(r.id));
const dates=inputs.flatMap(r=>r.allocations.map(a=>b.result?.payments.find(p=>p.id===a.paymentId)?.date??''));
if(i.interest.period===i.period&&date(i.interest.dueDate)&&i.interest.dueReference.trim()&&i.interest.reference.trim()&&paid!==null&&isZero(subtractFractions(principal,paid))&&inputs.length>0&&inputs.every(r=>r.settlement==='complete'&&r.allocations.length>0)&&dates.every(d=>date(d)&&d<=i.interest.dueDate)&&i.interest.dueDate>=i.period+'-01'){
interest=zero();interestReason=`Entregas integralmente reconciliadas até ao prazo documentado:${i.interest.dueDate};${i.interest.dueReference};${i.interest.reference}. Sem atraso neste recorte;sem declarar cumprimento global de obrigações.`;
}else interestReason='Ausência de atraso não demonstrada: confira prazo aplicável, comprovativos completos, datas e montante entregue. Sem zero de juros presumido.';
}
let automatic:IrpcInterestCalculation|undefined;
if(i.interest.mode===''&&i.interest.calculation==='automatic'){
if(!i.interest.automatic||i.interest.period!==i.period||!i.interest.reference.trim())interestReason='Cálculo automático sem parâmetros/ocorrência e período documentados;juros continuam indeterminados.';
else{automatic=calculateIrpcInterest(b,current,i.period,i.interest.dueDate,i.interest.dueReference,i.interest.date,i.interest.automatic);interest=automatic.total;interestReason=automatic.pending.length?automatic.pending.join(' | '):'Juros calculados por parâmetros documentados deste caso — simulação pelos pressupostos introduzidos, sem confirmação fiscal;sem taxa fiscal2026 pré-definida. Taxa anual:'+automatic.rule.annualRate+'%;fonte:'+automatic.rule.rateSource+';fundamento:'+automatic.rule.fiscalBasis+';vigência:'+automatic.rule.validFrom+'–'+automatic.rule.validTo+';base anual:'+(automatic.rule.dayBasis==='actual_year'?'dias efectivos de cada ano':automatic.rule.dayBasis+' dias')+';fonte:'+automatic.rule.dayBasisRef+';arredondamento do total aos cêntimos:'+(automatic.rule.rounding==='total_cent_half_up'?'metade por excesso':'por defeito')+';fonte:'+automatic.rule.roundingRef+';ocorrência:'+automatic.rule.occurrenceRef+';'+automatic.rows.map(r=>r.document+':'+r.segments.map(s=>s.from+'–'+s.to+':'+s.days+'dias/'+s.denominator+';principal '+money(s.principal)+';juros '+money(s.interest)).join(',')).join(' | ');}
}
if(!interest)pending.push(interestReason);
let total:FiscalFraction|null=null;
if(pending.length===0&&interest&&paid){const balance=subtractFractions(addFractions([principal,interest]),paid);if(negative(balance))pending.push('Valor já pago excede imposto e juros;reconcilie sem crédito/reembolso automático.');else total=balance;}
return {...(automatic?{automatic}:{}),period:i.period,input:structuredClone(i),lines,excluded,pending:[...new Set(pending)],principal,paid,interest,total,interestReason,source:mrftaSource};
}
export function recordMrfta(b:IrpcBook&MrftaStore,current:boolean,now=new Date().toISOString()):IrpcBook&MrftaStore{
const model=prepareMrfta(b,current);return{...b,mrftaHistory:b.mrftaResult?[...(b.mrftaHistory??[]),structuredClone(b.mrftaResult)]:b.mrftaHistory??[],mrftaResult:{key:key(b,current),createdAt:now,model}};
}
const money=(f:FiscalFraction|null)=>{if(!f)return'Indeterminado';const p=fractionPresentation(f);return(p.approximate?'≈':'')+p.decimal+' MZN';};
export function mrftaReportRows(b:IrpcBook&MrftaStore,current:boolean):Array<[string,string,string,string]>{
const r=b.mrftaResult;if(!r)return[];const m=r.model;return[['IRPC — retenções','MRFTA — '+m.period,`Subtotal das retenções correspondidas:${money(m.principal)};juros:${money(m.interest)};valor já pago:${money(m.paid)};total a pagar:${money(m.total)};${m.interestReason};pendências:${m.pending.join(' | ')}`,`${mrftaCurrent(b,current)?'Preparação correspondente':'Histórico;preparação desactualizada'};${r.createdAt};completude:${m.input.completenessRef};outras rubricas:${m.input.otherRubricsRef};${m.source}`],...m.lines.map(l=>['IRPC — retenções',l.rubric,`${l.documents.join(';')};base:${money(l.base)};taxa:${l.rate}%;imposto:${money(l.tax)};CER:${l.cer||'por corresponder'};código introduzido,sem validação por catálogo oficial`,`Período:${m.period};apenas rendimento pago;sem assinatura ou uso dos serviços;documentos:${l.ids.join(',')};suporte:${l.references.join(' | ')}`] as [string,string,string,string])];
}
export function mrftaHtml(b:IrpcBook&MrftaStore,current:boolean):string{
if(!current||!mrftaCurrent(b,current))throw Error('Calcule as retenções e prepare o MRFTA com as entradas actuais antes de exportar.');
const m=b.mrftaResult!.model,esc=(v:unknown)=>String(v).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]!));
return `<!doctype html><html lang="pt"><meta charset="utf-8"><title>MRFTA — preparação</title><body><h1>MRFTA — preenchimento de preparação</h1><p>Quadro1:retenção na fonte;${esc(m.input.declaration==='initial'?'Inicial':m.input.declaration==='replacement'?'Substituição':'Tipo por identificar')}. Quadro2:${esc(m.period)};${esc(m.input.timing==='within'?'Dentro do prazo':m.input.timing==='late'?'Fora do prazo':'Prazo por identificar')}.</p><p>Quadro3 NUIT:${esc(m.input.nuit)};área fiscal:${esc(m.input.taxArea)}. Quadro4:${esc(m.input.name)}. Quadro5:${esc(m.input.commercialName)}. Quadro6:${esc(m.input.address)};${esc(m.input.contact)}.</p><p>Conferência do período:${esc(m.input.completenessRef)}. Outras rubricas:${esc(m.input.otherRubricsRef)}.</p><p>CER introduzidos com referência do caso; sem validação automática por catálogo oficial. Códigos provisórios ou de simulação não são correspondências oficiais.</p><h2>Quadro7</h2><table><thead><tr><th>CER</th><th>Rubrica</th><th>Base</th><th>Taxa</th><th>Imposto</th><th>Documentos</th></tr></thead><tbody>${m.lines.map(l=>`<tr><td>${esc(l.cer||'Por corresponder')}</td><td>${esc(l.rubric)}</td><td>${esc(money(l.base))}</td><td>${l.rate}%</td><td>${esc(money(l.tax))}</td><td>${esc(l.documents.join(';')+';'+l.references.join(' | '))}</td></tr>`).join('')}</tbody></table><p>Subtotal correspondido:${esc(money(m.principal))};JUROS COMPENSATÓRIOS:${esc(money(m.interest))};VALOR JÁ PAGO:${esc(money(m.paid))};TOTAL A PAGAR:${esc(money(m.total))}.</p><p>${esc(m.interestReason)}</p><h2>Casos pendentes</h2><ul>${m.pending.map(p=>'<li>'+esc(p)+'</li>').join('')}</ul><h2>Casos separados</h2><ul>${m.excluded.map(p=>'<li>'+esc(p.id+':'+p.reason)+'</li>').join('')}</ul><p>Quadros8/9 reservados,sem assinatura,carimbo,número de entrada ou aceitação AT. Tributação autónoma e juros de mora não apurados. Este documento de preparação não substitui o original oficial nem submete uma declaração.</p><small>${esc(m.source)}</small></body></html>`;
}
@@ -0,0 +1,20 @@
import {fraction,type FiscalFraction} from './fiscal-rational.ts';
export const normalAssessmentVersion='IRPC-normal-adjustments/4';
export type NormalAssessmentInput={version:1;treatment:''|'general_61_1'|'other';reference:string};
export const newNormalAssessmentInput=():NormalAssessmentInput=>({version:1,treatment:'',reference:''});
export function validateNormalAssessment(i:NormalAssessmentInput){if(!i||i.version!==1||!['','general_61_1','other'].includes(i.treatment)||typeof i.reference!=='string')throw Error('Enquadramento da colecta não recuperável;original conservado.');}
export type NormalAssessmentModel={input:NormalAssessmentInput;period:{year:string;from:string;to:string};classification:string;rate:FiscalFraction|null;taxableBase:FiscalFraction|null;colecta:FiscalFraction|null;centExact:boolean|null;pending:string[];rule:string;source:string;finalBalance:{scope:'L8';status:'not_calculated';payable:null;recoverable:null;reason:string}};
export function calculateNormalAssessment(input:NormalAssessmentInput,base:FiscalFraction|null,context:{year:string;scope:string;currency:string;extended?:boolean;period?:{from:string;to:string}}):NormalAssessmentModel{
validateNormalAssessment(input);const pending:string[]=[],period={year:context.year,from:/^20\d{2}$/.test(context.year)?context.year+'-01-01':'',to:/^20\d{2}$/.test(context.year)?context.year+'-12-31':''};
if(context.year!=='2026')pending.push('Taxa geral correspondida neste incremento apenas ao exercício2026;sem taxa transportada para outro período.');
if(!(context.scope==='resident_general'||context.extended&&context.scope==='ep_general')||context.currency!=='MZN')pending.push('Colecta delimitada ao sujeito residente no regime geral emMZN;outros âmbitos por corresponder.');
if(input.treatment!=='general_61_1')pending.push(input.treatment==='other'?'Benefício,taxa reduzida,tributação autónoma ou outro caso especial:tratamento próprio;sem taxa geral aplicada por aproximação.':'Enquadramento da taxa geral por identificar;sem escolha presumida.');
if(!input.reference.trim())pending.push('Identifique suporte ou pressuposto da aplicação da taxa geral ao caso;uma actividade semelhante não prova o regime.');
if(base===null)pending.push('Matéria colectável actual indeterminada;lucro tributável não é substituto da base.');
else if(!/^-?\d{1,80}$/.test(base.numerator)||!/^\d{1,80}$/.test(base.denominator)||BigInt(base.denominator)===0n||BigInt(base.numerator)<0n)pending.push('Matéria colectável deve ser um valor conhecido não negativo e reconciliado.');
if(context.period){period.from=context.period.from;period.to=context.period.to;const start=new Date(period.from+'T00:00:00Z'),end=new Date(period.to+'T00:00:00Z');if(!Number.isFinite(+start)||!Number.isFinite(+end)||start.toISOString().slice(0,10)!==period.from||end.toISOString().slice(0,10)!==period.to||!period.from.endsWith('-01')||!period.to.startsWith('2026-'))pending.push('Período fiscal anual não reconciliado.');else{start.setUTCFullYear(start.getUTCFullYear()+1);start.setUTCDate(start.getUTCDate()-1);if(start.toISOString().slice(0,10)!==period.to)pending.push('Colecta anual: período de12 meses por reconciliar.');}}
const rate=input.treatment==='general_61_1'&&context.year==='2026'?fraction(32n):null;
const colecta=pending.length===0&&base!==null&&rate?fraction(BigInt(base.numerator)*32n,BigInt(base.denominator)*100n):null;
return{input:structuredClone(input),period,classification:input.treatment==='general_61_1'?'Regime normal — taxa geral do artigo61(1)':input.treatment==='other'?'Caso especial fora deste recorte':'Enquadramento por identificar',rate,taxableBase:base,colecta,centExact:colecta?(BigInt(colecta.numerator)*100n)%BigInt(colecta.denominator)===0n:null,pending,rule:'CIRPC61(1)-general-2026/1',source:context.extended?'CIRPC61(1), taxa geral32% mantida pelos diplomas inventariados até Lei12/2025; período anual documentado com termo em2026. CIRPC15(1)a/c,7(1–3): sujeito residente ou resultado imputável aEP no regime geral; ano civil, autorização ou comunicação expressamente identificadas. Sem arredondamento fiscal ou saldoL8 presumidos.':'CIRPC Lei34/2007 art61(1),PDF17/p768(71):taxa geral32%. Lei4/2012 altera61(2);Lei20/2022 PDF1/p2731 mantém61(1),altera61(2) com termo31/12/2025;Lei12/2025 PDF18/20 não altera61(1),adita61-A para mais-valias,fora deste recorte. Exercício anual2026/MZN/residente geral,matéria colectável actual×32/100 em aritmética racional exacta. Sem arredondamento fiscal ou transcriçãoM20/M22 presumidos.',finalBalance:{scope:'L8',status:'not_calculated',payable:null,recoverable:null,reason:'Saldo final a pagar ou recuperar por determinar emL8:retenções,pagamentos e créditos do fecho anual não apurados nem abatidos à colecta neste incremento. Colecta não equivale ao saldo final.'}};
}
+57
View File
@@ -0,0 +1,57 @@
import {addFractions,decimalFraction,fraction,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
import type {ProfitEvidence} from './irpc-normal-profit.ts';
export const normalBaseVersion='IRPC-normal-adjustments/3';
type Choice=''|'yes'|'no';
export type NormalLoss={id:string;year:string;subjectNuit:string;assessed:string;previouslyUsed:string;requested:string;reference:string;kind:''|'ordinary'|'transfer'|'other';annualPeriods:Choice;generalActivity:Choice;balanceConfirmed:Choice};
export type NormalBaseInput={version:1;subjectNuit:string;identityReference:string;method:''|'direct'|'indirect';methodReference:string;lossesState:''|'known'|'absent';lossesReference:string;unchangedObject:Choice;objectReference:string;losses:NormalLoss[];benefits:ProfitEvidence};
export const newNormalBaseInput=():NormalBaseInput=>({version:1,subjectNuit:'',identityReference:'',method:'',methodReference:'',lossesState:'',lossesReference:'',unchangedObject:'',objectReference:'',losses:[],benefits:{state:'',amount:'',reference:''}});
export const newNormalLoss=(id:string):NormalLoss=>({id,year:'',subjectNuit:'',assessed:'',previouslyUsed:'',requested:'',reference:'',kind:'',annualPeriods:'',generalActivity:'',balanceConfirmed:''});
export function validateNormalBase(i:NormalBaseInput){
if(!i||i.version!==1||['subjectNuit','identityReference','methodReference','lossesReference','objectReference'].some(k=>typeof i[k as 'subjectNuit']!=='string')||!['','direct','indirect'].includes(i.method)||!['','known','absent'].includes(i.lossesState)||!['','yes','no'].includes(i.unchangedObject)||!Array.isArray(i.losses)||new Set(i.losses.map(l=>l.id)).size!==i.losses.length||!i.benefits||!['','known','absent'].includes(i.benefits.state)||typeof i.benefits.amount!=='string'||typeof i.benefits.reference!=='string')throw Error('Preparação da matéria colectável não recuperável.');
for(const l of i.losses)if(!l||Object.keys(newNormalLoss('')).some(k=>typeof l[k as keyof NormalLoss]!=='string')||!['','ordinary','transfer','other'].includes(l.kind)||['annualPeriods','generalActivity','balanceConfirmed'].some(k=>!['','yes','no'].includes(l[k as 'annualPeriods'])))throw Error('Perda fiscal não recuperável;originais conservados.');
}
export type NormalBaseModel={input:NormalBaseInput;taxableProfit:FiscalFraction|null;requestedLosses:FiscalFraction;deductedLosses:FiscalFraction|null;benefitDeduction:FiscalFraction|null;taxableBase:FiscalFraction|null;losses:Array<NormalLoss&{available:FiscalFraction|null;requestedAmount:FiscalFraction|null;deducted:FiscalFraction|null;remaining:FiscalFraction|null;lastOrdinaryYear:number|null;status:'eligible'|'excluded'|'indeterminate';reason:string}>;pending:string[];source:string};
const zero=()=>fraction(0n);
function amount(s:string){if(!/^\d{1,18}(?:\.\d{1,2})?$/.test(s))throw Error();return decimalFraction(s);}
const units=(f:FiscalFraction)=>BigInt(f.numerator)*100n/BigInt(f.denominator);
export function calculateNormalBase(input:NormalBaseInput,profit:FiscalFraction|null,year:string,currentLossReference?:string):NormalBaseModel{
validateNormalBase(input);const i=structuredClone(input),pending:string[]=[],losses:NormalBaseModel['losses']=[];
if(year!=='2026')pending.push('Matéria colectável delimitada ao exercício2026.');
if(!/^\d{9}$/.test(i.subjectNuit)||!i.identityReference.trim())pending.push('Identifique NUIT e suporte do sujeito passivo do lucro e das perdas.');
if(i.method!=='direct'||!i.methodReference.trim())pending.push('Método declarativo/directo e suporte por identificar;apuramento indirecto fora deste recorte (15(2),41(2)).');
if(!profit)pending.push('Lucro tributável actual indeterminado;nenhuma dedução transforma informação em falta em zero.');
else if(units(profit)<0n&&!currentLossReference?.trim())pending.push('Resultado fiscal negativo conhecido;tratamento da perda do próprio exercício fora deste recorte,sem matéria colectável zero ou reporte automático.');
if(!i.lossesState||!i.lossesReference.trim())pending.push('Situação e completude das perdas anteriores em falta;sem ausência presumida.');
if(i.lossesState==='absent'&&i.losses.length)pending.push('Ausência declarada de perdas contradiz os registos existentes;reconcilie sem apagar histórico.');
if(i.lossesState==='known'&&!i.losses.length)pending.push('Perdas declaradas conhecidas sem discriminação por exercício.');
if(i.losses.some(l=>!/^20\d{2}$/.test(l.year)||Number(l.year)+5>=Number(year))&&(!i.unchangedObject||!i.objectReference.trim()))pending.push('Documente manutenção ou alteração do objecto/natureza da actividade no termo do exercício (41(7)).');
for(const l of i.losses){const r:NormalBaseModel['losses'][number]={...l,available:null,requestedAmount:null,deducted:null,remaining:null,lastOrdinaryYear:null,status:'indeterminate',reason:''};const issues:string[]=[];
if(!l.reference.trim())issues.push('Documento de apuramento/saldo fiscal por identificar.');
if(l.subjectNuit!==i.subjectNuit||!/^\d{9}$/.test(l.subjectNuit))issues.push('Perda não reconciliada com o mesmo sujeito passivo.');
if(!/^20\d{2}$/.test(l.year)||Number(l.year)>=Number(year))issues.push('Exercício da perda deve ser anterior ao exercício de utilização;perda actual não é dedução a si própria.');
if(i.losses.some(q=>q.id!==l.id&&q.year===l.year&&q.subjectNuit===l.subjectNuit))issues.push('Saldo anual duplicado;reconcilie um saldo por sujeito/exercício.');
if(l.kind!=='ordinary')issues.push('Transmissão/fusão ou outra origem exige correspondência própria;sem aplicação automática de41-A.');
if(l.annualPeriods!=='yes')issues.push('Contagem por exercícios anuais ordinários não demonstrada;períodos especiais/curtos (41(5)) fora deste recorte.');
if(l.generalActivity!=='yes')issues.push('Origem no regime geral,fora de transparência/isenção parcial ou actividade com redução,por demonstrar (41(4/6)).');
if(l.balanceConfirmed!=='yes')issues.push('Saldo fiscal corrigido e utilizações anteriores por reconciliar (41(3));não usar perda contabilística como fiscal.');
try{const assessed=amount(l.assessed),used=amount(l.previouslyUsed);if(units(used)>units(assessed))throw Error();r.available=subtractFractions(assessed,used);}catch{issues.push('Apuramento fiscal e utilização anterior devem ser montantes conhecidos não negativos e coerentes.');}
try{r.requestedAmount=amount(l.requested);if(r.available&&units(r.requestedAmount)>units(r.available))issues.push('Utilização proposta excede saldo fiscal disponível.');}catch{issues.push('Identifique utilização proposta,não negativa,mesmo quando zero.');}
if(l.annualPeriods==='yes'&&/^20\d{2}$/.test(l.year))r.lastOrdinaryYear=Number(l.year)+5;
if(!issues.length){if((r.lastOrdinaryYear!<Number(year))||i.unchangedObject==='no'){
r.status='excluded';r.reason=r.lastOrdinaryYear!<Number(year)?'Prazo dos cinco exercícios ordinários posteriores expirado (41(1));saldo não utilizável neste exercício.':'Objecto/natureza alterados conforme declaração;dedução41(1)não aplicável (41(7)).';
if(units(r.requestedAmount!)!==0n)issues.push('Perda excluída com utilização positiva proposta;corrija a proposta sem dedução presumida.');
}else{r.status='eligible';r.reason='Saldo fiscal ordinário documentado,mesmo sujeito,cinco exercícios posteriores;utilização escolhida explicitamente,sem ordemFIFO ou percentagem presumida.';}}
if(issues.length){r.status='indeterminate';r.reason=issues.join(' ');pending.push(l.year+': '+r.reason);}
losses.push(r);
}
const requestedLosses=addFractions(losses.filter(l=>l.status==='eligible').map(l=>l.requestedAmount!));
if(profit&&units(requestedLosses)>(units(profit)>0n?units(profit):0n))pending.push('Utilizações propostas excedem o lucro tributável disponível;reparta explicitamente sem criar base negativa ou escolher uma ordem de perdas.');
let benefitDeduction:FiscalFraction|null=null;const benefit=i.benefits;
if(!benefit.state||!benefit.reference.trim())pending.push('Benefícios/deduções à matéria colectável por identificar (15(4));créditos à colecta e retenções não são esta dedução.');
else if(benefit.state==='absent'){if(benefit.amount.trim())pending.push('Ausência de benefícios contradiz montante preenchido.');else benefitDeduction=zero();}
else{try{const value=amount(benefit.amount);if(units(value)!==0n)pending.push('Benefício de montante conhecido:regra,condições,limite e ordem próprios por implementar;sem subtracção livre do valor.');else benefitDeduction=value;}catch{pending.push('Montante conhecido das deduções por preencher ou inválido.');}}
const ready=pending.length===0&&profit!==null,deductedLosses=ready?requestedLosses:null,taxableBase=ready?subtractFractions(subtractFractions(units(profit!)<0n?zero():profit!,requestedLosses),benefitDeduction!):null;
for(const l of losses){if(l.available){l.deducted=ready?(l.status==='eligible'?l.requestedAmount!:zero()):null;l.remaining=l.deducted?subtractFractions(l.available,l.deducted):null;}}
return{input:i,taxableProfit:profit,requestedLosses,deductedLosses,benefitDeduction,taxableBase,losses,pending,source:'CIRPC15(1)a/15(2–4),41(1–7),Lei34/2007 PDF5/p768(59),PDF12/p768(66). Recorte2026,residente geral,método declarativo,perdas próprias em exercícios anuais ordinários;cinco exercícios posteriores,sem transferência41-A,regimes especiais ou benefícios positivos implementados. Pedido de utilização expresso e limitado ao saldo/lucro;semFIFO obrigatório ou limite percentual inventado. Matéria colectável simulada,não colecta/imposto a pagar,semM20/M22/submissão ou consumo persistente do saldo oficial.'};
}
+20
View File
@@ -0,0 +1,20 @@
import {fraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
export const normalFormSource='M/22, exemplar inventariado IRPC M-22- DECLARACAO DE RENDIMENTOS.pdf, SHA256 4b61bd83d1fbcfd3b7b5c5523cea5923f7d0f65dc4c004eff58e5db38f763c88, quadros10/11/12, três páginas conferidas. Correspondência parcial de preparação, sem ficheiro oficial ou submissão.';
export function normalFormFields(m:{profit?:{lines:Array<{code:string;amount:string;reference:string}>};taxableProfit:FiscalFraction|null;taxableBase:FiscalFraction|null;colecta?:FiscalFraction|null;base?:{deductedLosses:FiscalFraction|null;benefitDeduction:FiscalFraction|null}}){
const p=m.taxableProfit,negative=p!==null&&BigInt(p.numerator)<0n;
const values:Array<[string,string,FiscalFraction|null,string]>= [
['259','Prejuízo fiscal',negative?fraction(-BigInt(p!.numerator),BigInt(p!.denominator)):null,'Quadro10; apenas quando há perda conhecida.'],
['260','Lucro tributável',p&&!negative?p:null,'Quadro10; não preencher o campo de lucro com uma perda.'],
['269','Prejuízo fiscal — regime geral',negative?fraction(-BigInt(p!.numerator),BigInt(p!.denominator)):null,'Quadro11; não é uma perda anterior dedutível.'],
['270','Lucro tributável — regime geral',p&&!negative?p:null,'Quadro11; manter separados regimes reduzido/isento.'],
['276','Prejuízos fiscais deduzidos',m.base?.deductedLosses??null,'Quadro11; utilização simulada expressa.'],
['277','Benefícios fiscais a deduzir',m.base?.benefitDeduction??null,'Quadro11; benefícios positivos pertencem aL7.'],
['278','Matéria colectável — regime geral',m.taxableBase,'Quadro11; não é colecta.'],
['300','Imposto à taxa normal',m.colecta??null,'Quadro12; não é saldo final.'],
['200','Resultado do exercício',null,'Resultado financeiro antes de imposto não preenche automaticamente o resultado líquido do formulário; falta reconciliação própria.'],
['302','Colecta total',null,'Inclui eventual parcela de taxa reduzida; não presumir a ausência deL7.'],
['309–316','Liquidação e saldo final',null,'ÂmbitoL8; retenções, pagamentos, créditos e juros não preenchidos porL6.'],
];
const m20Fields=([['cost_of_sales','6.1.1','Custo dos inventários vendidos/consumidos'],['personnel','6.2','Gastos com pessoal'],['depreciation','6.5','Amortizações do período'],['interest_expense','6.9','Gastos financeiros — apenas juros da origem']]as const).map(([key,account,label])=>{const l=m.profit?.lines.find(l=>l.code===key);let value:FiscalFraction|null=null;if(l&&/^\d+(?:\.\d{1,2})?$/.test(l.amount)){const[n,f='']=l.amount.split('.');value=fraction(BigInt(n)*100n+BigInt(f.padEnd(2,'0')),100n);}return{account,label,value,display:value?fractionPresentation(value).decimal+' MZN':'Não preenchido',transcriptionReady:value!==null&&BigInt(value.numerator)%BigInt(value.denominator)===0n,reference:l?.reference??'',reason:'M20 A.1 quadro4, código contabilístico do exemplar, sem inventar número de campo. Valor contabilístico da origem; não é dedução fiscal. Exemplar exige meticais sem centavos; fracções conservadas, sem arredondamento presumido.'};});
return{source:normalFormSource,m20:{status:'partial',fields:m20Fields,source:'Cópia de IRPS-IMOP.xlsx, SHA256 1ceca6f4c6d77853c1b2b445876599b42093175fa89eecf40590180956d83a9e, folhas M,20 e M20A.1; rótulos reutilizados, sem valores de terceiros ou execução das fórmulas do exemplar.',reason:'M20 A.1: correspondência parcial dos custos contabilísticos. Vendas/serviços, fornecimentos/outros gastos, imposto sobre o rendimento e resultado líquido exigem discriminação própria. Divergência concreta: M20A.1 remete resultado para M22 campo201/quadro8; PDF M22 inventariado usa campo200/quadro10. Sem transporte automático entre essas edições; restantes campos independentes conservados.'},fields:values.map(([code,label,value,reason])=>{const centExact=value?(BigInt(value.numerator)*100n)%BigInt(value.denominator)===0n:null;return{code,label,value,centExact,display:value?fractionPresentation(value).decimal+' MZN':'Não preenchido',transcriptionReady:value!==null&&centExact===true,reason:reason+(centExact===false?' Fracção de cêntimo conservada exactamente; regra de representação fiscal por corresponder, sem arredondamento presumido.':'')};})};
}
+60
View File
@@ -0,0 +1,60 @@
import type {SchedulesModel} from './irpc-normal-schedules.ts';
import {addFractions,decimalFraction,fraction,type FiscalFraction} from './fiscal-rational.ts';
export const normalProfitVersion='IRPC-normal-adjustments/2';
export type ProfitEvidence={state:''|'known'|'absent';amount:string;reference:string};
export const profitTopics=[
['positivePatrimonial','Variações patrimoniais positivas fora do resultado'],
['negativePatrimonial','Variações patrimoniais negativas fora do resultado'],
['incomeCorrections','Outras correcções aos proveitos, incluindo exclusões'],
['expenseCorrections','Outras correcções aos custos, além dos acréscimos registados'],
['timing','Diferenças de periodização e de critérios contabilísticos/fiscais'],
['special','Operações especiais, benefícios e regimes fora deste recorte'],
]as const;
export type ProfitTopic=typeof profitTopics[number][0];
export type NormalProfitInput={version:1;completenessReference:string;lines:Array<{code:string;state:''|'known'|'absent';reference:string}>;topics:Record<ProfitTopic,ProfitEvidence>};
export const newNormalProfitInput=():NormalProfitInput=>({version:1,completenessReference:'',lines:[],topics:Object.fromEntries(profitTopics.map(([k])=>[k,{state:'',amount:'',reference:''}]))as NormalProfitInput['topics']});
export function validateNormalProfit(i:NormalProfitInput){
if(!i||i.version!==1||typeof i.completenessReference!=='string'||!Array.isArray(i.lines)||i.lines.some(l=>!l||typeof l.code!=='string'||typeof l.reference!=='string'||!['','known','absent'].includes(l.state))||new Set(i.lines.map(l=>l.code)).size!==i.lines.length||!i.topics||typeof i.topics!=='object'||Array.isArray(i.topics))throw Error('Conferência do lucro tributável não recuperável.');
for(const[k]of profitTopics){const t=i.topics[k];if(!t||!['','known','absent'].includes(t.state)||typeof t.amount!=='string'||typeof t.reference!=='string')throw Error('Estado documental do lucro tributável não recuperável.');}
}
type Source={currency:string;periods:number;accountingLines:Array<{code:string;origin:string;accountingEffect:'income'|'expense';total:string}>};
export type NormalProfitModel={input:NormalProfitInput;lines:Array<{code:string;label:string;amount:string;addedBack:FiscalFraction;remainder:FiscalFraction|null;state:ProfitEvidence['state'];reference:string;reason:string}>;topics:Array<ProfitEvidence&{key:ProfitTopic;label:string;value:FiscalFraction|null;reason:string}>;pending:string[];taxableProfit:FiscalFraction|null;source:string};
const zero=()=>fraction(0n,1n);
function money(s:string){if(!/^-?\d+(?:\.\d{1,2})?$/.test(s))throw Error('Montante inválido');const v=decimalFraction(s.startsWith('-')?s.slice(1):s);return s.startsWith('-')?fraction(-BigInt(v.numerator),BigInt(v.denominator)):v;}
const units=(f:FiscalFraction)=>BigInt(f.numerator)*100n/BigInt(f.denominator);
const difference=(a:FiscalFraction,b:FiscalFraction)=>fraction(BigInt(a.numerator)*BigInt(b.denominator)-BigInt(b.numerator)*BigInt(a.denominator),BigInt(a.denominator)*BigInt(b.denominator));
export function closeNormalProfit(input:NormalProfitInput,source:Source|null,rows:Array<{sourceCode:string;adjustment:FiscalFraction|null;status:string}>,accounting:FiscalFraction|null,additions:FiscalFraction,contextReady:boolean,schedules?:SchedulesModel):NormalProfitModel{
validateNormalProfit(input);const pending:string[]=[],lines:NormalProfitModel['lines']=[],topics:NormalProfitModel['topics']=[];
if(!contextReady)pending.push('Âmbito,exercício,moeda ou correspondência anual ainda insuficientes.');
if(!input.completenessReference.trim())pending.push('Documente que o plano e os ajustamentos abrangem o sujeito passivo/exercício completo;uma oportunidade isolada não equivale automaticamente ao conjunto da empresa.');
if(rows.some(r=>r.status!=='calculated'))pending.push('Existem ajustamentos registados por resolver;acréscimos independentes conservados.');
if(!source)pending.push('Falta resultado financeiro reconciliado.');
for(const l of source?.accountingLines??[]){
const review=input.lines.find(r=>r.code===l.code),state=review?.state??'',reference=review?.reference??'';
const addedBack=addFractions(rows.filter(r=>r.sourceCode===l.code&&r.adjustment).map(r=>r.adjustment!));let remainder:FiscalFraction|null=null;const issues:string[]=[];
try{const amount=money(l.total);remainder=difference(amount,addedBack);if(units(amount)<0n||units(remainder)<0n)issues.push('Valor negativo ou acréscimos superiores à origem;reconcilie a linha sem compensação presumida.');
if(!state||!reference.trim())issues.push('Conferência fiscal e suporte da linha em falta.');
if(state==='absent'&&(units(amount)!==0n||units(addedBack)!==0n))issues.push('Ausência declarada contradiz o montante conhecido da origem.');
if(state==='known'&&l.code==='depreciation'&&units(amount)!==0n&&schedules?.depreciation==null)issues.push('Depreciação contabilística conhecida;amortização fiscal por corresponder,não presumir igualdade.');
if(state==='known'&&l.code==='interest_expense'&&units(remainder)!==0n&&schedules?.interest==null)issues.push('Juros financeiros remanescentes conhecidos;dedutibilidade e eventuais limites por corresponder. Só os juros compensatórios já acrescidos estão cobertos.');
if(!['revenue','cost_of_sales','operating_expenses','personnel','depreciation','interest_expense'].includes(l.code))issues.push('Linha financeira sem correspondência neste recorte.');
}catch{issues.push('Montante da linha por reconciliar.');}
const reason=issues.join(' ')|| (state==='absent'?'Ausência expressamente declarada e compatível com a origem zero.':units(remainder??zero())===0n?'Valor conhecido,integralmente corrigido ou igual a zero;sem presumir ausência.':l.accountingEffect==='income'?'Proveito ordinário reconhecido no exercício,qualificado e documentado nos termos dos artigos18/20.':'Parcela remanescente qualificada como custo ordinário indispensável e documentado do artigo22,sem exclusões/limites adicionais declarados.');
if(issues.length)pending.push(l.origin+': '+reason);
lines.push({code:l.code,label:l.origin,amount:l.total,addedBack,remainder,state,reference,reason});
}
for(const l of input.lines)if(!source?.accountingLines.some(s=>s.code===l.code))pending.push('Conferência sem linha de origem actual: '+l.code);
for(const[key,label]of profitTopics){const t=input.topics[key];let value:FiscalFraction|null=null,reason='';
if(!t.state||!t.reference.trim())reason='Informação em falta;sem zero presumido.';
else if(t.state==='absent'){if(t.amount.trim())reason='Ausência declarada com montante preenchido;reconcilie os dois estados.';else{value=zero();reason='Ausência expressamente declarada com suporte;parcela zero apenas por esta declaração.';}}
else{try{value=money(t.amount);if(units(value)!==0n)reason='Montante conhecido,mas tratamento específico ainda por corresponder;conservado sem aplicação presumida.';else reason='Valor conhecido zero com suporte;distinto de ausência declarada.';}catch{reason='Montante conhecido por preencher ou inválido.';}}
const mapped=schedules?.effects.filter(e=>e.topic===key)??[];
const covered=schedules&&mapped.length>0&&mapped.every(e=>e.effect!==null)&&value!==null&&t.state==='known'&&units(addFractions(mapped.flatMap(e=>e.amount?[e.amount]:[])))===units(value);
if(covered)reason='Montante reconciliado com as regras do mapa complementar; efeito fiscal discriminado por linha.';
if(value===null||units(value)!==0n&&!covered||t.state==='absent'&&!!t.amount.trim()||mapped.length>0&&!covered)pending.push(label+': '+(mapped.length&&!covered?'Mapa complementar não reconciliado com este estado/montante. ': '')+reason);
topics.push({...structuredClone(t),key,label,value,reason});
}
if(schedules)pending.push(...schedules.pending);
return{input:structuredClone(input),lines,topics,pending,taxableProfit:pending.length===0&&accounting?addFractions([accounting,additions,...(schedules?[schedules.net]:[])]):null,source:schedules?'CIRPC17/18/20/21/22/24/36; Decreto72/2013 art3–7. Mapa complementar de efeitos com sinal reconciliado por tema, juros financeiros ordinários e quotas anuais constantes documentadas. Simulação emMZN/2026; benefícios e casos especiais separados emL7, saldo anual emL8.':'CIRPC17(1)/18/20/22/36(1)c;recorte anual2026,residente geral,MZN. Resultado antes de imposto + acréscimos36(1)c;demais correcções/variações sem efeito apenas quando ausência ou zero conhecidos expressamente suportados. Receita/custos ordinários classificados pelo utilizador;depreciação fiscal e juros financeiros remanescentes fora deste percurso. Lucro tributável simulado,não matéria colectável,colecta ou declaraçãoM20/22.'};
}
+71
View File
@@ -0,0 +1,71 @@
import {addFractions,decimalFraction,fraction,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export const normalSchedulesVersion='IRPC-normal-adjustments/5';
export const scheduleRules={
tax_own:['IRPC e impostos sobre o lucro contabilizados','expenseCorrections','36(1)a',1],
tax_other:['Impostos da responsabilidade de outrem','expenseCorrections','36(1)b',1],
undocumented:['Despesa não documentada','expenseCorrections','36(1)g',1],
capital_in:['Entrada de capital fora do resultado','positivePatrimonial','21(1)a',0],
patrimonial_gain:['Variação positiva ordinária fora do resultado','positivePatrimonial','21',1],
capital_out:['Distribuição aos titulares fora do resultado','negativePatrimonial','24(1)c',0],
patrimonial_cost:['Variação negativa indispensável, sem exclusões do artigo24','negativePatrimonial','22/24(1)',-1],
future_cost:['Custo contabilizado em2026 imputável ao exercício seguinte','timing','18(1)',1],
future_income:['Proveito contabilizado em2026 imputável ao exercício seguinte','timing','18(1)',-1],
current_cost:['Custo de2026 ainda não reflectido no resultado','timing','18(1)',-1],
current_income:['Proveito de2026 ainda não reflectido no resultado','timing','18(1)',1],
} as const;
export type ScheduleRule=keyof typeof scheduleRules;
export type ScheduleRow={id:string;rule:''|ScheduleRule;amount:string;sourceCode:string;document:string;line:string;reference:string;fiscalYear:string;conditions:''|'yes'};
export type NormalAsset={id:string;category:''|'computer'|'server'|'other';description:string;cost:string;residual:string;rate:string;accounting:string;previousFiscal:string;inUseFrom:string;tableReference:string;reference:string;conditions:''|'yes'};
export type NormalSchedules={version:1;period:{kind:''|'calendar'|'authorised_annual'|'ep_annual';from:string;to:string;reference:string};rows:ScheduleRow[];interest:{amount:string;reference:string;conditions:''|'yes'};assets:NormalAsset[];assetsReference:string;currentLossReference:string};
export const newNormalSchedules=():NormalSchedules=>({version:1,period:{kind:'',from:'',to:'',reference:''},rows:[],interest:{amount:'',reference:'',conditions:''},assets:[],assetsReference:'',currentLossReference:''});
export const newScheduleRow=(id:string):ScheduleRow=>({id,rule:'',amount:'',sourceCode:'',document:'',line:'',reference:'',fiscalYear:'',conditions:''});
export const newNormalAsset=(id:string):NormalAsset=>({id,category:'',description:'',cost:'',residual:'',rate:'',accounting:'',previousFiscal:'',inUseFrom:'',tableReference:'',reference:'',conditions:''});
export function validateSchedules(s:NormalSchedules){
if(!s||s.version!==1||!Array.isArray(s.rows)||!Array.isArray(s.assets)||!s.interest||typeof s.assetsReference!=='string'||typeof s.currentLossReference!=='string'||['amount','reference','conditions'].some(k=>typeof s.interest[k as 'amount']!=='string')||!['','yes'].includes(s.interest.conditions))throw Error('Mapas L6 não recuperáveis.');
for(const [rows,empty]of [[s.rows,newScheduleRow('')],[s.assets,newNormalAsset('')]]as const){if(new Set(rows.map(r=>r.id)).size!==rows.length)throw Error('Identificador duplicado no mapa L6.');for(const r of rows)if(!r||Object.keys(empty).some(k=>typeof (r as unknown as Record<string,unknown>)[k]!=='string')||!['','yes'].includes(r.conditions))throw Error('Linha L6 não recuperável.');}
if(s.rows.some(r=>r.rule!==''&&!Object.hasOwn(scheduleRules,r.rule)))throw Error('Regra L6 desconhecida.');
if(s.assets.some(a=>!['','computer','server','other'].includes(a.category)))throw Error('Categoria de activo desconhecida.');
if(!s.period||!['','calendar','authorised_annual','ep_annual'].includes(s.period.kind)||['from','to','reference'].some(k=>typeof s.period[k as 'from']!=='string'))throw Error('Período complementar não recuperável.');
}
export function normalSchedulePeriod(s:NormalSchedules,scope:string){
const p=s.period,pending:string[]=[];
const iso=(v:string)=>/^20\d{2}-\d{2}-\d{2}$/.test(v)&&Number.isFinite(Date.parse(v))&&new Date(v).toISOString().slice(0,10)===v;
if(!iso(p.from)||!iso(p.to)||!p.from.endsWith('-01')||!p.to.startsWith('2026-'))pending.push('Período anual por identificar: início no primeiro dia do mês e termo em2026, sem período curto ou alinhamento mensal presumido.');
else{const end=new Date(p.from+'T00:00:00Z');end.setUTCFullYear(end.getUTCFullYear()+1);end.setUTCDate(end.getUTCDate()-1);if(end.toISOString().slice(0,10)!==p.to)pending.push('Os12 meses do plano não correspondem ao período anual indicado.');}
if(!p.kind||!p.reference.trim())pending.push('Identifique tipo de período e correspondência dos12 meses; ausência de informação não é ano civil presumido.');
if(p.kind==='calendar'&&(p.from!=='2026-01-01'||p.to!=='2026-12-31'))pending.push('Datas incompatíveis com o ano civil2026.');
if(p.kind==='ep_annual'&&scope!=='ep_general')pending.push('Período do artigo7(3) exige EP e comunicação documentada; não aplicar a um residente.');
return{...structuredClone(p),pending};
}
const z=()=>fraction(0n);
export const fiscalMoney=(s:string)=>{if(!/^\d{1,18}(?:\.\d{1,2})?$/.test(s))throw Error('Montante não negativo com até dois decimais necessário.');return decimalFraction(s);};
const cmp=(a:FiscalFraction,b:FiscalFraction)=>BigInt(a.numerator)*BigInt(b.denominator)-BigInt(b.numerator)*BigInt(a.denominator);
export type SchedulesModel=ReturnType<typeof calculateSchedules>;
export function calculateSchedules(s:NormalSchedules,source:{accountingLines:Array<{code:string;total:string;accountingEffect:string}>}|null,oldRows:Array<{sourceCode:string;document:string;line:string;amount:string;adjustment:FiscalFraction|null}>){
validateSchedules(s);const pending:string[]=[],effects:Array<{id:string;topic:string;amount:FiscalFraction|null;effect:FiscalFraction|null;reason:string}>=[];
for(const r of s.rows){const issues:string[]=[],rule=r.rule?scheduleRules[r.rule]:null;let amount:FiscalFraction|null=null,effect:FiscalFraction|null=null;
if(!rule||!r.reference.trim()||!r.document.trim()||!r.line.trim()||r.conditions!=='yes')issues.push('Regra, documento/linha, suporte e condições por identificar.');
if(s.rows.some(q=>q!==r&&q.document.trim()===r.document.trim()&&q.line.trim()===r.line.trim())||oldRows.some(q=>q.document.trim()===r.document.trim()&&q.line.trim()===r.line.trim()))issues.push('Documento/linha duplicados entre mapas; sem dupla contagem.');
try{amount=fiscalMoney(r.amount);if(cmp(amount,z())<=0n)throw Error();}catch{issues.push('Parcela positiva por identificar.');}
const topic=rule?.[1]??'';const needsOrigin=topic==='expenseCorrections'||['future_cost','future_income'].includes(r.rule);
if(needsOrigin){const line=source?.accountingLines.find(l=>l.code===r.sourceCode);const wanted=r.rule==='future_income'?'income':'expense';if(!line||line.accountingEffect!==wanted)issues.push('Parcela deve estar incluída numa linha de origem compatível.');else try{const allocated=addFractions([...s.rows.filter(q=>(q.rule&&(['expenseCorrections'].includes(scheduleRules[q.rule][1])||['future_cost','future_income'].includes(q.rule)))&&q.sourceCode===r.sourceCode).map(q=>fiscalMoney(q.amount)),...oldRows.filter(q=>q.sourceCode===r.sourceCode).map(q=>fiscalMoney(q.amount))]);if(cmp(allocated,fiscalMoney(line.total))>0n)issues.push('Parcelas excedem a origem contabilística.');}catch{issues.push('Reconciliação da origem incompleta.');}}
else if(r.sourceCode)issues.push('Variação fora do resultado/custo ou proveito omitido não deve repetir linha já contabilizada.');
if(topic==='timing'&&r.fiscalYear!==(r.rule.startsWith('future_')?'2027':'2026'))issues.push('Exercício de imputação incompatível; este recorte cobre2026/seguinte, sem resolver exercícios anteriores.');
if(!issues.length&&amount&&rule)effect=fraction(BigInt(amount.numerator)*BigInt(rule[3]),BigInt(amount.denominator));
const reason=issues.join(' ')||'CIRPC'+rule?.[2]+'; classificação e condições documentadas pelo utilizador; projecção, sem alteração da contabilidade de origem.';if(issues.length)pending.push(r.document+': '+reason);effects.push({id:r.id,topic,amount,effect,reason});
}
let interest:FiscalFraction|null=null;const interestOrigin=source?.accountingLines.find(l=>l.code==='interest_expense');
try{const corrected=s.rows.filter(r=>r.sourceCode==='interest_expense'&&r.rule&&(scheduleRules[r.rule][1]==='expenseCorrections'||r.rule==='future_cost'));const corrections=corrected.map(r=>{const e=effects.find(e=>e.id===r.id);if(!e?.effect)throw Error();return e.effect;});const remaining=subtractFractions(fiscalMoney(interestOrigin?.total??''),addFractions([...oldRows.filter(r=>r.sourceCode==='interest_expense').flatMap(r=>r.adjustment?[r.adjustment]:[]),...corrections]));interest=fiscalMoney(s.interest.amount);if(cmp(interest,remaining)!==0n||!s.interest.reference.trim()||s.interest.conditions!=='yes')throw Error();}catch{interest=null;}
const assets=s.assets.map(a=>{const issues:string[]=[];let accounting:FiscalFraction|null=null,fiscal:FiscalFraction|null=null,adjustment:FiscalFraction|null=null;
try{const cost=fiscalMoney(a.cost),residual=fiscalMoney(a.residual),previous=fiscalMoney(a.previousFiscal),rate=fiscalMoney(a.rate);accounting=fiscalMoney(a.accounting);const depreciable=subtractFractions(cost,residual);if(cmp(depreciable,z())<0n||cmp(previous,depreciable)>0n||cmp(rate,z())<=0n||cmp(rate,fraction(100n))>0n)throw Error();const annual=fraction(BigInt(depreciable.numerator)*BigInt(rate.numerator),BigInt(depreciable.denominator)*BigInt(rate.denominator)*100n);const available=subtractFractions(depreciable,previous);fiscal=cmp(annual,available)>0n?available:annual;
if(cmp(fiscal,accounting)>0n)issues.push('Quota fiscal superior à contabilizada neste exercício; dedução de quotas anteriormente tributadas exige mapa próprio, sem presunção.');
}catch{issues.push('Custo, residual, taxa, acumulado fiscal e depreciação contabilizada por reconciliar.');}
if(!['computer','server'].includes(a.category)||a.rate!==(a.category==='computer'?'25':'20'))issues.push('Categoria/taxa não correspondida: este recorte cobre tabelaII, grupo3, itens9 (25%) e9.1 (20%), sem regra específica da tabelaI prevalecente.');
if(!/^20\d{2}-\d{2}-\d{2}$/.test(a.inUseFrom)||!Number.isFinite(Date.parse(a.inUseFrom))||new Date(a.inUseFrom).toISOString().slice(0,10)!==a.inUseFrom||a.inUseFrom>(s.period.from||'2026-01-01')||a.inUseFrom<'2014-01-01'||!a.description.trim()||!a.tableReference.trim()||!a.reference.trim()||a.conditions!=='yes')issues.push('Identifique activo próprio, em uso no início do período, tabela/taxa aplicável, vida útil e condições do método constante anual; casos especiais/duodécimos separados.');
if(['computer','server'].includes(a.category)&&/^20\d{2}-\d{2}-\d{2}$/.test(a.inUseFrom)){const limit=new Date(a.inUseFrom+'T00:00:00Z');if(Number.isFinite(+limit)){limit.setUTCFullYear(limit.getUTCFullYear()+(a.category==='computer'?8:10));if((s.period.from||'2026-01-01')>=limit.toISOString().slice(0,10))issues.push('Período máximo de vida útil excedido, artigo5; excepção específica não implementada.');}}
if(!issues.length&&accounting&&fiscal)adjustment=subtractFractions(accounting,fiscal);if(issues.length)pending.push(a.description+': '+issues.join(' '));return{...structuredClone(a),accountingValue:accounting,fiscal,adjustment,reason:issues.join(' ')||'Decreto72/2013 art3–7; quota constante anual documentada, limitada ao saldo fiscal depreciável; diferença para a depreciação contabilística.'};});
let depreciation:FiscalFraction|null=null;try{const total=addFractions(assets.map(a=>a.accountingValue??z()));if(s.assetsReference.trim()&&assets.every(a=>a.adjustment!==null)&&cmp(total,fiscalMoney(source?.accountingLines.find(l=>l.code==='depreciation')?.total??''))===0n)depreciation=addFractions(assets.map(a=>a.adjustment!));}catch{/* linha de origem desconhecida */}
if(assets.length&&(oldRows.some(r=>r.sourceCode==='depreciation')||s.rows.some(r=>r.sourceCode==='depreciation'))){depreciation=null;pending.push('Depreciação repartida entre mapas de ajustamentos e activos: reconcilie as parcelas sem sobreposição antes de aplicar a quota fiscal.');}
if(assets.length&&depreciation===null)pending.push('Mapa de activos sem reconciliação integral com a depreciação da origem; efeito fiscal não aplicado.');
return{input:structuredClone(s),effects,interest,depreciation,assets,pending,net: addFractions([...effects.flatMap(r=>r.effect?[r.effect]:[]),...(depreciation?[depreciation]:[])]),source:'CIRPC18/21/22/24/36; Decreto72/2013 art3–7. Entradas documentadas, sem taxas de activos sugeridas nem casos especiais presumidos.'};
}
+88
View File
@@ -0,0 +1,88 @@
import {normalFormFields} from './irpc-normal-forms.ts';
import {normalSchedulesVersion,normalSchedulePeriod,validateSchedules,calculateSchedules,type NormalSchedules,type SchedulesModel} from './irpc-normal-schedules.ts';
import {normalAssessmentVersion,validateNormalAssessment,calculateNormalAssessment,type NormalAssessmentInput,type NormalAssessmentModel} from './irpc-normal-assessment.ts';
import {normalBaseVersion,validateNormalBase,calculateNormalBase,type NormalBaseInput,type NormalBaseModel} from './irpc-normal-base.ts';
import {normalProfitVersion,validateNormalProfit,closeNormalProfit,type NormalProfitInput,type NormalProfitModel} from './irpc-normal-profit.ts';
import {forecastBusinessPlan,restoreBusinessPlanSnapshot} from './business-financial-plan.ts';
import {buildFinancialFiscalBridge} from './financial-fiscal-bridge.ts';
import {acquisitionScope} from './iva-acquisitions.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
export const irpcNormalVersion='IRPC-normal-adjustments/1';
export const irpcNormalSource='CIRPC Lei34/2007 art17(1),PDF6/p768(60):resultado e correcções;art36(1)c,PDF10/p768(64):multas e encargos por infracções sem origem contratual,incluindo juros compensatórios. Lei4/2012 PDF2 altera17(6)/acrescenta36(1)o;Lei19/2013 PDF2 mantém36(1)a–o e acrescenta p/q. Lei12/2025 altera3/5/20/62/67/75,adita61-A e revoga39/47/75(2)/76;sem alteração deste recorte36(1)c. Não é apuramento integral nem Modelo20/22.';
export type NormalAdjustment={id:string;sourceCode:string;document:string;line:string;amount:string;rule:''|'noncontractual_fine'|'compensatory_interest'|'other';included:''|'yes'|'no';reference:string};
export type NormalBook={version:1;year:string;mappingReference:string;scope:''|'resident_general'|'ep_general'|'other';scopeReference:string;rows:NormalAdjustment[];profit?:NormalProfitInput;base?:NormalBaseInput;assessment?:NormalAssessmentInput;schedules?:NormalSchedules;result?:NormalRecord;history?:NormalRecord[]};
type NormalModel={fiscalPeriod?:ReturnType<typeof normalSchedulePeriod>;schedules?:SchedulesModel;currentLoss?:FiscalFraction|null;assessment?:NormalAssessmentModel;colecta?:FiscalFraction|null;base?:NormalBaseModel;profit?:NormalProfitModel;version:string;year:string;currency:string;origin:'projected';accountingProfit:FiscalFraction|null;additions:FiscalFraction;partialAdjustedResult:FiscalFraction|null;taxableProfit:FiscalFraction|null;taxableBase:FiscalFraction|null;tax:null;rows:Array<NormalAdjustment&{status:'calculated'|'indeterminate'|'outside_scope';adjustment:FiscalFraction|null;reason:string}>;pending:string[];source:string};
type NormalRecord={key:string;createdAt:string;model:NormalModel};
export const newNormalBook=():NormalBook=>({version:1,year:'',mappingReference:'',scope:'',scopeReference:'',rows:[]});
export const newNormalAdjustment=(id:string):NormalAdjustment=>({id,sourceCode:'',document:'',line:'',amount:'',rule:'',included:'',reference:''});
export function normalFinancialSource(d:Record<string,unknown>){
const p=restoreBusinessPlanSnapshot(String(d.business_plan_snapshot??''));if(!p)return null;
const forecast=forecastBusinessPlan(p),bridge=buildFinancialFiscalBridge(forecast);
return{...bridge,periods:forecast.rows.length,origin:'projected' as const,scope:acquisitionScope(d)};
}
function store(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros fiscais não recuperáveis;originais preservados.');return s;}
export function validateNormal(b:NormalBook){
if(b?.schedules!==undefined)validateSchedules(b.schedules);
if(b?.assessment!==undefined)validateNormalAssessment(b.assessment);
if(b?.base!==undefined)validateNormalBase(b.base);
if(b?.profit!==undefined)validateNormalProfit(b.profit);
if(!b||b.version!==1||['year','mappingReference','scopeReference'].some(k=>typeof b[k as 'year']!=='string')||!['','resident_general','ep_general','other'].includes(b.scope)||!Array.isArray(b.rows)||b.history!==undefined&&!Array.isArray(b.history))throw Error('Preparação IRPC normal não recuperável.');
for(const r of b.rows)if(!r||Object.keys(newNormalAdjustment('')).some(k=>typeof r[k as keyof NormalAdjustment]!=='string')||!['','noncontractual_fine','compensatory_interest','other'].includes(r.rule)||!['','yes','no'].includes(r.included))throw Error('Ajustamento IRPC não recuperável;original conservado.');
if(new Set(b.rows.map(r=>r.id)).size!==b.rows.length)throw Error('Identificador de ajustamento duplicado.');
for(const r of [b.result,...(b.history??[])])if(r&&(!r.model||![irpcNormalVersion,normalProfitVersion,normalBaseVersion,normalAssessmentVersion,normalSchedulesVersion].includes(r.model.version)||typeof r.key!=='string'||typeof r.createdAt!=='string'||!Array.isArray(r.model.rows)||!Array.isArray(r.model.pending)))throw Error('Histórico IRPC normal não recuperável.');
}
export function normalBook(d:Record<string,unknown>):NormalBook{
const m=store(d).irpcNormal;if(m===undefined)return newNormalBook();if(!m||typeof m!=='object'||Array.isArray(m))throw Error('Mapa IRPC normal não recuperável.');const b=m[acquisitionScope(d)]??newNormalBook();validateNormal(b);return b;
}
export function saveNormalBook(d:Record<string,unknown>,b:NormalBook){validateNormal(b);const s=store(d);if(s.irpcNormal!==undefined&&(!s.irpcNormal||typeof s.irpcNormal!=='object'||Array.isArray(s.irpcNormal)))throw Error('Mapa IRPC normal não recuperável.');return JSON.stringify({...s,irpcNormal:{...s.irpcNormal,[acquisitionScope(d)]:b}});}
function key(d:Record<string,unknown>,b:NormalBook){return JSON.stringify([b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,acquisitionScope(d),d.business_plan_snapshot??'',b.year,b.mappingReference,b.scope,b.scopeReference,b.rows,...(b.profit?[b.profit]:[]),...(b.base?[b.base]:[]),...(b.assessment?[b.assessment]:[]),...(b.schedules?[b.schedules]:[])]);}
export function normalCurrent(d:Record<string,unknown>,b:NormalBook){return !!b.result&&b.result.key===key(d,b);}
const zero=()=>fraction(0n,1n);
const cents=(s:string)=>{if(!/^-?\d+(?:\.\d{1,2})?$/.test(s))throw Error('Montante MZN inválido;máximo dois decimais.');const v=decimalFraction(s.startsWith('-')?s.slice(1):s);return s.startsWith('-')?fraction(-BigInt(v.numerator),BigInt(v.denominator)):v;};
const integerCents=(v:FiscalFraction)=>BigInt(v.numerator)*100n/BigInt(v.denominator);
export function calculateNormal(d:Record<string,unknown>,b:NormalBook):NormalModel{
validateNormal(b);const pending:string[]=[],source=normalFinancialSource(d),fiscalPeriod=b.schedules?normalSchedulePeriod(b.schedules,b.scope):undefined;
if(fiscalPeriod)pending.push(...fiscalPeriod.pending);
if(!source)pending.push('Falta plano financeiro reconciliado.');
if(source?.currency!=='MZN')pending.push('Ponte em MZN necessária;sem conversão fiscal anual presumida.');
if(!/^2026$/.test(b.year)||!b.mappingReference.trim()||source?.periods!==12)pending.push('Documente correspondência dos 12 meses do plano ao exercício2026;outros exercícios/horizontes permanecem separados.');
if(!(b.scope==='resident_general'||b.schedules&&b.scope==='ep_general')||!b.scopeReference.trim())pending.push('Identifique sujeito residente no regime geral,fora de transparência/regimes especiais;EP e outros âmbitos não abrangidos.');
const rows:NormalModel['rows']=b.rows.map(r=>({...structuredClone(r),status:'indeterminate',adjustment:null,reason:''}));
const amounts=new Map<string,FiscalFraction>(),groups=new Map<string,NormalModel['rows']>();
for(const r of rows){
const line=source?.accountingLines.find(l=>l.code===r.sourceCode);
const issue:string[]=[];
if(!r.document.trim()||!r.line.trim()||!r.reference.trim())issue.push('Identifique documento,linha e suporte da qualificação.');
if(!line||line.accountingEffect!=='expense')issue.push('Seleccione linha de custo existente na ponte.');
if(r.included!=='yes')issue.push('Custo incluído no resultado de partida por demonstrar;sem acréscimo duplicado de montante já excluído.');
try{const a=cents(r.amount);if(integerCents(a)<=0n)throw Error();amounts.set(r.id,a);}catch{issue.push('Montante positivo MZN,até dois decimais,por identificar.');}
if(r.rule==='other'){r.status='outside_scope';issue.push('Outro ajustamento por corresponder;sem regra inventada.');}
else if(!r.rule)issue.push('Seleccione natureza da multa não contratual ou dos juros compensatórios;juros comerciais/penalidades contratuais não equiparados.');
if(rows.some(q=>q!==r&&q.document.trim()===r.document.trim()&&q.line.trim()===r.line.trim()&&r.document.trim()&&r.line.trim()))issue.push('Documento/linha repetidos;reconcilie sem duplicar o encargo.');
if(line){const g=groups.get(line.code)??[];g.push(r);groups.set(line.code,g);}
r.reason=issue.join(' ');
}
for(const [code,group]of groups){const line=source!.accountingLines.find(l=>l.code===code)!;const requested=addFractions(group.map(r=>amounts.get(r.id)??zero()));if(integerCents(requested)>integerCents(cents(line.total)))for(const r of group)r.reason+=' Parcelas excedem o custo da linha de origem;sem dupla contagem.';}
for(const r of rows){if(!r.reason){r.status='calculated';r.adjustment=amounts.get(r.id)!;r.reason='Acréscimo integral de custo incluído no resultado de partida,qualificado pelo utilizador como '+(r.rule==='noncontractual_fine'?'multa/encargo de infracção sem origem contratual':'juros compensatórios')+';CIRPC36(1)c. Projecção pelos pressupostos do plano.';}else pending.push(r.document+': '+r.reason);}
const additions=addFractions(rows.flatMap(r=>r.adjustment?[r.adjustment]:[]));
const accountingProfit=source?.currency==='MZN'?cents(source.accountingProfitBeforeTax):null;
const contextReady=(!fiscalPeriod||fiscalPeriod.pending.length===0)&&!!source&&source.currency==='MZN'&&source.periods===12&&b.year==='2026'&&!!b.mappingReference.trim()&&(b.scope==='resident_general'||!!b.schedules&&b.scope==='ep_general')&&!!b.scopeReference.trim();
if(rows.length===0&&!b.profit)pending.push('Sem ajustamentos documentados;ausência de registos não prova inexistência de correcções.');
if(!b.profit)pending.push('L6 parcial:resultado ajustado apenas destes acréscimos;restantes custos/variações patrimoniais,amortizações,perdas,deduções e colecta por tratar. Lucro tributável,matéria colectável e imposto indeterminados.');
const schedules=b.schedules?calculateSchedules(b.schedules,source,rows):undefined;
const profit=b.profit?closeNormalProfit(b.profit,source,rows,accountingProfit,additions,contextReady,schedules):undefined;
if(profit)pending.push(...profit.pending,...(!b.base?['Matéria colectável,perdas reportadas,deduções e imposto não apurados neste percurso.']:[]));
const base=b.base?calculateNormalBase(b.base,profit?.taxableProfit??null,b.year,b.schedules?.currentLossReference):undefined;
if(base)pending.push(...base.pending,...(!b.assessment?['Colecta/imposto a pagar,créditos anuais eM20/M22 não determinados;matéria colectável não é imposto.']:[]));
const assessment=b.assessment?calculateNormalAssessment(b.assessment,base?.taxableBase??null,{year:b.year,scope:b.scope,extended:!!b.schedules,currency:source?.currency??'',...(fiscalPeriod?{period:{from:fiscalPeriod.from,to:fiscalPeriod.to}}:{})}):undefined;
if(assessment)pending.push(...assessment.pending,assessment.finalBalance.reason);
const currentLoss=b.schedules&&profit?.taxableProfit&&BigInt(profit.taxableProfit.numerator)<0n?fraction(-BigInt(profit.taxableProfit.numerator),BigInt(profit.taxableProfit.denominator)):null;
return{...(schedules?{schedules,currentLoss,fiscalPeriod}:{}),...(assessment?{assessment,colecta:assessment.colecta}:{}),...(base?{base}:{}),...(profit?{profit}:{}),version:b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,year:b.year,currency:source?.currency??'',origin:'projected',accountingProfit,additions,partialAdjustedResult:contextReady&&rows.length>0&&rows.every(r=>r.status==='calculated')&&accountingProfit?addFractions([accountingProfit,additions]):null,taxableProfit:profit?.taxableProfit??null,taxableBase:base?.taxableBase??null,tax:null,rows,pending,source:irpcNormalSource+(b.schedules?' Mapas complementares: CIRPC18/21/22/24/36; Decreto72/2013 art3–7. EP: CIRPC15(1)c, apenas resultado imputável ao estabelecimento no regime geral, anual2026/MZN.':'')};
}
export function recordNormal(d:Record<string,unknown>,b:NormalBook,now=new Date().toISOString()):NormalBook{return{...b,history:b.result?[...(b.history??[]),structuredClone(b.result)]:b.history??[],result:{key:key(d,b),createdAt:now,model:calculateNormal(d,b)}};}
const money=(v:FiscalFraction|null)=>v?fractionPresentation(v).decimal+' MZN':'Indeterminado';
function normalBaseReport(m:NormalBaseModel):Array<[string,string,string,string]>{return[['IRPC normal — L6','Matéria colectável — deduções/perdas',`Lucro tributável:${money(m.taxableProfit)};perdas propostas elegíveis:${money(m.requestedLosses)};perdas deduzidas nesta simulação:${money(m.deductedLosses)};benefícios deduzidos:${money(m.benefitDeduction)};matéria colectável simulada:${money(m.taxableBase)};imposto a pagar:Indeterminado. ${m.pending.join(' | ')}`,`NUIT:${m.input.subjectNuit};${m.input.identityReference};método:${m.input.method==='direct'?'Declarativo/directo':m.input.method==='indirect'?'Indirecto':'Por identificar'};${m.input.methodReference};perdas:${m.input.lossesState==='absent'?'Ausência declarada':m.input.lossesState==='known'?'Conhecidas':'Informação em falta'};${m.input.lossesReference};objecto:${m.input.unchangedObject==='yes'?'Sem alteração declarada':m.input.unchangedObject==='no'?'Alteração declarada':'Por esclarecer'};${m.input.objectReference};${m.source}`],['IRPC normal — L6','Benefícios à matéria colectável',`Estado:${m.input.benefits.state==='known'?'Valor conhecido':m.input.benefits.state==='absent'?'Ausência declarada':'Informação em falta'};montante original:${m.input.benefits.amount||'Não preenchido'};dedução:${money(m.benefitDeduction)};não inclui créditos à colecta ou retenções sofridas.`,m.input.benefits.reference],...m.losses.map(l=>['IRPC normal — L6','Perda fiscal de '+l.year,`Estado:${l.status==='eligible'?'Elegível neste recorte':l.status==='excluded'?'Excluída neste exercício':'Indeterminada'};apurada:${l.assessed};utilizada antes:${l.previouslyUsed};saldo:${money(l.available)};utilização proposta:${l.requested};dedução nesta simulação:${money(l.deducted)};saldo aritmético posterior:${money(l.remaining)};último exercício ordinário:${l.lastOrdinaryYear??'Por determinar'};${l.reason}`,`NUIT:${l.subjectNuit};${l.reference};sem consumo do saldo oficial nem reporte automático.`]as[string,string,string,string])];}
function normalAssessmentReport(m:NormalAssessmentModel):Array<[string,string,string,string]>{return[['IRPC normal — L6','Colecta — regime normal',`Matéria colectável:${money(m.taxableBase)};taxa:${m.rate?m.rate.numerator+'%':'Por identificar'};colecta simulada:${money(m.colecta)};${m.classification};${m.centExact===false?'Valor racional exacto com fracção de cêntimo;sem arredondamento fiscal aplicado.':''}${m.pending.join(' | ')}`,`Exercício:${m.period.year};período:${m.period.from}–${m.period.to};${m.input.reference};${m.rule};${m.source}`],['IRPC normal — L6','Saldo final — âmbito L8','A pagar:Indeterminado;a recuperar:Indeterminado. '+m.finalBalance.reason,'Sequência:lucro tributável → matéria colectável → colecta → saldo final;retenções,pagamentos e créditos anuais reservados aL8.']];}
export function normalReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=normalBook(d),r=b.result;if(!r)return[];const m=r.model;return[['IRPC normal — L6','Ajustamentos ao resultado financeiro',`Exercício:${m.year};resultado contabilístico antes de imposto:${money(m.accountingProfit)};acréscimos demonstrados:${money(m.additions)};resultado parcial ajustado:${money(m.partialAdjustedResult)};${m.profit?'lucro tributável simulado:'+money(m.taxableProfit)+(m.base?';matéria colectável simulada:'+money(m.taxableBase)+(m.assessment?';colecta simulada:'+money(m.colecta??null)+';saldo final a pagar ou recuperar:Indeterminado (L8).':';imposto a pagar:Indeterminado.'):';matéria colectável/imposto:Indeterminados.'):'lucro tributável/matéria colectável/imposto:Indeterminados.'} Projecção com pressupostos;${m.pending.join(' | ')}`,`${normalCurrent(d,b)?'Entradas correspondentes':'Histórico;origem ou entradas alteradas'};${r.createdAt};${m.source}`],...(m.base?normalBaseReport(m.base):[]),...(m.assessment?normalAssessmentReport(m.assessment):[]),...(m.schedules?[['IRPC normal — L6','Mapas complementares',`Efeito líquido adicional:${money(m.schedules.net)};perda fiscal do próprio exercício:${money(m.currentLoss??null)};sem reporte ou consumo automático. ${m.schedules.pending.join(' | ')}`,m.schedules.source]as[string,string,string,string],...m.schedules.effects.map(e=>{const i=m.schedules!.input.rows.find(r=>r.id===e.id)!;return['IRPC normal — L6',i.document+'/'+i.line,`Montante:${money(e.amount)};efeito:${money(e.effect)};${e.reason}`,`${i.reference};exercício de imputação:${i.fiscalYear||'Não aplicável'}`]as[string,string,string,string];}),...m.schedules.assets.map(a=>['IRPC normal — L6',a.description,`Depreciação contabilística:${money(a.accountingValue)};quota fiscal:${money(a.fiscal)};acréscimo:${money(a.adjustment)};${a.reason}`,`${a.tableReference};${a.reference}`]as[string,string,string,string]),['IRPC normal — L6','Juros financeiros ordinários',`Remanescente aceite no recorte:${money(m.schedules.interest)};não corresponde a juros de mora/compensatórios L5.`,m.schedules.input.interest.reference]as[string,string,string,string]]:[]),...(m.schedules?[...normalFormFields(m).fields.map(f=>['IRPC normal — L6','M22 campo '+f.code+' — '+f.label,`${f.display};exacto:${f.value?f.value.numerator+'/'+f.value.denominator:'Indeterminado'};transcrição:${f.transcriptionReady?'Preparação parcial com valor exacto ao cêntimo':'Pendente ou sem aplicação'};${f.reason}`,normalFormFields(m).source]as[string,string,string,string]),...normalFormFields(m).m20.fields.map(f=>['IRPC normal — L6','M20 A.1 — conta '+f.account+' — '+f.label,`${f.display};representação em meticais inteiros:${f.transcriptionReady?'Exacta':'Pendente'};${f.reason}`,`${f.reference};${normalFormFields(m).m20.source}`]as[string,string,string,string]),['IRPC normal — L6','M20 — correspondência',normalFormFields(m).m20.reason,normalFormFields(m).m20.source]as[string,string,string,string]]:[]),...m.rows.map(r=>['IRPC normal — L6',r.document+'/'+r.line,`${({calculated:'Calculado neste recorte',indeterminate:'Indeterminado',outside_scope:'Fora deste recorte'})[r.status]};montante:${r.amount};acréscimo:${money(r.adjustment)};${r.reason}`,`Origem:${({revenue:'Receitas',cost_of_sales:'Custo das vendas',operating_expenses:'Despesas operacionais',personnel:'Pessoal',depreciation:'Depreciação contabilística',interest_expense:'Juros reconhecidos'}as Record<string,string>)[r.sourceCode]??'Por corresponder'};incluído:${r.included==='yes'?'Sim':r.included==='no'?'Não':'Por demonstrar'};suporte:${r.reference}`]as[string,string,string,string]),...(m.profit?[...m.profit.lines.map(l=>['IRPC normal — L6','Conferência: '+l.label,`Estado:${l.state==='known'?'Valor conhecido':l.state==='absent'?'Ausência declarada':'Informação em falta'};origem:${l.amount};acréscimos:${money(l.addedBack)};remanescente:${money(l.remainder)};${l.reason}`,l.reference]as[string,string,string,string]),...m.profit.topics.map(t=>['IRPC normal — L6',t.label,`Estado:${t.state==='known'?'Valor conhecido':t.state==='absent'?'Ausência declarada':'Informação em falta'};montante:${money(t.value)};${t.reason}`,t.reference]as[string,string,string,string]),['IRPC normal — L6','Âmbito da conferência',m.profit.input.completenessReference,m.profit.source]as[string,string,string,string]]:[])];}catch(e){return[['IRPC normal — L6','Não recuperável',String(e),'Originais conservados.']];}}
export function normalHtml(d:Record<string,unknown>){const b=normalBook(d);if(!normalCurrent(d,b))throw Error('Calcule e guarde as entradas actuais antes de exportar.');const esc=(s:string)=>s.replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]!));return'<!doctype html><html lang="pt"><meta charset="utf-8"><title>IRPC normal — ajustamentos</title><h1>L6 — mapa parcial de ajustamentos</h1><p>Projecção pelos pressupostos do plano. Não é demonstração contabilística,liquidação ou Modelo20/22.</p>'+normalReportRows(d).map(r=>'<section><h2>'+esc(r[1])+'</h2><p>'+esc(r[2])+'</p><small>'+esc(r[3])+'</small></section>').join('')+'</html>';}
@@ -0,0 +1,96 @@
import type {IrpcRow} from './irpc-withholdings.ts';
export const irpcReliefVersion = 'IRPC-L5-reliefs/1';
export type IrpcReliefPreparation = {
rule?: '' | 'cirpc68d' | 'cirpc68f' | 'ptMz12';
facts?: Partial<Record<'subjectToIrpc' | 'notTransparent' | 'treatyResident' | 'beneficialOwner' | 'payerResidentMz' | 'armLength' | 'royaltyDefinition', '' | 'yes' | 'no'>>;
kind: 'dispensation' | 'exemption' | 'treaty';
instrument: string;
article: string;
country: string;
residenceDocument: string;
validFrom: string;
validTo: string;
conditions: string;
evidence: string;
};
export const irpcReliefRules = [
['', 'Correspondência por identificar'],
['cirpc68d', 'Dispensa — artigo 68(d), serviços / uso de equipamento'],
['cirpc68f', 'Dispensa — artigo 68(f), gestão de imóveis próprios'],
['ptMz12', 'Portugal–Moçambique — royalties, artigo 12'],
] as const;
const documentLabels: Record<string,string> = {instrument:'diploma/convenção',article:'artigo',validFrom:'início do período',validTo:'fim do período',conditions:'condições',evidence:'documentos',country:'Estado contratante',residenceDocument:'prova de residência'};
const factLabels: Record<string,string> = {subjectToIrpc:'Titular sujeito a IRPC neste rendimento',notTransparent:'Fora da transparência fiscal',treatyResident:'Residência convencional em Portugal',beneficialOwner:'Beneficiário efectivo',payerResidentMz:'Devedor residente em Moçambique',armLength:'Sem excesso por relações especiais',royaltyDefinition:'Definição convencional de royalties'};
export function evaluateIrpcRelief(row: IrpcRow, eventDate: string):
{applied: false; reason: string} | {applied: true; treatment: 'dispensed' | 'treaty'; rate: number; reason: string; rule: string} {
const e = row.reliefPreparation;
if (!e) return {applied: false, reason: 'Identifique a regra da dispensa/convenção e os documentos aplicáveis.'};
const preparation = prepareIrpcRelief(row, e);
if (preparation.missing.length || !preparation.validPeriod || eventDate < e.validFrom || eventDate > e.validTo)
return {applied: false, reason: 'Informação insuficiente ou período incompatível na dispensa/convenção: ' + preparation.missing.map(k=>documentLabels[k]).join(', ') + '. Confira o período e a prova aplicáveis ao primeiro evento.'};
const f = e.facts ?? {};
const article = e.article.toLowerCase().replace(/[^a-z0-9]/g, '');
if (e.rule === 'cirpc68d' && article !== '68d' || e.rule === 'cirpc68f' && article !== '68f' || e.rule === 'ptMz12' && article !== '12')
return {applied: false, reason: 'O artigo invocado diverge da regra seleccionada; reconcilie a referência sem apagar a prova.'};
const onAccount = row.residence === 'resident' || row.residence === 'nonresident' && row.permanentEstablishment === 'yes' && row.attributable === 'yes';
if (e.rule === 'cirpc68d' || e.rule === 'cirpc68f') {
if (e.kind !== 'dispensation' || f.subjectToIrpc !== 'yes' || row.recipientIrpc !== 'yes' || !row.ordinary || row.ordinary.nonDigital !== 'yes' || !row.ordinary.reference.trim())
return {applied: false, reason: 'Dispensa: identifique o titular sujeito a IRPC relativamente a este rendimento e a classificação não digital, com suporte.'};
if (e.rule === 'cirpc68d' && (!onAccount || !['equipment', 'services'].includes(row.kind)))
return {applied: false, reason: 'Artigo 68(d) exige rendimento 67(1)b/g com natureza de imposto por conta; não dispensa retenções definitivas.'};
if (e.rule === 'cirpc68f' && (row.kind !== 'rent' || row.ordinary.rentOwnPropertyManagement !== 'yes' || f.notTransparent !== 'yes'))
return {applied: false, reason: 'Artigo 68(f): faltam rendas de sociedade de gestão de imóveis próprios e exclusão documentada da transparência fiscal (6(1)c).'};
return {applied: true, treatment: 'dispensed', rate: 0, rule: e.rule,
reason: `Dispensa de retenção ${e.rule === 'cirpc68d' ? '68(d), rendimentos 67(1)b/g' : '68(f), rendimentos prediais 67(1)c e 6(1)c'}; CIRPC Lei 34/2007, PDF19/p768(73). Sem retenção nesta operação; não é isenção do rendimento nem crédito anual.`};
}
if (e.rule === 'ptMz12') {
if (e.kind !== 'treaty' || !['PT', 'PORTUGAL'].includes(e.country.trim().toUpperCase()) || row.residence !== 'nonresident' || row.permanentEstablishment !== 'no' || !['royalty', 'equipment'].includes(row.kind) || row.ordinary?.nonDigital !== 'yes' || !row.ordinary.reference.trim())
return {applied: false, reason: 'Convenção PT–MZ, artigo 12: este recorte exige titular residente em Portugal, sem EP em Moçambique e royalties/uso de equipamento qualificados não digitais. Outros casos conservam correspondência própria.'};
if (['treatyResident', 'beneficialOwner', 'payerResidentMz', 'armLength', 'royaltyDefinition'].some(k => f[k as keyof typeof f] !== 'yes'))
return {applied: false, reason: 'Informação insuficiente: documente residência convencional (art.4), beneficiário efectivo, devedor residente em Moçambique, definição de royalties e ausência de excesso por relações especiais (art.12(2–6)).'};
return {applied: true, treatment: 'treaty', rate: 10, rule: e.rule,
reason: 'Limite convencional de 10% sobre royalties brutas: CDT PT–MZ artigo12(2–6), RAR36/1992; definição12(3) e IRPC actualizados pelo Protocolo/RAR36/2009 arts1/7. Cálculo da retenção; formalidades de accionamento e MRFTA não equivalem a submissão ou aceitação AT.'};
}
return {applied: false, reason: 'Dispensa, isenção ou convenção sem correspondência executável neste recorte; conserve os documentos e identifique a regra específica.'};
}
export const newIrpcReliefPreparation = (): IrpcReliefPreparation => ({
kind: 'dispensation', instrument: '', article: '', country: '',
residenceDocument: '', validFrom: '', validTo: '', conditions: '', evidence: '',
});
// A preparation records an invocation; it does not activate a tax rule.
export function prepareIrpcRelief(row: IrpcRow, evidence: IrpcReliefPreparation) {
const missing = (['instrument', 'article', 'validFrom', 'validTo', 'conditions', 'evidence'] as const)
.filter(key => !evidence[key].trim()).map(String);
if (evidence.kind === 'treaty') {
if (!evidence.country.trim()) missing.push('country');
if (!evidence.residenceDocument.trim()) missing.push('residenceDocument');
}
const validDate = (s: string) => /^\d{4}-\d{2}-\d{2}$/.test(s) &&
Number.isFinite(Date.parse(s)) && new Date(s).toISOString().slice(0, 10) === s;
const validPeriod = validDate(evidence.validFrom) && validDate(evidence.validTo) && evidence.validFrom <= evidence.validTo;
const outsidePeriod = validPeriod && row.events.some(event => validDate(event.date) &&
(event.date < evidence.validFrom || event.date > evidence.validTo));
return {
counterparty: row.counterparty, residence: row.residence,
permanentEstablishment: row.permanentEstablishment, attributable: row.attributable,
documentRef: row.documentRef, qualificationRef: row.qualificationRef,
previousReference: row.reliefRef, evidence: structuredClone(evidence),
missing, validPeriod, outsidePeriod,
status: 'preparation' as const,
notice: 'Condições e documentos invocados; o cálculo verifica apenas a regra seleccionada e o período aplicável.',
};
}
export function irpcReliefEvidenceLabel(row: IrpcRow): string {
const e = row.reliefPreparation;
if (!e) return row.reliefRef || 'Sem benefício invocado';
const p = prepareIrpcRelief(row, e);
return `${irpcReliefRules.find(([rule])=>rule===e.rule)?.[1]??'Regra por corresponder'};${e.instrument};artigo:${e.article};período:${e.validFrom}–${e.validTo};Estado:${e.country};residência fiscal:${e.residenceDocument};condições:${e.conditions};provas:${e.evidence};${Object.entries(e.facts??{}).map(([k,v])=>`${factLabels[k]??k}:${v==='yes'?'Sim':v==='no'?'Não':'Por esclarecer'}`).join(';')};${p.missing.length?'Falta: '+p.missing.map(k=>documentLabels[k]).join(', '):'Elementos documentais registados'};${p.validPeriod?'Período válido':'Período por resolver'};referência anterior:${row.reliefRef}`;
}
+122
View File
@@ -0,0 +1,122 @@
import {validateMrfta,mrftaReportRows,type MrftaStore} from './irpc-mrfta.ts';
import {irpcReliefVersion,evaluateIrpcRelief,irpcReliefEvidenceLabel,type IrpcReliefPreparation} from './irpc-relief-preparation.ts';
import {convertIrpcAmount,irpcFxDependency,irpcFxEvidenceLabel,type IrpcFxAmount,type IrpcFxEvidence} from './irpc-fx.ts';
import {acquisitionBook,acquisitionScope} from './iva-acquisitions.ts';
import {salesBook} from './iva-operations.ts';
import {closureFingerprint} from './iva-closure.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export const irpcWithholdingVersion='irpc-L5/1';
export const irpcWithholdingSource='Lei12/2025,BR248/2025,PDF19/p2180(19):arts5(5/7),20(2)c,62(5)a/b e67(5/7);CIRPC Lei34/2007 arts2,62/67/68,PDF17–19/p768(71–73);Lei19/2013 PDF2/p682(22),62(3/4);Lei20/2022 BR252 p2731/PDF1,62(1–5). Art67(7)remete62(6),enquanto taxa nova consta62(5):divergência formal preservada,sem renumerar o original. MRFTA19/39AT,p1–2. Código2002 revogado não usado. Outros regimes/taxas dependem da correspondência específica,sem zero presumido.';
type Choice=''|'yes'|'no';
export type IrpcKind=''|'digital_goods'|'digital_services'|'emoney_commission'|'royalty'|'equipment'|'rent'|'capital'|'services'|'telecom'|'international_transport'|'connected_installation'|'aircraft_maintenance_charter'|'rural_public_electrification'|'maritime_fishing_cabotage'|'other';
export const irpcKinds:Array<[IrpcKind,string]>=[['','Por identificar'],['digital_goods','Transmissão de bens digitais'],['digital_services','Prestação de serviços digitais'],['emoney_commission','Comissão de agente de moeda electrónica'],['royalty','Propriedade intelectual/industrial'],['equipment','Uso de equipamento'],['rent','Rendimento predial'],['capital','Aplicação de capitais'],['services','Outras prestações/intermediação'],['telecom','Serviços de telecomunicações — artigo62(4)a'],['international_transport','Transportes internacionais — artigo62(4)a'],['connected_installation','Montagem/instalação de equipamentos conexos a telecomunicações/transportes —62(4)a'],['aircraft_maintenance_charter','Manutenção e fretamento de aeronaves —62(4)a'],['rural_public_electrification','Construção/reabilitação de infraestruturas de produção,transporte e distribuição de energia eléctrica,nas zonas rurais,em projectos públicos de electrificação rural —62(4)b'],['maritime_fishing_cabotage','Afretamento de embarcações marítimas para pesca/cabotagem —62(4)c'],['other','Outro enquadramento']];
export type IrpcEvent={kind:'cost'|'payment'|'maturity'|'availability'|'liquidation'|'quantification';date:string;reference:string};
export type IrpcPayment=IrpcFxAmount&{id:string;kind:'beneficiary'|'remittance'|'withholding_proof';reference:string;date:string;amount:string;currency:string};
export type IrpcOrdinaryFacts={nonDigital:Choice;capitalType:''|'unlisted_interest'|'unlisted_dividend'|'listed_debt_mz'|'listed_other_mz'|'liquidity_repo'|'other';rentOwnPropertyManagement:Choice;specialFacts:Choice;capitalSeatAndManagement?:Choice;reference:string};
export const emptyIrpcOrdinaryFacts=():IrpcOrdinaryFacts=>({nonDigital:'',capitalType:'',rentOwnPropertyManagement:'',specialFacts:'',capitalSeatAndManagement:'',reference:''});
export type IrpcRow=IrpcFxAmount&{reliefPreparation?:IrpcReliefPreparation;ordinary?:IrpcOrdinaryFacts;id:string;direction:'paid'|'received';counterparty:string;documentRef:string;description:string;base:string;currency:string;origin:'projected'|'effective';kind:IrpcKind;recipientIrpc:Choice;payerIrpc:Choice;residence:''|'resident'|'nonresident';permanentEstablishment:Choice;attributable:Choice;mozambique:Choice;qualificationRef:string;specialRelief:''|'none'|'claimed';reliefRef:string;eventsComplete:Choice;events:IrpcEvent[];settlement:''|'none'|'complete';settlementRef:string;allocations:Array<{paymentId:string;amount:string}>;source?:{id:string;key:string;fingerprint:string};};
export type IrpcResult={treatment?:'dispensed'|'treaty';reliefRule?:string;id:string;status:'calculated'|'indeterminate'|'outside_scope';reason:string;period:string;eventDate:string;nature:'definitive'|'on_account'|null;rate:number|null;base:FiscalFraction|null;tax:FiscalFraction|null;settled:FiscalFraction|null;outstanding:FiscalFraction|null;direction:IrpcRow['direction'];conversion?:IrpcFxEvidence|null};
export type IrpcBook=MrftaStore&{version:1;rows:IrpcRow[];payments:IrpcPayment[];result?:{version:string;key:string;calculatedAt:string;inputs:IrpcRow[];payments:IrpcPayment[];rows:IrpcResult[];paymentConversions?:Record<string,IrpcFxEvidence|null>};history?:Array<NonNullable<IrpcBook['result']>>};
export const newIrpcRow=(id:string):IrpcRow=>({id,direction:'paid',counterparty:'',documentRef:'',description:'',base:'',currency:'MZN',origin:'projected',kind:'',recipientIrpc:'',payerIrpc:'',residence:'',permanentEstablishment:'',attributable:'',mozambique:'',qualificationRef:'',specialRelief:'',reliefRef:'',eventsComplete:'',events:[],settlement:'',settlementRef:'',allocations:[]});
function store(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros fiscais não recuperáveis;originais preservados.');return s;}
function map(d:Record<string,unknown>):Record<string,IrpcBook>{const m=store(d).irpcWithholdings;if(m===undefined)return{};if(!m||typeof m!=='object'||Array.isArray(m))throw Error('Mapa IRPC não recuperável;originais preservados.');return m;}
function validate(b:IrpcBook){
if(!b||b.version!==1||!Array.isArray(b.rows)||!Array.isArray(b.payments)||b.history!==undefined&&!Array.isArray(b.history))throw Error('Livro IRPC não recuperável.');
validateMrfta(b);
for(const r of b.rows){const template=newIrpcRow('');if(!r||Object.keys(template).filter(k=>typeof template[k as keyof IrpcRow]==='string').some(k=>typeof r[k as keyof IrpcRow]!=='string')||!['paid','received'].includes(r.direction)||!['projected','effective'].includes(r.origin)||!irpcKinds.some(([k])=>k===r.kind)||!['','resident','nonresident'].includes(r.residence)||!['','none','claimed'].includes(r.specialRelief)||!['','none','complete'].includes(r.settlement)||['recipientIrpc','payerIrpc','permanentEstablishment','attributable','mozambique','eventsComplete'].some(k=>!['','yes','no'].includes(r[k as keyof IrpcRow]as string))||!Array.isArray(r.events)||!Array.isArray(r.allocations)||r.events.some(e=>!e||!['cost','payment','maturity','availability','liquidation','quantification'].includes(e.kind)||typeof e.date!=='string'||typeof e.reference!=='string')||r.allocations.some(a=>!a||typeof a.paymentId!=='string'||typeof a.amount!=='string')||r.source!==undefined&&(!r.source||!['id','key','fingerprint'].every(k=>typeof r.source![k as keyof NonNullable<IrpcRow['source']>]==='string')))throw Error('Entradas IRPC não recuperáveis;sem apagar ou repor vazios.');}
for(const r of b.rows)if(r.reliefPreparation&&(r.reliefPreparation.rule!==undefined&&!['','cirpc68d','cirpc68f','ptMz12'].includes(r.reliefPreparation.rule)||r.reliefPreparation.facts!==undefined&&(!r.reliefPreparation.facts||typeof r.reliefPreparation.facts!=='object'||Array.isArray(r.reliefPreparation.facts)||Object.values(r.reliefPreparation.facts).some(v=>!['','yes','no'].includes(v)))))throw Error('Condições da dispensa/convenção não recuperáveis.');
for(const r of b.rows)if(r.reliefPreparation&&(!['dispensation','exemption','treaty'].includes(r.reliefPreparation.kind)||['instrument','article','country','residenceDocument','validFrom','validTo','conditions','evidence'].some(k=>typeof r.reliefPreparation![k as keyof IrpcReliefPreparation]!=='string')))throw Error('Preparação de dispensa/convenção não recuperável;original preservado.');
for(const r of b.rows)if(r.ordinary&&(['nonDigital','rentOwnPropertyManagement','specialFacts'].some(k=>!['','yes','no'].includes(r.ordinary![k as 'nonDigital'|'rentOwnPropertyManagement'|'specialFacts']))||typeof r.ordinary.reference!=='string'||!['','unlisted_interest','unlisted_dividend','listed_debt_mz','listed_other_mz','liquidity_repo','other'].includes(r.ordinary.capitalType)))throw Error('Factos específicos IRPC não recuperáveis.');
for(const r of b.rows)if(r.ordinary?.capitalSeatAndManagement!==undefined&&!['','yes','no'].includes(r.ordinary.capitalSeatAndManagement))throw Error('Factos de sede/direcção não recuperáveis.');
for(const v of [...b.rows,...b.payments])if(v.fxSelection!==undefined&&(!v.fxSelection||typeof v.fxSelection!=='object'||Array.isArray(v.fxSelection))||v.fxLink!==undefined&&(!v.fxLink||typeof v.fxLink.id!=='string'||typeof v.fxLink.fingerprint!=='string'))throw Error('Vínculo/selecção cambial não recuperável;original preservado.');
for(const p of b.payments)if(!p||!['id','reference','date','amount','currency'].every(k=>typeof p[k as keyof IrpcPayment]==='string')||!['beneficiary','remittance','withholding_proof'].includes(p.kind))throw Error('Pagamento IRPC inválido;originais preservados.');
if(b.result&&(!Array.isArray(b.result.rows)||!Array.isArray(b.result.inputs)||typeof b.result.key!=='string'||b.result.version!==irpcWithholdingVersion))throw Error('Resultado IRPC não recuperável.');
if(b.payments.some((p,i)=>p.reference.trim()&&b.payments.some((q,j)=>i!==j&&q.kind===p.kind&&q.reference.trim()===p.reference.trim()&&q.date===p.date&&q.currency===p.currency)))throw Error('Pagamento/prova já registado:reutilize a referência existente em vez de duplicar.');
if(new Set(b.rows.map(r=>r.id)).size!==b.rows.length||new Set(b.payments.map(p=>p.id)).size!==b.payments.length)throw Error('Identificadores IRPC repetidos.');
}
export function irpcBook(d:Record<string,unknown>):IrpcBook{const b=map(d)[acquisitionScope(d)]??{version:1,rows:[],payments:[]};validate(b);return b;}
export function saveIrpcBook(d:Record<string,unknown>,b:IrpcBook):string{validate(b);return JSON.stringify({...store(d),irpcWithholdings:{...map(d),[acquisitionScope(d)]:b}});}
export function irpcSources(d:Record<string,unknown>){return[
...acquisitionBook(d).rows.map(r=>({id:'acquisition:'+r.id,key:closureFingerprint(r),counterparty:r.supplier,documentRef:r.documentRef+(r.documentLine?' / linha '+r.documentLine:''),description:r.description,amount:r.net,currency:acquisitionBook(d).currency,direction:'paid' as const,origin:r.origin})),
...salesBook(d).rows.map(r=>({id:'sale:'+r.id,key:closureFingerprint(r),counterparty:'',documentRef:r.evidence,description:r.description,amount:r.basis==='net'?r.amount:'',currency:r.sourceCurrency,direction:'received' as const,origin:'projected' as const})),
];}
export function reuseIrpcSources(d:Record<string,unknown>,b:IrpcBook):IrpcBook{validate(b);const rows=[...b.rows];for(const s of irpcSources(d))if(!rows.some(r=>r.source?.id===s.id)){const r={...newIrpcRow('irpc:'+s.id),counterparty:s.counterparty,documentRef:s.documentRef,description:s.description,base:s.amount,currency:s.currency,direction:s.direction,origin:s.origin};rows.push({...r,source:{id:s.id,key:s.key,fingerprint:closureFingerprint(r)}});}return{...b,rows};}
function sourceIssue(d:Record<string,unknown>,r:IrpcRow){if(!r.source)return'';const s=irpcSources(d).find(s=>s.id===r.source!.id);return !s?'Operação de origem não está disponível neste contexto;vínculo e edições conservados.':s.key!==r.source.key?'Documento/operação de origem alterado;compare o histórico e reconcilie a divergência antes de calcular.':'';}
const date=(s:string)=>/^20\d{2}-(0[1-9]|1[0-2])-\d{2}$/.test(s)&&!Number.isNaN(Date.parse(s))&&new Date(s).toISOString().slice(0,10)===s;
const positive=(f:FiscalFraction)=>BigInt(f.numerator)>0n;
export function evaluateIrpc(d:Record<string,unknown>,r:IrpcRow):IrpcResult{
const v:IrpcResult={id:r.id,status:'indeterminate',reason:'Identifique o rendimento e os intervenientes.',period:'',eventDate:'',nature:null,rate:null,base:null,tax:null,settled:null,outstanding:null,direction:r.direction};
const issue=sourceIssue(d,r)||irpcFxDependency(d,r);if(issue)return{...v,reason:issue};
if(r.recipientIrpc==='no')return{...v,status:'outside_scope',reason:'Titular fora de IRPC;sem converter em IRPS ou em isenção.'};
if(!r.counterparty.trim()||!r.documentRef.trim()||r.recipientIrpc!=='yes'||r.payerIrpc!=='yes'||!r.residence||!r.kind||!r.qualificationRef.trim())return{...v,reason:'Faltam contraparte,documento,qualificação do rendimento,titular IRPC,devedor IRPC ou residência. A via devedor IRPS exige âmbito próprio.'};
if(r.mozambique!=='yes')return{...v,reason:'Falta correspondência territorial aos arts5/67;ser estrangeiro não resolve incidência nem isenção.'};
if(r.specialRelief!=='none'&&r.specialRelief!=='claimed')return{...v,reason:'Convenção,isenção ou dispensa invocada/desconhecida:identificar artigo,período,condições e prova;sem taxa reduzida ou zero automáticos.'};
if(!r.eventsComplete||r.eventsComplete!=='yes'||!r.events.length||r.events.some(e=>!date(e.date)||!e.reference.trim()))return{...v,reason:'Identifique os eventos aplicáveis67(5),incluindo reconhecimento do custo,e confirme a sua completude com suporte;uma factura ou pagamento isolado não fixa o momento.'};
v.eventDate=r.events.map(e=>e.date).sort()[0];v.period=v.eventDate.slice(0,7);
if(!v.eventDate.startsWith('2026-'))return{...v,reason:'Primeiro evento aplicável fora de2026;corresponder versão/período próprio,sem deslocar para o pagamento posterior.'};
try{const converted=convertIrpcAmount(d,r.base,r);v.base=converted.value;v.conversion=converted.evidence;}catch(e){return{...v,reason:'Base do rendimento/conversão por resolver: '+String(e)};}
if(r.specialRelief==='claimed'){
const relief=evaluateIrpcRelief(r,v.eventDate);if(!relief.applied)return{...v,reason:relief.reason};
v.treatment=relief.treatment;v.reliefRule=relief.rule;v.rate=relief.rate;v.nature=relief.treatment==='treaty'?'definitive':'on_account';v.reason=relief.reason;
v.tax=fraction(BigInt(v.base.numerator)*BigInt(relief.rate),BigInt(v.base.denominator)*100n);v.status='calculated';return v;
}
const digital=['digital_goods','digital_services','emoney_commission'].includes(r.kind);
if(digital){
if(r.residence==='nonresident'&&r.permanentEstablishment==='no'||r.residence==='nonresident'&&r.permanentEstablishment==='yes'&&r.attributable==='no')v.nature='definitive';
else return{...v,reason:'Para residente ou rendimento imputável aEP,corresponder concretamente a taxa62(5) com as dispensas68,em especial68(d),antes da liquidação. EP desconhecido permanece indeterminado;90dias/serviço digital não criam ausência deEP automática.'};
v.rate=10;v.reason='Taxa10%62(5) no âmbito digital/moeda electrónica demonstrado;retenção definitiva67(3). Procedimento67(7)/remissão62(6) e CER permanecem separados.';
}else{
const f=r.ordinary;
if(!f||f.nonDigital!=='yes'||!f.reference.trim())return{...v,reason:'Classifique o rendimento não abrangido pelo ramo digital/moeda electrónica e identifique os factos específicos. Cotejo62/67:Lei34/2007,Lei19/2013 eLei20/2022 agora disponível;sem taxa genérica.'};
const nonresident=r.residence==='nonresident';
if(nonresident&&r.permanentEstablishment!=='no'&&!(r.permanentEstablishment==='yes'&&['yes','no'].includes(r.attributable)))return{...v,reason:'Falta identificar EP e imputação;ausência física ou nacionalidade não resolvem este facto.'};
const attributable=!nonresident||r.permanentEstablishment==='yes'&&r.attributable==='yes';
v.nature=r.kind==='rent'||attributable?'on_account':'definitive';
if(['equipment','services'].includes(r.kind)&&v.nature==='on_account')return{...v,reason:'Rendimento67(1)b/g com imposto por conta:dispensa68(d) identificada,por corresponder no ramo de dispensas;não reter20% nem declarar isenção do rendimento.'};
if(r.kind==='rent'&&f.rentOwnPropertyManagement!=='no')return{...v,reason:'Rendimento predial mantém natureza por conta67(3). Identifique a gestão de imóveis próprios e eventual dispensa68(f)/transparência;apenas este caso depende dessa correspondência.'};
if(r.kind==='capital'){
if(!f.capitalType||f.capitalType==='other')return{...v,reason:'Identifique juros/dividendos não cotados,títulos cotadosBM ou permutas de liquidez;62(3/4) não permite taxa única para capitais.'};
if(r.residence==='resident'&&['listed_debt_mz','liquidity_repo'].includes(f.capitalType)){if(f.capitalSeatAndManagement!=='yes')return{...v,reason:'Art62(3):identifique sede e direcção efectiva nacionais do titular,além da categoria exacta dos títulos/permuta;residência genérica não substitui estes factos.'};v.nature='definitive';}
if(v.nature==='on_account'&&f.capitalType!=='listed_debt_mz')return{...v,reason:'Capitais com imposto por conta:correspondência específica das dispensas68(a/b/c/g),incluindo titular e operação,permanece separada;sem bloquear capitais definitivos independentes.'};
if(f.capitalType==='liquidity_repo'&&r.residence!=='resident')return{...v,reason:'Permutas de liquidez62(3)b exigem entidade com sede/direcção efectiva nacional;caso não residente mantém correspondência própria.'};
}
const special=['telecom','international_transport','connected_installation','aircraft_maintenance_charter','rural_public_electrification','maritime_fishing_cabotage'].includes(r.kind)||r.kind==='capital'&&f.capitalType==='listed_other_mz';
if(special){
if(!nonresident||r.permanentEstablishment!=='no')return{...v,reason:'Taxa especial62(4) refere entidades62(2),não residentes semEP. O caso residente/EP tem correspondência própria;sem copiar10%.'};
if(f.specialFacts!=='yes')return{...v,reason:'Confirme os factos exactos62(4)a–d:conexão dos equipamentos,projecto público rural,pesca/cabotagem ou título cotadoBM que não é dívida/bilhete62(3)a,conforme categoria. Sem taxa especial por descrição genérica.'};
v.rate=10;v.reason='Taxa especial10%62(4),redacçãoLei19/2013,conservada emLei20/2022 eLei12/2025;entidade não residente semEP e categoria específica identificadas. Não é a taxa digital62(5).';
}else{
if(!['royalty','equipment','rent','capital','services'].includes(r.kind))return{...v,reason:'Natureza fora dos ramos agrupados;identificar artigo e condições próprios,sem taxa por defeito.'};
v.rate=20;v.reason=(r.kind==='capital'&&r.residence==='resident'&&['listed_debt_mz','liquidity_repo'].includes(f.capitalType)?'Retenção liberatória20%62(3)a/b:juros de dívida/bilhetes cotados ou permuta de liquidez qualificados,com sede e direcção efectiva nacionais. ':'')+'Taxa20%62(1),com62(2/3) quando aplicável;incidência67(1),natureza67(3). Lei20/2022,p2731,confrontada:as medidas agrícolas terminam31/12/2025 e não são transportadas para2026. Sem aplicar10% digital a rendimentos não digitais.';
}
}
v.tax=fraction(BigInt(v.base.numerator)*BigInt(v.rate!),BigInt(v.base.denominator)*100n);v.status='calculated';v.reason+=' Base separada do IVA;entrega/prova e liquidação anual mantêm reconciliação própria.';return v;
}
function sharedPayments(d:Record<string,unknown>,b:IrpcBook){const used=b.payments.filter(p=>b.rows.some(r=>r.allocations.some(a=>a.paymentId===p.id)));return Object.entries(map(d)).filter(([ctx])=>ctx!==acquisitionScope(d)).flatMap(([ctx,other])=>{validate(other);const payments=other.payments.filter(q=>used.some(p=>p.reference.trim()===q.reference.trim()&&p.date===q.date&&p.currency===q.currency&&p.kind===q.kind));return payments.length?[[ctx,payments,other.rows.flatMap(r=>r.allocations.filter(a=>payments.some(p=>p.id===a.paymentId)))]]:[];});}
function key(d:Record<string,unknown>,b:IrpcBook){const fx=[...b.rows,...b.payments].filter(r=>r.currency!=='MZN'&&r.fxLink).map(r=>irpcFxDependency(d,r));return JSON.stringify([irpcWithholdingVersion,acquisitionScope(d),b.rows,b.payments,b.rows.map(r=>sourceIssue(d,r)),sharedPayments(d,b),...(fx.length?[fx]:[]),...(b.rows.some(r=>r.specialRelief==='claimed')?[irpcReliefVersion]:[])]);}
export function irpcCurrent(d:Record<string,unknown>,b:IrpcBook){return !!b.result&&b.result.key===key(d,b);}
export function recordIrpc(d:Record<string,unknown>,b:IrpcBook,now=new Date().toISOString()):IrpcBook{
validate(b);const rows=b.rows.map(r=>evaluateIrpc(d,r));const paymentConversions:Record<string,IrpcFxEvidence|null>={};const allocations=new Map<string,FiscalFraction[]>();
const fail=(i:number,reason:string)=>{rows[i]={...rows[i],status:'indeterminate',reason,settled:null,outstanding:null};};
b.rows.forEach((r,i)=>{
if(rows[i].status!=='calculated')return;
if(rows[i].treatment==='dispensed'){if(r.allocations.length){fail(i,'Dispensa com entrega/prova associada: reconcilie sem apagar o pagamento nem gerar crédito automático.');return;}rows[i].settled=fraction(0n,1n);rows[i].outstanding=fraction(0n,1n);return;}
if(r.settlement==='none'&&r.allocations.length){fail(i,'Ausência de entrega/prova contradiz pagamentos associados;conserve e reconcilie.');return;}
if(!r.settlement||!r.settlementRef.trim()){rows[i].reason+=' Entrega à AT/retenção sofrida ainda não reconciliada;não presumir zero pago.';return;}
const parts:FiscalFraction[]=[];const seen=new Set<string>();
for(const a of r.allocations){const p=b.payments.find(p=>p.id===a.paymentId);try{
if(!p||seen.has(p.id)||p.kind==='remittance'&&p.currency!=='MZN'||!date(p.date)||p.date<rows[i].eventDate||!p.reference.trim()||p.kind!==(r.direction==='paid'?'remittance':'withholding_proof'))throw Error();
seen.add(p.id);const amount=decimalFraction(a.amount);paymentConversions[p.id]=convertIrpcAmount(d,p.amount,p).evidence;parts.push(amount);allocations.set(p.id,[...(allocations.get(p.id)??[]),amount]);
}catch(e){fail(i,'Pagamento/prova ausente,incoerente,repetido ou de outra natureza:pagamento ao fornecedor e imposto IVA não são entrega IRPC. '+String(e));return;}}
const settled=addFractions(parts);if(positive(subtractFractions(settled,rows[i].tax!))){fail(i,'Valor associado excede a retenção calculada;reconcilie excesso sem gerar crédito automático.');return;}
rows[i].settled=settled;rows[i].outstanding=subtractFractions(rows[i].tax!,settled);
});
for(const [id,parts]of allocations){const p=b.payments.find(p=>p.id===id)!;let excess=false;try{const elsewhere:FiscalFraction[]=[];for(const [ctx,other]of Object.entries(map(d))){if(ctx===acquisitionScope(d))continue;validate(other);for(const q of other.payments.filter(q=>q.reference.trim()===p.reference.trim()&&q.date===p.date&&q.kind===p.kind&&q.currency===p.currency)){if(q.amount!==p.amount||q.currency!=='MZN'&&JSON.stringify(q.fxSelection)!==JSON.stringify(p.fxSelection))throw Error('Montantes/conversões divergentes');for(const r of other.rows)for(const a of r.allocations.filter(a=>a.paymentId===q.id))elsewhere.push(decimalFraction(a.amount));}}excess=positive(subtractFractions(addFractions([...parts,...elsewhere]),convertIrpcAmount(d,p.amount,p).value));}catch{excess=true;}if(excess)b.rows.forEach((r,i)=>{if(r.allocations.some(a=>a.paymentId===id))fail(i,'Mesmo pagamento utilizado além do montante disponível;reparta sem duplicação.');});}
// An identical source document/income cannot become a second tax just by adding a row.
b.rows.forEach((r,i)=>{if(b.rows.some((s,j)=>j!==i&&(r.source&&s.source?.id===r.source.id||r.documentRef.trim()&&s.documentRef.trim()===r.documentRef.trim()&&s.counterparty.trim()===r.counterparty.trim()&&s.direction===r.direction))){fail(i,'Documento/rendimento repetido neste livro;identifique parcelas próprias antes de somar,sem duplicação.');}});
return{...b,history:b.result?[...(b.history??[]),structuredClone(b.result)]:b.history,result:{version:irpcWithholdingVersion,key:key(d,b),calculatedAt:now,inputs:structuredClone(b.rows),payments:structuredClone(b.payments),rows,paymentConversions}};
}
const amount=(v:FiscalFraction|null)=>{if(!v)return'Indeterminado';const p=fractionPresentation(v);return(p.approximate?'≈':'')+p.decimal+' MZN';};
export function irpcReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=irpcBook(d),r=b.result;if(!r)return mrftaReportRows(b,false);return [...r.rows.map((v):[string,string,string,string]=>{const i=r.inputs.find(i=>i.id===v.id)!;return['IRPC — retenções',`${i.documentRef} — ${i.counterparty}`,`${({calculated:'Calculado',indeterminate:'Indeterminado',outside_scope:'Fora deste âmbito'})[v.status]};tratamento:${v.treatment==='dispensed'?'Dispensa de retenção':v.treatment==='treaty'?'Limite convencional':'Retenção interna'};enquadramento: ${irpcKinds.find(([k])=>k===i.kind)?.[1]??i.kind};${i.direction==='paid'?'retida a entregar':'sofrida'};base:${amount(v.base)};taxa:${v.treatment==='dispensed'?'Dispensa (sem retenção)':(v.rate??'por corresponder')+'%'};retenção:${amount(v.tax)};entrega/prova:${amount(v.settled)};saldo:${amount(v.outstanding)};${v.reason}`,`${acquisitionScope(d)};${i.origin};${v.period};evento:${v.eventDate};${v.nature==='on_account'?'Imposto por conta (sem crédito anual automático)':v.nature==='definitive'?'Retenção definitiva':'Natureza por determinar'};${irpcCurrent(d,b)?'Entradas correspondentes':'Histórico;entradas/origem divergentes'};dispensa/convenção:${irpcReliefEvidenceLabel(i)};reconciliação:${i.settlementRef};comprovativos:${i.allocations.map(a=>{const p=r.payments.find(p=>p.id===a.paymentId);return p?`${p.reference}/${p.date}:parcela${a.amount}MZN de${p.amount}${p.currency};${r.paymentConversions?.[p.id]?irpcFxEvidenceLabel(r.paymentConversions[p.id]!):'sem conversão usada'}`:'referência por resolver';}).join(' | ')};${r.calculatedAt};${v.conversion?'Câmbio:'+irpcFxEvidenceLabel(v.conversion)+';':''}${irpcWithholdingSource}`];}),...mrftaReportRows(b,irpcCurrent(d,b))];}catch(e){return[['IRPC — retenções','Livro não recuperável',String(e),'Originais e histórico preservados.']];}}
export function irpcPreparationHtml(d:Record<string,unknown>):string{const b=irpcBook(d);if(!b.result||!irpcCurrent(d,b))throw Error('Calcule e guarde as entradas actuais antes de preparar.');const esc=(v:unknown)=>String(v).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]!));return'<!doctype html><html lang="pt"><meta charset="utf-8"><title>IRPC — preparação das retenções</title><body><h1>Preparação IRPC — L5</h1><p>Mapa de trabalho;sem submissão,recepção ou aceitação AT. MRFTA19/39:quadro1 retenção;quadro2 mês/ano único por declaração;quadro7 base/taxa/imposto. CER e correspondência das rubricas digitais/moeda electrónica por esclarecer;67(7)remete62(6),mas taxa nova em62(5). Não preencher assinatura ou uso dos serviços. Não consolidar períodos diferentes nem transformar retenções sofridas em imposto a entregar.</p>'+irpcReportRows(d).map(r=>'<section><h2>'+esc(r[1])+'</h2><p>'+esc(r[2])+'</p><small>'+esc(r[3])+'</small></section>').join('')+'<p>Instruções do exemplar:prazo nominal dia20 do mês seguinte à dedução,sem ajuste de calendário/prorrogação ou procedimento2026 presumidos. Juros não calculados. GuiaM/39 anterior preservada,sem actualizar remissões do original.</p></body></html>';}
+63
View File
@@ -0,0 +1,63 @@
import {acquisitionScope} from './iva-acquisitions.ts';
import {decimalFraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
export const ispcEligibilitySource='L4-A:Lei9/2025,BR248/1.ºsuplemento,republicaçãoISPC,arts2–5,9-A/13;PDF10–11/p2180(10–11);vigência2026art6/PDF9. Enquadramento preliminar de actividade habitual;opção separada;sem liquidação trimestral,retenção,submissão ou alteração de IVA/IRPC/IRPS.';
export const ispcActivities=[['forestry','Silvícola'],['fishery','Pesqueira'],['livestock','Pecuária'],['agriculture','Agrícola'],['poultry','Avícola'],['beekeeping','Apícola'],['industry','Industrial'],['commerce','Comercial'],['craft','Artesanato'],['services12','Serviços do artigo8(1)b'],['liberal15','Profissão liberal do artigo8(1)c'],['other','Outra actividade,fora dos âmbitos identificados']] as const;
export type IspcActivity=typeof ispcActivities[number][0];
type Choice=''|'yes'|'no';
export type IspcEligibilityInput={entityRef:string;personType:''|'singular'|'collective';origin:'projected'|'effective';assessmentDate:string;currency:string;mode:'regular'|'occasional';activities:IspcActivity[];activityDescription:string;territory:Choice;establishments:string;basis:''|'previous_year'|'start_forecast';referenceYear:string;annualReference:string;annualReferenceRef:string;forecastConfirmed:Choice;forecastConfirmationRef:string;organizedRequired:Choice;sharesInIspc:Choice;sharesAnonymous:Choice;otherActivities:Choice;unlistedServices:Choice;liberalDaysSameEntity:string;liberalClientRef:string;generalRegimeChosen:Choice;generalThreeYearsCompleted:Choice;generalRegimeRef:string;option:'preparation'|'opted'|'not_opted';optionReference:string;optionDate:string};
export type IspcEligibilityResult={calculatedAt:string;key:string;scope:string;input:IspcEligibilityInput;status:'compatible'|'incompatible'|'indeterminate';reason:string;missing:string[];annualReference:FiscalFraction|null;optionStatus:'preparation'|'recorded'|'not_opted'|'indeterminate';optionReason:string;source:string};
export type IspcEligibilityBook={version:1;input:IspcEligibilityInput;result?:IspcEligibilityResult;history?:IspcEligibilityResult[]};
const scope=(d:Record<string,unknown>)=>acquisitionScope(d);
export function ispcReuseValues(d:Record<string,unknown>):Partial<IspcEligibilityInput>{
const p:Partial<IspcEligibilityInput>={},person=String(d.person_type??'');if(['singular','sole_trader'].includes(person))p.personType='singular';else if(person==='collective')p.personType='collective';
if(typeof d.fiscal_activity==='string'&&d.fiscal_activity.trim())p.activityDescription=d.fiscal_activity;
const establishments=String(d.fiscal_establishments??'');if(/^[1-9]\d{0,4}$/.test(establishments))p.establishments=establishments;
const entity=String(d.fiscal_entity_ref||d.organization_name||'');if(entity.trim())p.entityRef=entity;
return p;
}
export function newIspcEligibilityInput(d:Record<string,unknown>):IspcEligibilityInput{return{entityRef:'',personType:'',origin:'projected',assessmentDate:'2026-01-01',currency:d.currency==='MZN'?'MZN':'',mode:'regular',activities:[],activityDescription:'',territory:'',establishments:'',basis:'',referenceYear:'',annualReference:'',annualReferenceRef:'',forecastConfirmed:'',forecastConfirmationRef:'',organizedRequired:'',sharesInIspc:'',sharesAnonymous:'',otherActivities:'',unlistedServices:'',liberalDaysSameEntity:'',liberalClientRef:'',generalRegimeChosen:'',generalThreeYearsCompleted:'',generalRegimeRef:'',option:'preparation',optionReference:'',optionDate:'',...ispcReuseValues(d)};}
function store(d:Record<string,unknown>):Record<string,unknown>{const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros não recuperáveis;originais preservados.');return s;}
function map(d:Record<string,unknown>):Record<string,IspcEligibilityBook>{const value=store(d).ispcEligibility;if(value===undefined)return{};if(!value||typeof value!=='object'||Array.isArray(value))throw Error('PreparaçãoISPC não recuperável;originais preservados.');return value as Record<string,IspcEligibilityBook>;}
function validate(b:IspcEligibilityBook):void{
const sample=newIspcEligibilityInput({});if(!b||b.version!==1||!b.input||typeof b.input!=='object'||Object.keys(sample).some(k=>k==='activities'?!Array.isArray(b.input.activities)||new Set(b.input.activities).size!==b.input.activities.length||b.input.activities.some(a=>!ispcActivities.some(([kind])=>kind===a)):typeof b.input[k as keyof IspcEligibilityInput]!=='string')||!['','singular','collective'].includes(b.input.personType)||!['projected','effective'].includes(b.input.origin)||!['regular','occasional'].includes(b.input.mode)||!['','previous_year','start_forecast'].includes(b.input.basis)||!['preparation','opted','not_opted'].includes(b.input.option)||['territory','forecastConfirmed','organizedRequired','sharesInIspc','sharesAnonymous','otherActivities','unlistedServices','generalRegimeChosen','generalThreeYearsCompleted'].some(k=>!['','yes','no'].includes(String(b.input[k as keyof IspcEligibilityInput])))||b.history!==undefined&&!Array.isArray(b.history)||b.result!==undefined&&(!b.result.input||!Array.isArray(b.result.missing)||!['compatible','incompatible','indeterminate'].includes(b.result.status)))throw Error('EntradasISPC não recuperáveis;sem substituir por valores vazios.');
}
export function ispcEligibilityBook(d:Record<string,unknown>):IspcEligibilityBook{const b=map(d)[scope(d)]??{version:1,input:newIspcEligibilityInput(d)};validate(b);return b;}
export function saveIspcEligibilityBook(d:Record<string,unknown>,b:IspcEligibilityBook):string{validate(b);return JSON.stringify({...store(d),ispcEligibility:{...map(d),[scope(d)]:b}});}
const validDate=(v:string)=>/^20\d{2}-(0[1-9]|1[0-2])-\d{2}$/.test(v)&&!Number.isNaN(Date.parse(v))&&new Date(v).toISOString().slice(0,10)===v;
function option(i:IspcEligibilityInput):Pick<IspcEligibilityResult,'optionStatus'|'optionReason'>{
if(i.option==='not_opted')return{optionStatus:'not_opted',optionReason:'Sem opçãoISPC declarada;não aplicar a exclusão de outros impostos doart5.'};
if(i.option==='preparation')return{optionStatus:'preparation',optionReason:'Opção em preparação;compatibilidade de acesso não é adesão nem alteração automática de regime.'};
if(!i.optionReference.trim()||!validDate(i.optionDate)||!validDate(i.assessmentDate)||i.optionDate>i.assessmentDate)return{optionStatus:'indeterminate',optionReason:'Identifique referência e data da opção,até à data de avaliação;não inferir adesão pela selecçãoISPC.'};
return{optionStatus:'recorded',optionReason:'Opção registada segundo documento ou pressuposto declarado;sem submissãoAT ou reescrita dos livros deIVA/IRPC/IRPS.'};
}
function assess(i:IspcEligibilityInput):Pick<IspcEligibilityResult,'status'|'reason'|'missing'|'annualReference'>{
let annual:FiscalFraction|null=null;try{annual=decimalFraction(i.annualReference);}catch{ /* Missing or invalid is never zero. */ }
const stop=(status:IspcEligibilityResult['status'],reason:string,missing:string[]=[])=>({status,reason,missing,annualReference:annual});
if(!validDate(i.assessmentDate)||!i.assessmentDate.startsWith('2026-')||i.currency!=='MZN')return stop('indeterminate','Este incremento cobre apenas avaliação2026emMZN;identifique data e moeda sem conversão silenciosa.',['data2026','moedaMZN']);
if(i.mode==='occasional')return stop('indeterminate','Operação ocasional3(3–4):conservar dados;use o percurso específico de operações ocasionais próprias abaixo,com incidênciaIRPS e famílias3(4).',['enquadramento específico da operação ocasional']);
if(i.territory==='no')return stop('incompatible','O âmbito territorial declarado não corresponde ao exercício em território nacional de2(1);nacionalidade do investidor não substitui este facto.');
if(i.activities.includes('other')||i.otherActivities==='yes')return stop('incompatible','Actividade fora dos âmbitos2/3declarada;exclusão3(2)c,não aplicarISPC por nome do sector.');
if(i.organizedRequired==='yes')return stop('incompatible','Obrigação de contabilidade organizada declarada:4(1)b não permite este enquadramento. Manter contabilidade voluntária distinto de obrigação.');
if(i.sharesInIspc==='yes'||i.sharesAnonymous==='yes')return stop('incompatible','Participações abrangidas por3(2)a/b declaradas;enquadramentoISPC incompatível.');
if(/^[1-9]\d{0,4}$/.test(i.establishments)&&Number(i.establishments)>1)return stop('incompatible','Actividade distribuída por vários estabelecimentos:exclusão3(2)d;sem presumir um estabelecimento por oportunidade.');
const service=i.activities.some(a=>['services12','liberal15'].includes(a)),liberal=i.activities.includes('liberal15');
if(service&&i.unlistedServices==='yes')return stop('incompatible','Serviços fora dos previstos declarados:exclusão3(2)f. Categoria e natureza próprias devem ser identificadas.');
if(liberal&&/^\d{1,3}$/.test(i.liberalDaysSameEntity)&&Number(i.liberalDaysSameEntity)<=366&&Number(i.liberalDaysSameEntity)>183)return stop('incompatible','Serviços8(1)càmesma entidade por mais183dias durante o ano:exclusão3(2)e. Não estender esta condição automaticamente aos serviços8(1)b.');
if(i.generalRegimeChosen==='yes'&&i.generalThreeYearsCompleted==='no')return stop('incompatible','Permanência mínima de três anos nos impostos gerais5(3)ainda não cumprida,segundo factos declarados.');
if(annual&&(i.basis==='previous_year'&&i.referenceYear==='2025'||i.basis==='start_forecast'&&i.referenceYear==='2026')&&BigInt(annual.numerator)>4000000n*BigInt(annual.denominator))return stop('incompatible','Volume anual de referência superior4.000.000MZN:fora do acesso4(1)a/4(2). Excesso do próprio ano e20%de8(1)d têm tratamento separado;não liquidado aqui.');
const missing:string[]=[];if(!i.personType)missing.push('pessoa singular ou colectiva');if(i.territory!=='yes')missing.push('exercício em território nacional');if(!i.activities.length||!i.activityDescription.trim())missing.push('actividade/natureza identificadas');if(!/^[1-9]\d{0,4}$/.test(i.establishments))missing.push('número de estabelecimentos');
for(const[field,label]of [['organizedRequired','obrigação de contabilidade organizada'],['sharesInIspc','participações noutras sociedadesISPC'],['sharesAnonymous','participaçõesSA/sócios não identificáveis'],['otherActivities','actividades fora do âmbito'],['generalRegimeChosen','opção pelos impostos gerais']] as const)if(i[field]==='')missing.push(label);
if(!i.basis)missing.push('origem do volume anual de referência');if(!annual)missing.push('montante anual de referência');const expected=i.basis==='previous_year'?'2025':i.basis==='start_forecast'?'2026':'';if(expected&&i.referenceYear!==expected)missing.push(`ano${expected}da referência;não reinterpretar outro ano`);
if(i.basis==='start_forecast'&&(i.forecastConfirmed!=='yes'||i.origin==='effective'&&!i.forecastConfirmationRef.trim()))missing.push('previsão da declaração de início confirmadaAT4(2),ou pressuposto expresso na projecção');
if(service&&i.unlistedServices==='')missing.push('correspondência dos serviços aos âmbitos daLei');
if(liberal&&(!/^\d{1,3}$/.test(i.liberalDaysSameEntity)||Number(i.liberalDaysSameEntity)>366||!i.liberalClientRef.trim()))missing.push('maior duração anual por mesma entidade e suporte declarado');
if(i.generalRegimeChosen==='yes'&&(i.generalThreeYearsCompleted!=='yes'||!i.generalRegimeRef.trim()))missing.push('cumprimento dos três anos5(3)e referência da opção/registo');
if(missing.length)return stop('indeterminate','Condições específicas por esclarecer;desconhecido não significa não aplicável nemzero.',missing);
return stop('compatible','Condições de acesso da actividade habitual compatíveis com os dados de referência declarados;opção separada. Volume do ano em curso, trimestre, excesso e mínimo têm apuramento trimestral próprio; retenções têm registo separado.'+(liberal?' Serviçosliberais:limite5anos9-A,contagemtransitória13a partir da vigência2026;sem presumir permanência fora da cobertura.':''));
}
const key=(d:Record<string,unknown>,b:IspcEligibilityBook)=>JSON.stringify(['ispc-eligibility/1',scope(d),b.input]);
export function ispcEligibilityCurrent(d:Record<string,unknown>,b:IspcEligibilityBook):boolean{return!!b.result&&b.result.key===key(d,b);}
export function recordIspcEligibility(d:Record<string,unknown>,b:IspcEligibilityBook,now=new Date().toISOString()):IspcEligibilityBook{validate(b);const result:IspcEligibilityResult={calculatedAt:now,key:key(d,b),scope:scope(d),input:structuredClone(b.input),...assess(b.input),...option(b.input),source:ispcEligibilitySource};return{...b,...(b.result?{history:[...(b.history??[]),structuredClone(b.result)]}:{}),result};}
export function ispcReuseDiff(d:Record<string,unknown>,b:IspcEligibilityBook):Array<{field:keyof IspcEligibilityInput;before:string;after:string}>{return Object.entries(ispcReuseValues(d)).filter(([field,value])=>b.input[field as keyof IspcEligibilityInput]!==value).map(([field,value])=>({field:field as keyof IspcEligibilityInput,before:String(b.input[field as keyof IspcEligibilityInput]),after:String(value)}));}
export function ispcEligibilityReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=ispcEligibilityBook(d),r=b.result;if(!r)return[];const i=r.input;return[['ISPC','L4-A — enquadramento2026',`${r.status==='compatible'?'Compatível com os dados de referência':r.status==='incompatible'?'Incompatível':'Indeterminado'};${r.reason};falta:${r.missing.join('; ')||'nenhum dado deste recorte'}`,`${r.scope};${ispcEligibilityCurrent(d,b)?'Entradas correspondentes':'Histórico preservado;rever entradas'};${r.calculatedAt};${r.source}`],['ISPC','Origem e âmbito',`${i.entityRef||'Entidade por identificar'};${i.personType};${i.origin==='projected'?'Pressupostos de simulação':'Dados efectivos declarados'};${i.activities.map(a=>ispcActivities.find(([kind])=>kind===a)?.[1]??a).join('; ')};${i.activityDescription};estabelecimentos${i.establishments};territórionacional${i.territory}`,`Referênciaanual:${i.basis}/${i.referenceYear};${r.annualReference?fractionPresentation(r.annualReference).decimal:'Indeterminado'}MZN;${i.annualReferenceRef};previsãoAT${i.forecastConfirmed}/${i.forecastConfirmationRef};liberal${i.liberalDaysSameEntity}dias/${i.liberalClientRef};factos:${JSON.stringify({organizedRequired:i.organizedRequired,sharesInIspc:i.sharesInIspc,sharesAnonymous:i.sharesAnonymous,otherActivities:i.otherActivities,unlistedServices:i.unlistedServices,generalRegimeChosen:i.generalRegimeChosen,generalThreeYearsCompleted:i.generalThreeYearsCompleted,generalRegimeRef:i.generalRegimeRef})}`],['ISPC','Opção e próximo passo',`${r.optionReason};referência${i.optionReference};data${i.optionDate}`,`Prossiga no apuramento trimestral; esta avaliação não adopta regime nem calcula imposto. ${r.source}`]];}catch(error){return[['ISPC','Enquadramento','Dados não recuperáveis;originais preservados',String(error)]];}}
+45
View File
@@ -0,0 +1,45 @@
import {acquisitionScope} from './iva-acquisitions.ts';
import {ispcEligibilityBook,ispcEligibilityCurrent,type IspcEligibilityResult} from './ispc-eligibility.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export const ispcQuarterSource='Lei 9/2025, republicação ISPC, arts 8, 9, 10, 10-A e 11; BR248/2025, PDF11/p2180(11). Taxa do escalão anual aplicada à base trimestral (8(1)a e 9); 20% apenas na parcela em excesso de 4.000.000; actividades cumuladas: taxa mais alta (8(2)). Sem fraccionar os limites anuais por quatro nem copiar o volume do ano anterior. Preparação do apuramento; sem submissão ou pagamento AT.';
export type IspcQuarterInput={year:string;quarter:string;sales:[string,string,string,string];salesRefs:[string,string,string,string];annualBandVolume:string;annualBandOrigin:''|'forecast'|'closed_year';annualBandRef:string;coverage:''|'all_taxpayer_activity';};
export type IspcQuarterResult={key:string;calculatedAt:string;scope:string;input:IspcQuarterInput;eligibility:IspcEligibilityResult|null;status:'calculated'|'indeterminate'|'not_applicable';reason:string;missing:string[];base:FiscalFraction|null;prior:FiscalFraction|null;ordinary:FiscalFraction|null;excess:FiscalFraction|null;rate:number|null;tax:FiscalFraction|null;payment:FiscalFraction|null;declaration:boolean;projected:boolean;source:string};
export type IspcQuarterBook={version:1;input:IspcQuarterInput;result?:IspcQuarterResult;history?:IspcQuarterResult[]};
export const newIspcQuarterInput=():IspcQuarterInput=>({year:'2026',quarter:'1',sales:['','','',''],salesRefs:['','','',''],annualBandVolume:'',annualBandOrigin:'',annualBandRef:'',coverage:''});
function snapshot(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros não recuperáveis; originais preservados.');return s;}
function validate(b:IspcQuarterBook){if(!b||b.version!==1||!b.input||['year','quarter','annualBandVolume','annualBandOrigin','annualBandRef','coverage'].some(k=>typeof b.input[k as keyof IspcQuarterInput]!=='string')||!['','forecast','closed_year'].includes(b.input.annualBandOrigin)||!['','all_taxpayer_activity'].includes(b.input.coverage)||!Array.isArray(b.input.sales)||b.input.sales.length!==4||b.input.sales.some(v=>typeof v!=='string')||!Array.isArray(b.input.salesRefs)||b.input.salesRefs.length!==4||b.input.salesRefs.some(v=>typeof v!=='string')||b.history!==undefined&&!Array.isArray(b.history)||b.result!==undefined&&(!b.result.input||!Array.isArray(b.result.missing)))throw Error('Apuramento ISPC não recuperável; sem substituir por zero ou apagar histórico.');}
function books(d:Record<string,unknown>):Record<string,IspcQuarterBook>{const v=snapshot(d).ispcQuarters;if(v===undefined)return{};if(!v||typeof v!=='object'||Array.isArray(v))throw Error('Mapa trimestral ISPC inválido; originais preservados.');return v;}
export function ispcQuarterBook(d:Record<string,unknown>):IspcQuarterBook{const b=books(d)[acquisitionScope(d)]??{version:1,input:newIspcQuarterInput()};validate(b);return b;}
export function saveIspcQuarterBook(d:Record<string,unknown>,b:IspcQuarterBook):string{validate(b);return JSON.stringify({...snapshot(d),ispcQuarters:{...books(d),[acquisitionScope(d)]:b}});}
const cmp=(a:FiscalFraction,b:FiscalFraction)=>BigInt(a.numerator)*BigInt(b.denominator)-BigInt(b.numerator)*BigInt(a.denominator);
const minimum=(a:FiscalFraction,b:FiscalFraction)=>cmp(a,b)<=0n?a:b;
const positive=(a:FiscalFraction)=>cmp(a,fraction(0n))>0n?a:fraction(0n);
const atRate=(v:FiscalFraction,r:number)=>fraction(BigInt(v.numerator)*BigInt(r),BigInt(v.denominator)*100n);
function eligibility(d:Record<string,unknown>){const b=ispcEligibilityBook(d);return ispcEligibilityCurrent(d,b)?b.result??null:null;}
const key=(d:Record<string,unknown>,b:IspcQuarterBook)=>JSON.stringify(['ispc-quarter/1',acquisitionScope(d),b.input,eligibility(d)]);
export const ispcQuarterCurrent=(d:Record<string,unknown>,b:IspcQuarterBook)=>!!b.result&&b.result.key===key(d,b);
export function recordIspcQuarter(d:Record<string,unknown>,b:IspcQuarterBook,now=new Date().toISOString()):IspcQuarterBook{
validate(b);const i=b.input,e=eligibility(d),r:IspcQuarterResult={key:key(d,b),calculatedAt:now,scope:acquisitionScope(d),input:structuredClone(i),eligibility:e?structuredClone(e):null,status:'indeterminate',reason:'',missing:[],base:null,prior:null,ordinary:null,excess:null,rate:null,tax:null,payment:null,declaration:false,projected:e?.input.origin==='projected'||i.annualBandOrigin==='forecast',source:ispcQuarterSource};
const finish=()=>({...b,...(b.result?{history:[...(b.history??[]),structuredClone(b.result)]}:{}),result:r});
if(!e){r.missing.push('Avaliação de elegibilidade actual correspondente às entradas');r.reason='Reveja e guarde o enquadramento; a avaliação anterior continua no histórico.';return finish();}
if(e.status==='incompatible'||e.optionStatus==='not_opted'){r.status='not_applicable';r.reason='Os factos guardados não permitem aplicar ISPC ou indicam que não optou. Outros regimes mantêm os seus percursos.';return finish();}
if(e.status!=='compatible'){r.missing.push(...e.missing);r.reason='Enquadramento indeterminado; não produzir imposto zero.';return finish();}
// A preparation scenario may estimate tax, but never asserts an effective election.
if(e.optionStatus==='indeterminate'||e.input.origin==='effective'&&e.optionStatus!=='recorded'){r.missing.push('Opção documentada para apuramento efectivo; a preparação permite somente simulação');}
if(e.optionStatus==='preparation')r.projected=true;
if(i.year!=='2026'||!['1','2','3','4'].includes(i.quarter))r.missing.push('Ano 2026 e trimestre entre 1 e 4');
if(i.coverage!=='all_taxpayer_activity')r.missing.push('Confirmar volume de todas as actividades do sujeito passivo, não apenas desta oportunidade');
const q=Number(i.quarter),amounts:FiscalFraction[]=[],allFour=i.annualBandOrigin==='closed_year'&&!e.input.activities.some(a=>['liberal15','services12'].includes(a));
if(e.input.origin==='effective'&&e.input.optionDate&&['1','2','3','4'].includes(i.quarter)&&e.input.optionDate>`2026-${['03-31','06-30','09-30','12-31'][q-1]}`)r.missing.push('A opção registada é posterior ao trimestre; esclarecer operações abrangidas sem retroagir automaticamente');
if(['1','2','3','4'].includes(i.quarter))for(let n=0;n<(allFour?4:q);n++){try{amounts[n]=decimalFraction(i.sales[n]);}catch{r.missing.push(`Volume do trimestre ${n+1}, incluindo zero expresso`);}if(!i.salesRefs[n].trim())r.missing.push(`Suporte ou pressuposto do trimestre ${n+1}`);}
const liberal=e.input.activities.includes('liberal15'),service=e.input.activities.includes('services12');
let band:FiscalFraction|null=null;
if(!liberal&&!service){try{band=decimalFraction(i.annualBandVolume);}catch{r.missing.push('Volume anual de 2026 para identificar o escalão; distinto do volume de acesso 2025');}if(!i.annualBandOrigin||!i.annualBandRef.trim())r.missing.push('Origem (previsão ou ano encerrado) e suporte do escalão anual');}
if(r.missing.length){r.reason='Faltam dados específicos para este apuramento; os restantes percursos mantêm-se disponíveis.';return finish();}
r.base=amounts[q-1];r.prior=addFractions(amounts.slice(0,q-1));const cumulative=addFractions(amounts.slice(0,q)),annualTotal=addFractions(amounts);
if(band&&(cmp(band,cumulative)<0n||i.annualBandOrigin==='closed_year'&&cmp(band,annualTotal)!==0n)){r.reason='Volume anual do escalão diverge dos trimestres declarados; reveja a divergência antes de calcular.';r.missing.push('Reconciliar referência anual 2026 com o acumulado trimestral');return finish();}
r.rate=liberal?15:service?12:band&&cmp(band,fraction(1000000n))<=0n?3:band&&cmp(band,fraction(2500000n))<=0n?4:5;
r.ordinary=minimum(r.base,positive(subtractFractions(fraction(4000000n),r.prior)));r.excess=subtractFractions(r.base,r.ordinary);r.tax=addFractions([atRate(r.ordinary,r.rate),atRate(r.excess,20)]);r.payment=cmp(r.tax,fraction(500n))<0n?fraction(0n):r.tax;r.declaration=true;r.status='calculated';r.reason=`${r.projected?'Simulação com pressupostos explícitos; sem adesão automática.':'Apuramento segundo factos e opção documentados.'} Taxa ${r.rate}% sobre a parcela ordinária trimestral e 20% apenas sobre o excesso anual. ${cmp(r.tax,fraction(500n))<0n?'Prestação inferior a 500 MZN: sem pagamento; obrigação declarativa preservada.':'Prestação igual ou superior a 500 MZN: montante a preparar para pagamento.'} Sem dedução de custos, retenções sofridas presumidas, compensação ou acumulação de prestações dispensadas.`;return finish();
}
const amount=(v:FiscalFraction|null)=>v?`${fractionPresentation(v).decimal} MZN (${v.numerator}/${v.denominator})`:'Indeterminado';
export function ispcQuarterReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=ispcQuarterBook(d),r=b.result;if(!r)return[];return[['ISPC',`Apuramento ${r.input.year}/T${r.input.quarter}`,`${r.status==='calculated'?'Calculado':r.status==='not_applicable'?'Não aplicável':'Indeterminado'}; ${r.reason}; falta: ${r.missing.join('; ')||'nenhum dado deste recorte'}`,`${r.scope}; ${ispcQuarterCurrent(d,b)?'Entradas correspondentes':'Histórico preservado; rever entradas'}; ${r.calculatedAt}; ${r.source}`],['ISPC','Base e taxa trimestral',`Base: ${amount(r.base)}; anterior no ano: ${amount(r.prior)}; ordinária: ${amount(r.ordinary)} a ${r.rate??'indeterminada'}%; excesso: ${amount(r.excess)} a 20%`,`Volume anual de escalão: ${r.input.annualBandVolume||'não necessário para taxa de serviços'}; ${r.input.annualBandOrigin}; ${r.input.annualBandRef}; suportes: ${r.input.salesRefs.join('; ')}`],['ISPC','Imposto, pagamento e declaração',`Imposto: ${amount(r.tax)}; prestação a pagar: ${amount(r.payment)}; obrigação declarativa: ${r.declaration?'mantida':'por determinar neste percurso'}; ${r.projected?'simulação':'factos efectivos'}`,`Opção: ${r.eligibility?.optionStatus??'indeterminada'}; referência: ${r.eligibility?.input.optionReference??''}; histórico: ${b.history?.length??0} versão(ões) anterior(es). Sem submissão AT.`]];}catch(error){return[['ISPC','Apuramento não recuperável',String(error),'Originais preservados.']];}}
+86
View File
@@ -0,0 +1,86 @@
import {acquisitionScope} from './iva-acquisitions.ts';
import {ispcEligibilityBook,ispcEligibilityCurrent} from './ispc-eligibility.ts';
import {ispcWithholdingBook} from './ispc-withholding.ts';
import {ispcQuarterBook,ispcQuarterCurrent} from './ispc-quarter.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,subtractFractions,type FiscalFraction} from './fiscal-rational.ts';
export type ResidualKind='occasional'|'acquisitions'|'formalities';
export type ResidualResult={key:string;scope:string;calculatedAt:string;status:'calculated'|'settled_by_withholding'|'partial'|'indeterminate'|'not_applicable';reason:string;missing:string[];input:Record<string,string>;amounts:Record<string,FiscalFraction|null>;details:Record<string,string>;source:string};
export type ResidualBook={version:1;kind:ResidualKind;input:Record<string,string>;result?:ResidualResult;history?:ResidualResult[]};
export const residualSources={occasional:'ISPC Lei9/2025 arts3(3–4),4,5,8,9,10-A,12(3);BR248 PDF10–11. IRPS republicação Lei19/2017,BR202/7.ºsuplemento,art8(3h,4),9;PDF4/p2602(128). Lei11/2025 não altera estes artigos. Operação imprevisível/não reiterada, pessoa singular sem actividade habitual e famílias restritas; imposto próprio distinto de retenção liberatória documentada.',acquisitions:'ISPC12(3–4):limite global anual2.500.000MZN para factura por conta/retencão5%. Parcela acima do limite não adquire taxa por ultrapassagem. IRPS57(1,2k,4),republicação19/2017 PDF13/p2602(137),e65(1)naLei11/2025 PDF17:acto isolado qualificado e sem opçãoISPC aplicável,20%sobre rendimento ilíquido declarado; não confundir com20%do excesso de vendasISPC8(1)d.',formalities:'AT Comunicado9/2026,06/10/2026,p1:ModeloB–Geral enquanto se ajusta sistema;pagamentos trimestrais emJaneiro/Abril/Julho/Outubro. AT ModeloBGeral2p:quadros1/2/3/5/6/8/10. Modelo30 disponível contém75.000/3%antigos,não usado para calcular2026. Sem submissãoAT automática.'};
const blank=(kind:ResidualKind):Record<string,string>=>kind==='occasional'?{personType:'',currency:'',origin:'projected',operationDate:'',quarter:'',noHabitual:'',territory:'',sporadic:'',activity:'',reference:'',amount:'',allQuarterOperations:'',priorYearTurnover:'',priorYearRef:'',organizedRequired:'',option:'preparation',optionRef:'',optionDate:'',settlement:'',annual2026:'',annualOrigin:'',annualRef:'',priorInYear:'',buyerIspc:'',unregistered:'',buyerAnnualPurchases:'',withheldActual:'',withheldRef:''}:kind==='acquisitions'?{route:'unknown',noIspcOnExcess:'',isolatedAct:'',incomeInMoz:'',grossExcess:'',grossRef:'',supplierOptionRef:'',reference:''}:{sourceKind:'quarter',name:'',nuit:'',fiscalArea:'',address:'',declaration:'initial',formMonth:'',formYear:'2026',formPeriodRef:'',interestSituation:'',interestAmount:'',interestRef:'',externalStatus:'preparation',externalRef:'',externalDate:''};
function store(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros não recuperáveis; originais preservados.');return s;}
function maps(d:Record<string,unknown>):Record<string,Record<string,ResidualBook>>{const v=store(d).ispcResiduals;if(v===undefined)return{};if(!v||typeof v!=='object'||Array.isArray(v))throw Error('Mapa residualISPC inválido; originais preservados.');return v;}
function validate(b:ResidualBook,kind:ResidualKind){
const enums:Record<string,string[]>=kind==='occasional'?{personType:['','singular','collective'],origin:['projected','effective'],noHabitual:['','yes','no'],territory:['','yes','no'],sporadic:['','yes','no'],activity:['','forestry','fishery','livestock','agriculture','poultry','beekeeping','other'],allQuarterOperations:['','yes','no'],organizedRequired:['','yes','no'],option:['preparation','opted','not_opted'],settlement:['','self','withheld'],annualOrigin:['','forecast','closed_year'],buyerIspc:['','yes','no'],unregistered:['','yes','no']}:kind==='acquisitions'?{route:['unknown','ispc_supplier','irps_isolated'],noIspcOnExcess:['','yes','no'],isolatedAct:['','yes','no'],incomeInMoz:['','yes','no']}:{sourceKind:['quarter','occasional','acquisitions'],declaration:['initial','substitution'],interestSituation:['','none','amount'],externalStatus:['preparation','submitted','received','paid']};
if(b?.input&&Object.entries(enums).some(([k,v])=>!v.includes(b.input[k])))throw Error('Opções residuais não recuperáveis;entradas preservadas.');
if(!b||b.version!==1||b.kind!==kind||!b.input||Object.keys(blank(kind)).some(k=>typeof b.input[k]!=='string')||b.history!==undefined&&!Array.isArray(b.history)||b.result!==undefined&&(!b.result.input||!b.result.amounts||!Array.isArray(b.result.missing)))throw Error('Livro residualISPC não recuperável; sem substituir por vazio.');}
export function ispcResidualBook(d:Record<string,unknown>,kind:ResidualKind):ResidualBook{const m=maps(d)[acquisitionScope(d)];if(m!==undefined&&(!m||typeof m!=='object'||Array.isArray(m)))throw Error('Contexto residual inválido.');let b=m?.[kind];if(!b){const input=blank(kind);if(kind==='occasional'){const i=ispcEligibilityBook(d).input;Object.assign(input,{personType:i.personType,currency:i.currency,origin:i.origin,operationDate:i.assessmentDate,territory:i.territory,option:i.option,optionRef:i.optionReference,optionDate:i.optionDate});}if(kind==='formalities'){if(ispcEligibilityBook(d).input.mode==='occasional'&&m?.occasional?.result)input.sourceKind='occasional';else if(!ispcQuarterBook(d).result&&m?.acquisitions?.result)input.sourceKind='acquisitions';Object.assign(input,{name:String(d.legal_name??d.organization_name??''),nuit:String(d.nuit??''),address:String(d.address??'')});}b={version:1,kind,input};}validate(b,kind);return b;}
export function saveIspcResidualBook(d:Record<string,unknown>,b:ResidualBook):string{validate(b,b.kind);const scope=acquisitionScope(d);return JSON.stringify({...store(d),ispcResiduals:{...maps(d),[scope]:{...maps(d)[scope],[b.kind]:b}}});}
const cmp=(a:FiscalFraction,b:FiscalFraction)=>BigInt(a.numerator)*BigInt(b.denominator)-BigInt(b.numerator)*BigInt(a.denominator);
const rate=(a:FiscalFraction,n:number)=>fraction(BigInt(a.numerator)*BigInt(n),BigInt(a.denominator)*100n);
const min=(a:FiscalFraction,b:FiscalFraction)=>cmp(a,b)<0n?a:b;
const positive=(a:FiscalFraction)=>cmp(a,fraction(0n))>0n?a:fraction(0n);
const validDate=(s:string)=>/^2026-\d{2}-\d{2}$/.test(s)&&!Number.isNaN(Date.parse(s))&&new Date(s).toISOString().slice(0,10)===s;
const amount=(s:string,label:string,r:ResidualResult)=>{try{return decimalFraction(s);}catch{r.missing.push(label);return null;}};
function dependency(d:Record<string,unknown>,kind:ResidualKind,i:Record<string,string>):unknown{if(kind==='acquisitions'){const e=ispcEligibilityBook(d);return[ispcWithholdingBook(d).input,e.input,e.result?.key];}if(kind==='formalities'){if(i.sourceKind==='quarter'){const b=ispcQuarterBook(d);return[b.input,b.result?.key,ispcQuarterCurrent(d,b)];}const b=ispcResidualBook(d,i.sourceKind==='occasional'?'occasional':'acquisitions');return[b.input,b.result?.key,b.result?.calculatedAt,ispcResidualCurrent(d,b)];}return null;}
const key=(d:Record<string,unknown>,b:ResidualBook)=>JSON.stringify(['ispc-residual/1',acquisitionScope(d),b.kind,b.input,dependency(d,b.kind,b.input)]);
export const ispcResidualCurrent=(d:Record<string,unknown>,b:ResidualBook)=>!!b.result&&b.result.key===key(d,b);
function occasional(i:Record<string,string>,r:ResidualResult){
if(i.personType==='collective'||i.noHabitual==='no'||i.territory==='no'||i.sporadic==='no'||i.activity==='other'){r.status='not_applicable';r.reason='Os factos excluem o recorte ocasional3(3–4); conserve o percurso habitual ou o imposto próprio aplicável, sem presumir isenção.';return;}
if(i.territory!=='yes')r.missing.push('Operação em território nacional,sem inferir da moeda ou nacionalidade');
if(!i.personType)r.missing.push('Pessoa singular por identificar');
if(i.currency!=='MZN'||!validDate(i.operationDate)||!['1','2','3','4'].includes(i.quarter)||validDate(i.operationDate)&&Math.ceil(Number(i.operationDate.slice(5,7))/3)!==Number(i.quarter))r.missing.push('Data/trimestre de2026 coerentes e moedaMZN');
if(i.noHabitual!=='yes'||i.sporadic!=='yes'||!['forestry','fishery','livestock','agriculture','poultry','beekeeping'].includes(i.activity)||!i.reference.trim())r.missing.push('Pessoa sem actividade habitual,acto imprevisível/não reiterado,família3(4)e suporte da operação');
const base=amount(i.amount,'Volume das operações ocasionais deste trimestre, incluindo zero expresso',r);r.amounts.base=base;
r.details.IRPS='Acto isolado8(3h)referente a8(2a),não previsível/reiterado8(4);família3(4)ISPC. Não se infere pelo nome do sector.';
if(i.settlement==='withheld'){
const purchases=amount(i.buyerAnnualPurchases,'Aquisições globais anuais do adquirente, incluindo estas operações',r),actual=amount(i.withheldActual,'Montante efectivamente retido',r);
if(i.buyerIspc!=='yes'||i.unregistered!=='yes'||!i.withheldRef.trim())r.missing.push('AdquirenteISPC,fornecedor não inscrito e documento de retenção liberatória12(3)');
if(purchases&&base&&(cmp(purchases,base)<0n||cmp(purchases,fraction(2500000n))>0n))r.missing.push('Reconciliar aquisições globais do adquirente dentro do limite2.500.000;fora dele usar tratamento próprio');
if(!r.missing.length&&base&&actual){r.amounts.tax=rate(base,5);r.amounts.withheld=actual;if(cmp(actual,r.amounts.tax)!==0n){r.missing.push('Retenção documentada diverge de5%da base;reconciliar diferença sem presumir quitação');return;}r.status='settled_by_withholding';r.details.rate='5';r.reason='Retenção liberatória documentada para estas operações; não somar nova liquidação própria3/4/5%nem usar a retenção como crédito duplicado. Pagamento próprio adicional não é gerado.';}return;
}
if(i.settlement!=='self'){r.missing.push('Via de liquidação própria ou retenção liberatória documentada');return;}
if(i.organizedRequired==='yes'){r.status='not_applicable';r.reason='Obrigação de contabilidade organizada declarada:fora da liquidação própriaISPC4(1b);entradas e documentos conservados,sem presumir isenção noutro imposto.';return;}
if(i.allQuarterOperations!=='yes')r.missing.push('Volume de todas as operações ocasionais do sujeito passivo no trimestre');
const access=amount(i.priorYearTurnover,'Volume de referência2025, sem inferir zero por ausência de actividade habitual',r);if(!i.priorYearRef.trim()||i.organizedRequired!=='no')r.missing.push('Suporte da referência anual e inexistência de obrigação de contabilidade organizada4(1)');if(access&&cmp(access,fraction(4000000n))>0n){r.status='not_applicable';r.reason='Volume de acesso4(1)superior4.000.000MZN declarado:fora da liquidação própriaISPC;sem atribuir taxa de outro regime por presunção.';return;}
if(i.option==='not_opted'){r.status='not_applicable';r.reason='Sem opçãoISPC para esta operação; não aplicar exclusãoIRPS5nem taxaISPC automaticamente.';return;}
if(!['preparation','opted'].includes(i.option)||i.option==='opted'&&(!i.optionRef.trim()||!validDate(i.optionDate)||i.optionDate>i.operationDate)||i.origin==='effective'&&i.option!=='opted')r.missing.push('Opção documentada aplicável à operação efectiva;preparação apenas permite cenário');
const annual=amount(i.annual2026,'Volume anual2026 para escalão, distinto do acesso2025',r),prior=amount(i.priorInYear,'Volume anterior no ano2026',r);if(!['forecast','closed_year'].includes(i.annualOrigin)||!i.annualRef.trim())r.missing.push('Referência anual suportada e previsão identificada como cenário');
if(base&&prior&&annual&&(cmp(annual,addFractions([base,prior]))<0n||i.annualOrigin==='closed_year'&&i.quarter==='4'&&cmp(annual,addFractions([base,prior]))!==0n))r.missing.push('Reconciliar volume anual com acumulado anterior e trimestre');
if(r.missing.length||!base||!prior||!annual)return;
const n=cmp(annual,fraction(1000000n))<=0n?3:cmp(annual,fraction(2500000n))<=0n?4:5,ordinary=min(base,positive(subtractFractions(fraction(4000000n),prior))),excess=subtractFractions(base,ordinary),tax=addFractions([rate(ordinary,n),rate(excess,20)]);r.amounts={...r.amounts,ordinary,excess,tax,payment:cmp(tax,fraction(500n))<0n?fraction(0n):tax};r.details.projected=i.origin==='projected'||i.option==='preparation'||i.annualOrigin==='forecast'?'yes':'no';r.details.rate=String(n);r.details.declaration='Mantida mesmo quando prestação inferior500MZN';r.status='calculated';r.reason=`${r.details.projected==='yes'?'Cenário declarado;sem adesão automática.':'Opção e factos efectivos declarados.'} Operações ocasionais próprias3(3–4),base trimestral9,taxa${n}%e20%somente no excesso de vendas acima4.000.000. Não há retenção presumida nem dedução de custos/IVA.`;
}
function acquisitions(d:Record<string,unknown>,i:Record<string,string>,r:ResidualResult){
const w=ispcWithholdingBook(d).input,e=ispcEligibilityBook(d);if(!ispcEligibilityCurrent(d,e)||e.result?.status!=='compatible'||e.result.optionStatus==='not_opted'||e.result.optionStatus==='indeterminate'||e.input.origin==='effective'&&e.result.optionStatus!=='recorded'){r.missing.push('Enquadramento/opção actual do adquirenteISPC');return;}
if(w.applicable!=='yes'||w.naturalOccasional!=='yes'||w.unregistered!=='yes'||w.related!=='yes'||!['forestry','fishery','livestock','agriculture','poultry','beekeeping'].includes(w.activity)||!w.reference.trim()){r.missing.push('Condições específicas12(3–4)e suporte no livro das aquisições');return;}
const base=amount(w.base,'Base das aquisições',r),prior=amount(w.priorAnnualPurchases,'Aquisições globais anteriores do ano',r);if(!base||!prior)return;const covered=min(base,positive(subtractFractions(fraction(2500000n),prior))),excess=subtractFractions(base,covered);r.amounts={base,prior,covered,excess,coveredTax:rate(covered,5),excessTax:null,total:null};r.details.quarter=w.quarter;r.details.acquisitionRef=w.reference;
if(cmp(excess,fraction(0n))<=0n){r.status='not_applicable';r.reason='Sem parcela acima do limite; o cálculo5%já disponível permanece no seu livro, sem segunda liquidação.';return;}
r.status='partial';r.reason='Parcela até ao limite separada a5%; parcela excedente quantificada, sem presumir5%ou20%pelo simples excesso. Montante total continua indeterminado até identificar tratamento próprio.';
if(i.route==='irps_isolated'){
const net=amount(i.grossExcess,'Rendimento ilíquido da parcela excedente, distinto de rendimento líquido e do preço líquido de IVA',r);if(i.noIspcOnExcess!=='yes'||i.isolatedAct!=='yes'||i.incomeInMoz!=='yes'||!i.grossRef.trim()||!i.reference.trim())r.missing.push('Acto isoladoIRPS8(3h,4),rendimento emMoçambique,sem opçãoISPC5aplicável à parcela,e referências da classificação/base');
if(net&&cmp(net,excess)!==0n)r.missing.push('Base ilíquida57(4)não coincide com a parcela bruta identificada;reconciliar sem deduzir custos/IVA automaticamente');
if(!r.missing.length&&net){r.amounts.excessTax=rate(net,20);r.amounts.total=addFractions([r.amounts.coveredTax!,r.amounts.excessTax]);r.status='calculated';r.reason='Correspondência positiva independente:IRPS57(2k)acto isolado,20%sobre rendimento ilíquido57(4)da parcela identificada,sem opçãoISPCaplicável. Não se usa taxa20%do excesso de vendasISPC. Retenções5%e20%separadas,não são crédito do imposto próprio do adquirente.';}
}else if(i.route==='ispc_supplier'){if(!i.supplierOptionRef.trim())r.missing.push('Referência da opção/registoISPCdo fornecedor aplicável a estas operações');r.reason='Fornecedor com opçãoISPC declarada:art5impede aplicarIRPSporpresunção. A parcela fora12(3)exige factura/registo do fornecedor e liquidação própria correspondente; o comprador não atribui5%ou20%automaticamente. Sem total de retenção presumido.';}
else r.missing.push('Enquadramento específico da parcela excedente:opçãoISPCdo fornecedor ou acto isoladoIRPS,base e suporte');
}
function formalities(d:Record<string,unknown>,i:Record<string,string>,r:ResidualResult){
let src:ResidualResult|undefined;if(i.sourceKind==='quarter'){const b=ispcQuarterBook(d),v=b.result;if(!v||!ispcQuarterCurrent(d,b)||v.status!=='calculated'){r.missing.push('Apuramento trimestral actual e calculado');return;}r.amounts={base:v.base,tax:v.tax,payment:v.payment,ordinary:v.ordinary,excess:v.excess};r.details={quarter:v.input.quarter,rate:String(v.rate),sourceDate:v.calculatedAt};}
else{const b=ispcResidualBook(d,i.sourceKind==='occasional'?'occasional':'acquisitions');src=b.result;if(!src||!ispcResidualCurrent(d,b)){r.missing.push('Resultado actual do percurso seleccionado');return;}if(src.status==='settled_by_withholding'){r.status='not_applicable';r.reason='Operação própria já com retenção liberatória documentada:conservar comprovativo,sem emitir liquidação própria duplicada.';return;}if(src.status!=='calculated'){r.missing.push('Cálculo completo do percurso seleccionado;as partes determinadas permanecem consultáveis');return;}r.amounts={...src.amounts,tax:src.amounts.total??src.amounts.tax,payment:src.amounts.total??src.amounts.payment};r.details={quarter:src.input.quarter||src.details.quarter,rate:src.details.rate||'retenções separadas',sourceDate:src.calculatedAt};}
const first=r.amounts.covered??r.amounts.ordinary??r.amounts.base,second=r.amounts.excess??fraction(0n),firstRate=i.sourceKind==='acquisitions'?5:Number(r.details.rate);
if(first&&[3,4,5,12,15].includes(firstRate)){const firstTax=r.amounts.coveredTax??rate(first,firstRate),secondTax=r.amounts.excessTax??rate(second,20);r.amounts.q8base01=first;r.amounts.q8tax05=firstTax;r.amounts.q8base02=second;r.amounts.q8tax06=secondTax;r.details.q8rate01=String(firstRate);r.details.q8rate02='20';if(r.amounts.tax&&cmp(addFractions([firstTax,secondTax]),r.amounts.tax)!==0n)r.missing.push('Parcelas do quadro8divergem do cálculo guardado;conferir apenas essa correspondência');}
if(i.sourceKind==='acquisitions'&&!(i.retentionFormRef??'').trim())r.missing.push('Modelo/código de entrega da retençãoISPC12(3)e da retençãoIRPS57(2k),distintos do imposto próprio;comunicado9não resolve isoladamente este modelo');
if(r.amounts.tax&&r.amounts.payment&&cmp(r.amounts.tax,fraction(0n))>0n&&cmp(r.amounts.tax,fraction(500n))<0n&&cmp(r.amounts.payment,fraction(0n))===0n)r.missing.push('Representação da dispensa de pagamento10-A noB–Geral:declarar imposto apurado sem presumir zero no campo de montante apurado');
r.details.model='Modelo B–Geral;comunicadoAT9/2026';r.details.paymentMonth=['Abril2026','Julho2026','Outubro2026','Janeiro2027'][Number(r.details.quarter)-1]||'Trimestre por identificar';r.details.formPeriod=i.formMonth?`${i.formMonth}/${i.formYear}`:'Indeterminado:quadro2pede mês/ano;comunicado identifica trimestre/mês de pagamento,sem resolver a codificação do período';
if(!/^[0-9]{9}$/.test(i.nuit)||!i.name.trim()||!i.fiscalArea.trim()||!i.address.trim())r.missing.push('NUIT9dígitos,nome,área fiscal/UGC e domicílio para formalização;preparação do cálculo não exige esses campos');
if(!/^(0[1-9]|1[0-2])$/.test(i.formMonth)||!['2026','2027'].includes(i.formYear)||!i.formPeriodRef.trim())r.missing.push('Mês/ano a inscrever no quadro2e instrução/correspondência utilizada; não preencher automaticamente com mês de pagamento');
if(!['none','amount'].includes(i.interestSituation)||!i.interestRef.trim())r.missing.push('Situação dos juros compensatórios e suporte;desconhecido não é zero');
if(i.interestSituation==='amount')r.amounts.interest=amount(i.interestAmount,'Juros documentados,não calculados por falta de taxa/período regulamentar',r);else if(i.interestSituation==='none')r.amounts.interest=fraction(0n);
r.amounts.finalPayment=r.amounts.payment&&r.amounts.interest?addFractions([r.amounts.payment,r.amounts.interest]):null;
if(i.externalStatus!=='preparation'&&(!i.externalRef.trim()||!i.externalDate.trim()))r.missing.push('Referência e data da submissão/recepção/pagamento declarado;sem confirmação automáticaAT');
r.status=r.missing.length?'partial':'calculated';r.reason='Preparação dos campos identificados do B–Geral,com cálculo e prestação separados. O Modelo30antigo não recebe taxas2026. Submissão,recepção e pagamento são actos externos;este registo conserva referências e histórico,sem os efectuar ou certificar.';
}
export function priorOccasionalSettlement(b:ResidualBook):ResidualResult|undefined{if(b.kind!=='occasional'||b.input.settlement!=='self')return;return[b.result,...(b.history??[])].find(r=>r?.status==='settled_by_withholding'&&r.input.reference.trim()===b.input.reference.trim()&&r.input.operationDate===b.input.operationDate&&r.input.quarter===b.input.quarter&&r.input.amount===b.input.amount);}
export function recordIspcResidual(d:Record<string,unknown>,b:ResidualBook,now=new Date().toISOString()):ResidualBook{validate(b,b.kind);const r:ResidualResult={key:key(d,b),scope:acquisitionScope(d),calculatedAt:now,status:'indeterminate',reason:'Dados específicos em falta;sem presumir zero.',missing:[],input:structuredClone(b.input),amounts:{},details:{},source:residualSources[b.kind]};if(b.kind==='occasional'){occasional(b.input,r);const prior=priorOccasionalSettlement(b);if(prior&&r.status==='calculated'){r.details.priorWithholdingRef=prior.input.withheldRef;r.details.priorWithholdingDate=prior.calculatedAt;if(b.input.withholdingCorrected==='yes'&&(b.input.withholdingCorrectionRef??'').trim()){r.details.withholdingCorrectionRef=b.input.withholdingCorrectionRef;r.reason+=' Correcção da retenção anterior declarada segundo referência externa,sem certificar esse acto;histórico preservado.';}else{r.status='partial';r.amounts.hypotheticalOwnTax=r.amounts.tax;r.amounts.tax=null;r.amounts.payment=null;r.amounts.withheld=prior.amounts.withheld??prior.amounts.tax;r.missing.push('Retenção liberatória anterior para a mesma operação;reconciliar eventual correcção documentada antes de nova prestação própria');r.reason='A via foi alterada,mas a retenção liberatória documentada permanece no histórico. Não é gerada segunda prestação;os dados da operação e as duas versões ficam preservados.';}}}else if(b.kind==='acquisitions')acquisitions(d,b.input,r);else formalities(d,b.input,r);return{...b,...(b.result?{history:[...(b.history??[]),structuredClone(b.result)]}:{}),result:r};}
const labels:Record<string,string>={base:'Base',prior:'Acumulado global anterior',ordinary:'Parcela ordinária',excess:'Parcela excedente',tax:'Imposto',payment:'Prestação própria',withheld:'Retenção documentada',hypotheticalOwnTax:'Cálculo próprio apenas hipotético,sem prestação gerada',covered:'Parcela abrangida pelo limite',coveredTax:'Retenção5%da parcela abrangida',excessTax:'RetençãoIRPS20%da parcela qualificada',total:'Total de retenções',interest:'Juros documentados',finalPayment:'Preparação do montante a entregar'};
export function ispcResidualReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{const rows:Array<[string,string,string,string]>=[];for(const kind of ['occasional','acquisitions','formalities']as const){try{const b=ispcResidualBook(d,kind),r=b.result;if(!r)continue;const title={occasional:'Operações ocasionais próprias',acquisitions:'Aquisições acima do limite',formalities:'Formalidades2026—B–Geral'}[kind];rows.push(['ISPC',title,`${({calculated:'Calculado',settled_by_withholding:'Retenção liberatória documentada',partial:'Parcial',indeterminate:'Indeterminado',not_applicable:'Não aplicável ao recorte'} as Record<string,string>)[r.status]};${r.reason};falta:${r.missing.join('; ')||'nenhum dado deste recorte'}`,`${ispcResidualCurrent(d,b)?'Entradas correspondentes':'Histórico preservado;rever entradas'};${r.calculatedAt};${r.source}`]);for(const[k,v]of Object.entries(r.amounts).filter(([k])=>!k.startsWith('q8')))rows.push(['ISPC',`${title}—${kind==='formalities'&&r.input.sourceKind==='acquisitions'&&k==='payment'?'Retenções a entregar pelo adquirente':labels[k]||k}`,v?`${fractionPresentation(v).decimal}MZN (${v.numerator}/${v.denominator})`:'Indeterminado',`${r.input.reference||r.details.acquisitionRef||r.input.externalRef||'Pressupostos/documentos declarados'};${r.scope}`]);}catch(e){rows.push(['ISPC','Residual não recuperável',String(e),'Originais preservados.']);}}return rows;}
export function ispcFormalPreparationHtml(d:Record<string,unknown>):string{const b=ispcResidualBook(d,'formalities'),r=b.result;if(!r||!ispcResidualCurrent(d,b)||!Object.keys(r.amounts).length)throw Error('Guarde primeiro preparação actual com cálculo identificado.');const esc=(v:unknown)=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]!));const v=(n:string)=>r.amounts[n]?fractionPresentation(r.amounts[n]!).decimal:'Indeterminado';const fields=[['Quadro1—tipo',b.input.declaration==='initial'?'Inicial':'Substituição'],['Quadro2—mês/ano',r.details.formPeriod],['Contexto—trimestre e mês de pagamento',`2026/T${r.details.quarter};${r.details.paymentMonth} (não copiado automaticamente para quadro2)`],['Quadro3—NUIT/ÁreaFiscal',`${b.input.nuit}/${b.input.fiscalArea}`],['Quadro5—nome',b.input.name],['Quadro6—domicílio',b.input.address],['Quadro8—linha1:base01/taxa/montante05',`${b.input.sourceKind==='acquisitions'?'ISPC—retenção12(3)':'ISPC—parcela ordinária'};base01:${v('q8base01')};taxa:${r.details.q8rate01}%;montante05:${v('q8tax05')}`],['Quadro8—linha2:base02/taxa/montante06',r.amounts.q8base02&&cmp(r.amounts.q8base02,fraction(0n))>0n?`${b.input.sourceKind==='acquisitions'?'IRPS—acto isolado57(2k)':'ISPC—excesso de vendas8(1)d'};base02:${v('q8base02')};taxa20%;montante06:${v('q8tax06')}`:'Não aplicável ao cálculo seleccionado;sem segunda parcela'],['Quadro8—subtotal1campo09',v('tax')],['Quadro10—montante/juros/importância',`Imposto calculado:${v('tax')};prestação legal:${v('payment')};juros:${v('interest')};totalpreparado:${v('finalPayment')}`],['Modelo/código das retenções',b.input.retentionFormRef||'Por corresponder se aplicável'],['Estado externo declarado',`${({preparation:'Em preparação',submitted:'Submetido segundo referência declarada',received:'Recebido segundo referência declarada',paid:'Pago segundo referência declarada'} as Record<string,string>)[b.input.externalStatus]};${b.input.externalRef};${b.input.externalDate}`],['Falta',r.missing.join('; ')||'Nenhum dado deste recorte']];return`<!doctype html><html lang="pt"><meta charset="utf-8"><title>PreparaçãoISPC—B–Geral</title><style>body{font:16px system-ui;margin:32px}td,th{border:1px solid #777;padding:10px;vertical-align:top}table{border-collapse:collapse;width:100%}</style><h1>Preparação de campos ISPC—Modelo B–Geral</h1><p>Correspondência de apoio; não é formulário oficial emitido, declaração submetida ou comprovativo de pagamento. Original e instrução AT preservados,sem os alterar.</p><table>${fields.map(([a,c])=>`<tr><th>${esc(a)}</th><td>${esc(c)}</td></tr>`).join('')}</table><p>${esc(r.source)}</p><p>Quadros8e10têm numeração própria;campos homónimos não são somados entre quadros. Não preencher área de serviços nem assinatura automaticamente.</p></html>`;}
+24
View File
@@ -0,0 +1,24 @@
import {ispcEligibilityBook,ispcEligibilityCurrent} from './ispc-eligibility.ts';
import {acquisitionScope} from './iva-acquisitions.ts';
import {addFractions,decimalFraction,fraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
export type IspcWithholdingInput={applicable:''|'no'|'yes';quarter:string;base:string;priorAnnualPurchases:string;naturalOccasional:''|'yes'|'no';unregistered:''|'yes'|'no';related:''|'yes'|'no';activity:''|'forestry'|'fishery'|'livestock'|'agriculture'|'poultry'|'beekeeping'|'other';reference:string;};
export type IspcWithholdingResult={input:IspcWithholdingInput;key:string;status:'calculated'|'indeterminate'|'not_applicable';reason:string;withheld:FiscalFraction|null;calculatedAt:string;source:string};
export type IspcWithholdingBook={version:1;input:IspcWithholdingInput;result?:IspcWithholdingResult;history?:IspcWithholdingResult[]};
export const ispcWithholdingSource='Lei9/2025,republicaçãoISPC,arts3(3–4),12(3–4);PDF10–11/p2180(10–11). Retenção liberatória5% sobre aquisição a pessoa singular ocasional não inscrita, ligada à actividade, até limite global anual2.500.000MZN; factura por conta do fornecedor e entrega trimestral em modelo próprio. Não é crédito contra o imposto próprio nem se aplica o mínimo500 desta prestação à retenção.';
const blank=():IspcWithholdingInput=>({applicable:'',quarter:'1',base:'',priorAnnualPurchases:'',naturalOccasional:'',unregistered:'',related:'',activity:'',reference:''});
function snapshot(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros não recuperáveis; originais preservados.');return s;}
function validate(b:IspcWithholdingBook){if(!b||b.version!==1||!b.input||Object.keys(blank()).some(k=>typeof b.input[k as keyof IspcWithholdingInput]!=='string')||['applicable','naturalOccasional','unregistered','related'].some(k=>!['','yes','no'].includes(b.input[k as keyof IspcWithholdingInput]))||!['','forestry','fishery','livestock','agriculture','poultry','beekeeping','other'].includes(b.input.activity)||b.history!==undefined&&!Array.isArray(b.history))throw Error('RetençõesISPC não recuperáveis; originais preservados.');}
function map(d:Record<string,unknown>):Record<string,IspcWithholdingBook>{const v=snapshot(d).ispcWithholdings;if(v===undefined)return{};if(!v||typeof v!=='object'||Array.isArray(v))throw Error('Mapa de retençõesISPC inválido.');return v;}
export function ispcWithholdingBook(d:Record<string,unknown>):IspcWithholdingBook{const b=map(d)[acquisitionScope(d)]??{version:1,input:blank()};validate(b);return b;}
export function saveIspcWithholdingBook(d:Record<string,unknown>,b:IspcWithholdingBook):string{validate(b);return JSON.stringify({...snapshot(d),ispcWithholdings:{...map(d),[acquisitionScope(d)]:b}});}
export function recordIspcWithholding(d:Record<string,unknown>,b:IspcWithholdingBook,now=new Date().toISOString()):IspcWithholdingBook{validate(b);const i=b.input,e=ispcEligibilityBook(d),r:IspcWithholdingResult={input:structuredClone(i),key:JSON.stringify([acquisitionScope(d),i]),status:'indeterminate',reason:'Identifique se existem aquisições abrangidas; não presumir retenção zero.',withheld:null,calculatedAt:now,source:ispcWithholdingSource};
if(i.applicable==='no'){r.status='not_applicable';r.reason='Sem aquisições abrangidas, segundo declaração expressa; entradas anteriores preservadas.';}
else if(i.applicable==='yes'&&(!ispcEligibilityCurrent(d,e)||e.result?.status!=='compatible'||e.result.optionStatus==='not_opted'||e.result.optionStatus==='indeterminate'||e.input.origin==='effective'&&e.result.optionStatus!=='recorded')){r.reason='Guarde o enquadramento e a opção aplicáveis do adquirenteISPC antes de calcular retenção efectiva; sem inferir adesão.';}
else if(i.applicable==='yes'){
if(i.naturalOccasional==='no'||i.unregistered==='no'||i.related==='no'||i.activity==='other'){r.status='not_applicable';r.reason='Aquisição fora do recorte12(3–4) declarado; outros regimes de retenção mantêm análise própria,sem presumir isenção.';}
else if(i.naturalOccasional==='yes'&&i.unregistered==='yes'&&i.related==='yes'&&i.activity&&i.reference.trim()&&['1','2','3','4'].includes(i.quarter)){
try{const base=decimalFraction(i.base),prior=decimalFraction(i.priorAnnualPurchases),total=addFractions([base,prior]);if(BigInt(total.numerator)>2500000n*BigInt(total.denominator))r.reason='Total global anual superior2.500.000MZN: tratamento da aquisição acima do limite por corresponder; não reter automaticamente5% nem truncar a base.';else{r.status='calculated';r.withheld=fraction(BigInt(base.numerator)*5n,BigInt(base.denominator)*100n);r.reason='Retenção5% calculada separadamente do imposto próprio; emitir factura por conta do fornecedor e preparar entrega trimestral em modelo próprio. Sem deduzir esta retenção da prestaçãoISPC.';}}catch{r.reason='Base e aquisições globais anteriores do ano necessários,incluindo zero expresso; não presumir montantes.';}
}else r.reason='Identifique pessoa singular ocasional3(3–4),actividade abrangida,não inscrição,ligação à actividade,trimestre e suporte; dados desconhecidos não viram não aplicáveis.';
}
return{...b,...(b.result?{history:[...(b.history??[]),structuredClone(b.result)]}:{}),result:r};}
export function ispcWithholdingReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=ispcWithholdingBook(d),r=b.result;if(!r)return[];return[['ISPC','Retenção em aquisições ocasionais',`${r.status}; ${r.withheld?fractionPresentation(r.withheld).decimal+' MZN':'Indeterminado/não aplicado'}; ${r.reason}`,`2026/T${r.input.quarter}; base:${r.input.base}; anteriores globais:${r.input.priorAnnualPurchases}; suporte:${r.input.reference}; ${r.key===JSON.stringify([acquisitionScope(d),b.input])?'Entradas correspondentes':'Histórico preservado;rever entradas'}; ${r.calculatedAt}; ${r.source}`]];}catch(e){return[['ISPC','Retenção não recuperável',String(e),'Originais preservados.']];}}
@@ -175,6 +175,9 @@ const rowSection: Record<string, DossierReportSectionId> = {
Orçamento: 'finance',
Tesouraria: 'finance',
'IVA mensal': 'finance',
ISPC: 'finance',
'IRPC — retenções': 'finance',
'IRPC normal — L6': 'finance',
Equipa: 'team',
'Necessidade de negócio': 'resources',
Financiamento: 'resources',
+12
View File
@@ -1,3 +1,9 @@
import {normalReportRows} from './irpc-normal.ts';
import {irpcReportRows} from './irpc-withholdings.ts';
import {ispcResidualReportRows} from './ispc-residuals.ts';
import {ispcWithholdingReportRows} from './ispc-withholding.ts';
import {ispcQuarterReportRows} from './ispc-quarter.ts';
import {ispcEligibilityReportRows} from './ispc-eligibility.ts';
import {fiscalCalculationGapReportRows} from './iva-calculation-gaps.ts';
import {l3FormPreparationReportRows} from './l3-form-preparation.ts';
import { remissionReportRows } from './iva-remission-imports.ts';
@@ -685,6 +691,12 @@ export function buildProjectDossierRows(
rows.push(...travelReportRows(draft));
rows.push(...travelEventReportRows(draft));
rows.push(...offerPreparationReportRows(draft));
rows.push(...ispcEligibilityReportRows(draft));
rows.push(...ispcQuarterReportRows(draft));
rows.push(...ispcWithholdingReportRows(draft));
rows.push(...ispcResidualReportRows(draft));
rows.push(...irpcReportRows(draft));
rows.push(...normalReportRows(draft));
rows.push(...fiscalCalculationGapReportRows(draft));
rows.push(...l3FormPreparationReportRows(draft));
const operationRows = salesReportRows(draft);
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcGroupedDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_grouped_irpc_rates_and_existing_fx_recover_with_originals_and_accepted_history():void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$d=json_decode(file_get_contents(base_path('tests/frontend/fixtures/irpc-grouped-preserved.json')),true,flags:JSON_THROW_ON_ERROR);$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');$this->assertSame($d['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);$s=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$b=$s['irpcWithholdings'][$d['context_opportunity']];
$foreign=$b['result']['rows'][2];$this->assertSame('calculated',$foreign['status']);$this->assertSame(20,$foreign['rate']);$this->assertSame(['numerator'=>'64000','denominator'=>'1'],$foreign['base']);$this->assertSame(['numerator'=>'12800','denominator'=>'1'],$foreign['tax']);$this->assertSame(['numerator'=>'7800','denominator'=>'1'],$foreign['outstanding']);$this->assertSame('1000',$foreign['conversion']['originalAmount']);$this->assertSame('USD',$foreign['conversion']['originalCurrency']);$this->assertSame('2026-10-20',$foreign['conversion']['date']);$this->assertSame('2026-10-02',$foreign['eventDate']);
$this->assertSame(10,$b['result']['rows'][3]['rate']);$this->assertSame('on_account',$b['result']['rows'][4]['nature']);$this->assertSame(['numerator'=>'10000','denominator'=>'1'],$b['result']['rows'][4]['tax']);$this->assertSame(['numerator'=>'640','denominator'=>'1'],$b['result']['rows'][5]['settled']);$this->assertSame(['numerator'=>'640','denominator'=>'1'],$b['result']['rows'][5]['outstanding']);$this->assertSame('10',$b['result']['paymentConversions']['p4']['originalAmount']);$this->assertSame('USD',$b['result']['payments'][3]['currency']);
$old=json_decode(file_get_contents(base_path('tests/frontend/fixtures/irpc-l5-preserved.json')),true,flags:JSON_THROW_ON_ERROR);$prior=json_decode($old['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);foreach($prior as$k=>$v){if(in_array($k,['irpcWithholdings','currencyEvents'],true))continue;$this->assertSame($v,$s[$k],$k);}
$oldBook=$prior['irpcWithholdings'][$d['context_opportunity']];$this->assertSame($oldBook['result'],$b['history'][array_key_last($b['history'])]);$this->assertSame($oldBook['rows'],array_slice($b['rows'],0,count($oldBook['rows'])));$this->assertSame($oldBook['payments'],array_slice($b['payments'],0,count($oldBook['payments'])));foreach(($prior['currencyEvents']??[])as$ctx=>$value){if($ctx!==$d['context_opportunity'])$this->assertSame($value,$s['currencyEvents'][$ctx]);}
if(is_dir(base_path('outputs/irpc-l5-grouped-20261025')))file_put_contents(base_path('outputs/irpc-l5-grouped-20261025/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
@@ -0,0 +1,45 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcInterestCerDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_documented_parameter_calculation_and_segmented_cases_recover_through_private_api(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);
$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$draft=json_decode(file_get_contents(base_path('outputs/irpc-interest-cer/calculated.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$draft['person_type']];unset($draft['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$draft],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);
$store=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);
$model=$store['irpcWithholdings'][$draft['context_opportunity']]['mrftaResult']['model'];
$this->assertSame('7300',$model['principal']['numerator']);
$this->assertSame('3650',$model['paid']['numerator']);
$this->assertSame('15',$model['interest']['numerator']);
$this->assertSame('3665',$model['total']['numerator']);
$this->assertSame('IRPC-interest/1',$model['automatic']['version']);
$this->assertSame('',$model['input']['interest']['mode']);
$this->assertSame('automatic',$model['input']['interest']['calculation']);
$this->assertSame('10',$model['automatic']['rule']['annualRate']);
$this->assertStringContainsString('fictício',$model['automatic']['rule']['rateSource']);
$segments=$model['automatic']['rows'][0]['segments'];
$this->assertCount(2,$segments);
$this->assertSame(5,$segments[0]['days']);
$this->assertSame('7300',$segments[0]['principal']['numerator']);
$this->assertSame('3650',$segments[1]['principal']['numerator']);
$this->assertSame('999',$model['lines'][0]['cer']);
file_put_contents(base_path('outputs/irpc-interest-cer/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcMrftaDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_mrfta_and_documented_interest_recover_from_private_api_without_losing_history(): void
{
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
$this->assertSame(55441, (int) $target->port);
config(['investor-path.enabled'=>true, 'suitecrm.enabled'=>false]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$draft = json_decode(file_get_contents(base_path('outputs/irpc-mrfta/calculated.json')), true, flags: JSON_THROW_ON_ERROR);
$personal = ['person_type'=>$draft['person_type']];
unset($draft['person_type']);
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot'=>$personal, 'economic_snapshot'=>$draft], ['Idempotency-Key'=>(string) Str::uuid()])->assertCreated()->json('data.id');
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
$store = json_decode($recovered['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
$book = $store['irpcWithholdings'][$draft['context_opportunity']];
$model = $book['mrftaResult']['model'];
$this->assertSame('2026-10', $model['period']);
$this->assertSame('20000', $model['principal']['numerator']);
$this->assertSame('3000', $model['paid']['numerator']);
$this->assertSame('500', $model['interest']['numerator']);
$this->assertSame('17500', $model['total']['numerator']);
$this->assertSame([], $model['pending']);
$this->assertSame('999', $model['lines'][0]['cer']);
$this->assertStringContainsString('fictício', $model['input']['codes'][0]['reference']);
$this->assertNotEmpty($book['history']);
file_put_contents(base_path('outputs/irpc-mrfta/recovered.json'), json_encode($recovered, JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
@@ -0,0 +1,34 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcNormalAssessmentDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_normal_colecta_and_missing_classification_recover_without_annual_settlement(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$id=null;$etag=null;
foreach(['calculated','missing'] as $case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l6-colecta/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);$p=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$p,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$p,'economic_snapshot'=>$d],['If-Match'=>$etag])->assertOk();
$r=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();$etag=$r->headers->get('ETag');$back=$r->json('data.economic_snapshot');
$this->assertSame($d['modelo_a_snapshot'],$back['modelo_a_snapshot']);$this->assertSame($d['business_plan_snapshot'],$back['business_plan_snapshot']);
$s=json_decode($back['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$b=$s['irpcNormal'][$d['context_opportunity']];$m=$b['result']['model'];
$this->assertSame('IRPC-normal-adjustments/4',$m['version']);$this->assertSame('6700',$m['taxableProfit']['numerator']);$this->assertSame('4400',$m['taxableBase']['numerator']);$this->assertNull($m['tax']);
$this->assertSame('2026',$m['assessment']['period']['year']);$this->assertSame('2026-01-01',$m['assessment']['period']['from']);$this->assertSame('2026-12-31',$m['assessment']['period']['to']);
$this->assertSame('L8',$m['assessment']['finalBalance']['scope']);$this->assertNull($m['assessment']['finalBalance']['payable']);$this->assertNull($m['assessment']['finalBalance']['recoverable']);
$this->assertSame('IRPC-normal-adjustments/3',$b['history'][2]['model']['version']);$this->assertArrayHasKey('irpcWithholdings',$s);
if($case==='calculated'){$this->assertSame('32',$m['assessment']['rate']['numerator']);$this->assertSame('1408',$m['colecta']['numerator']);$this->assertSame('general_61_1',$m['assessment']['input']['treatment']);}
else{$this->assertNull($m['colecta']);$this->assertNull($m['assessment']['rate']);$this->assertSame('',$m['assessment']['input']['treatment']);}
file_put_contents(base_path('outputs/irpc-l6-colecta/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcNormalBaseDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_taxable_base_and_missing_deduction_information_recover_without_consuming_loss_balances(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$id=null;$etag=null;
foreach(['calculated','missing'] as $case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l6-base/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);$p=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$p,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$p,'economic_snapshot'=>$d],['If-Match'=>$etag])->assertOk();
$r=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();$etag=$r->headers->get('ETag');$back=$r->json('data.economic_snapshot');
$this->assertSame($d['modelo_a_snapshot'],$back['modelo_a_snapshot']);$this->assertSame($d['business_plan_snapshot'],$back['business_plan_snapshot']);
$s=json_decode($back['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$b=$s['irpcNormal'][$d['context_opportunity']];$m=$b['result']['model'];
$this->assertSame('6700',$m['taxableProfit']['numerator']);$this->assertNull($m['tax']);$this->assertSame('IRPC-normal-adjustments/3',$m['version']);
$this->assertSame('2300',$m['base']['requestedLosses']['numerator']);$this->assertSame('2021',$m['base']['losses'][0]['year']);$this->assertSame(2026,$m['base']['losses'][0]['lastOrdinaryYear']);
$this->assertSame('800',$m['base']['losses'][0]['available']['numerator']);$this->assertSame('2500',$m['base']['losses'][1]['available']['numerator']);
$this->assertSame('200',$b['base']['losses'][0]['previouslyUsed']);$this->assertSame('500',$b['base']['losses'][1]['previouslyUsed']);
$this->assertArrayHasKey('irpcWithholdings',$s);$this->assertSame('IRPC-normal-adjustments/2',$b['history'][1]['model']['version']);
if($case==='calculated'){
$this->assertSame('4400',$m['taxableBase']['numerator']);$this->assertSame('2300',$m['base']['deductedLosses']['numerator']);$this->assertSame('1000',$m['base']['losses'][1]['remaining']['numerator']);
$this->assertSame('known',$m['base']['input']['benefits']['state']);$this->assertSame('0',$m['base']['input']['benefits']['amount']);
}else{$this->assertNull($m['taxableBase']);$this->assertNull($m['base']['deductedLosses']);$this->assertSame('',$m['base']['input']['benefits']['state']);}
file_put_contents(base_path('outputs/irpc-l6-base/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcNormalDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_partial_normal_irpc_adjustments_recover_without_overwriting_withholdings(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);
$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$draft=json_decode(file_get_contents(base_path('outputs/irpc-l6/calculated.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$draft['person_type']];unset($draft['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$draft],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);
$this->assertSame($draft['business_plan_snapshot'],$recovered['business_plan_snapshot']);
$store=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);
$book=$store['irpcNormal'][$draft['context_opportunity']];$model=$book['result']['model'];
$this->assertSame('6480',$model['accountingProfit']['numerator']);
$this->assertSame('120',$model['additions']['numerator']);
$this->assertSame('6600',$model['partialAdjustedResult']['numerator']);
$this->assertNull($model['taxableProfit']);
$this->assertNull($model['taxableBase']);
$this->assertNull($model['tax']);
$this->assertSame('projected',$model['origin']);
$this->assertSame('IRPC-normal-adjustments/1',$model['version']);
$this->assertSame('2026',$model['year']);
$this->assertCount(2,$model['rows']);
$this->assertSame('compensatory_interest',$model['rows'][1]['rule']);
$this->assertStringContainsString('L6 parcial',implode(' ',$model['pending']));
$this->assertArrayHasKey('irpcWithholdings',$store);
file_put_contents(base_path('outputs/irpc-l6/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
@@ -0,0 +1,48 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcNormalProfitDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_scoped_taxable_profit_and_missing_information_recover_with_all_prior_books(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);
$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$id=null;$etag=null;
foreach(['calculated','missing'] as $case){
$draft=json_decode(file_get_contents(base_path('outputs/irpc-l6-profit/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$draft['person_type']];unset($draft['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$draft],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$personal,'economic_snapshot'=>$draft],['If-Match'=>$etag])->assertOk();
$response=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();$etag=$response->headers->get('ETag');$recovered=$response->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);
$this->assertSame($draft['business_plan_snapshot'],$recovered['business_plan_snapshot']);
$store=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);
$book=$store['irpcNormal'][$draft['context_opportunity']];$m=$book['result']['model'];
$this->assertSame('6480',$m['accountingProfit']['numerator']);
$this->assertSame('220',$m['additions']['numerator']);
$this->assertNull($m['taxableBase']);$this->assertNull($m['tax']);
$this->assertSame('IRPC-normal-adjustments/2',$m['version']);
$this->assertSame('projected',$m['origin']);
$this->assertSame('absent',$m['profit']['input']['topics']['positivePatrimonial']['state']);
$this->assertCount(6,$m['profit']['lines']);
$this->assertSame('known',$m['profit']['input']['topics']['incomeCorrections']['state']);
$this->assertSame('0',$m['profit']['input']['topics']['incomeCorrections']['amount']);
$this->assertArrayHasKey('irpcWithholdings',$store);
$this->assertSame('IRPC-normal-adjustments/1',$book['history'][0]['model']['version']);
if($case==='calculated'){$this->assertSame('6700',$m['taxableProfit']['numerator']);$this->assertCount(0,$m['profit']['pending']);}
else{$this->assertNull($m['taxableProfit']);$this->assertSame('',$m['profit']['input']['topics']['negativePatrimonial']['state']);}
file_put_contents(base_path('outputs/irpc-l6-profit/recovered-'.$case.'.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
@@ -0,0 +1,35 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcNormalSchedulesDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_complementary_rules_recover_calculated_missing_and_current_loss_without_settlement(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$id=null;$etag=null;
foreach(['calculated','missing','loss','ep'] as $case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l6-sets/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);$p=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$p,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$p,'economic_snapshot'=>$d],['If-Match'=>$etag])->assertOk();
$r=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();$etag=$r->headers->get('ETag');$back=$r->json('data.economic_snapshot');
$this->assertSame($d['modelo_a_snapshot'],$back['modelo_a_snapshot']);$this->assertSame($d['business_plan_snapshot'],$back['business_plan_snapshot']);
$s=json_decode($back['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$b=$s['irpcNormal'][$d['context_opportunity']];$m=$b['result']['model'];
$this->assertSame('IRPC-normal-adjustments/5',$m['version']);$this->assertNull($m['tax']);
$this->assertSame('2026',$m['assessment']['period']['year']);$this->assertSame($case==='ep'?'2025-07-01':'2026-01-01',$m['assessment']['period']['from']);$this->assertSame($case==='ep'?'2026-06-30':'2026-12-31',$m['assessment']['period']['to']);
$this->assertSame('L8',$m['assessment']['finalBalance']['scope']);$this->assertNull($m['assessment']['finalBalance']['payable']);$this->assertNull($m['assessment']['finalBalance']['recoverable']);
$this->assertContains('IRPC-normal-adjustments/4',array_column(array_column($b['history'],'model'),'version'));$this->assertArrayHasKey('schedules',$m);$this->assertArrayHasKey('irpcWithholdings',$s);
if(in_array($case,['calculated','ep'],true)){$this->assertSame('6980',$m['taxableProfit']['numerator']);$this->assertSame('4680',$m['taxableBase']['numerator']);$this->assertSame(['numerator'=>'7488','denominator'=>'5'],$m['colecta']);$this->assertSame('120',$m['schedules']['interest']['numerator']);}
elseif($case==='missing'){$this->assertNull($m['taxableProfit']);$this->assertNull($m['colecta']);$this->assertNull($m['schedules']['interest']);$this->assertSame('520',$m['schedules']['net']['numerator']);}
else{$this->assertSame('3820',$m['currentLoss']['numerator']);$this->assertSame('0',$m['taxableBase']['numerator']);$this->assertSame('0',$m['colecta']['numerator']);$this->assertSame([],$b['base']['losses']);}
file_put_contents(base_path('outputs/irpc-l6-sets/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcReliefsDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_demonstrated_reliefs_and_insufficient_information_recover_through_private_api(): void
{
$target = DB::selectOne('select current_database() as name, inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
$this->assertSame(55441, (int) $target->port);
config(['investor-path.enabled'=>true, 'suitecrm.enabled'=>false]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$draft = json_decode(file_get_contents(base_path('outputs/irpc-reliefs/calculated.json')), true, flags: JSON_THROW_ON_ERROR);
$personal = ['person_type'=>$draft['person_type']];
unset($draft['person_type']);
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot'=>$personal, 'economic_snapshot'=>$draft], ['Idempotency-Key'=>(string) Str::uuid()])->assertCreated()->json('data.id');
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
$store = json_decode($recovered['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
$book = $store['irpcWithholdings'][$draft['context_opportunity']];
[$dispensed, $rent, $treaty, $missing] = array_slice($book['result']['rows'], -4);
$this->assertSame('dispensed', $dispensed['treatment']);
$this->assertSame(['numerator'=>'0','denominator'=>'1'], $dispensed['tax']);
$this->assertSame('dispensed', $rent['treatment']);
$this->assertSame('cirpc68f', $rent['reliefRule']);
$this->assertSame(['numerator'=>'0','denominator'=>'1'], $rent['tax']);
$this->assertSame('treaty', $treaty['treatment']);
$this->assertSame(10, $treaty['rate']);
$this->assertSame(['numerator'=>'10000','denominator'=>'1'], $treaty['tax']);
$this->assertSame('indeterminate', $missing['status']);
$this->assertNull($missing['tax']);
$this->assertSame('QA certificado fiscal Portugal 2026', $book['result']['inputs'][count($book['result']['inputs'])-2]['reliefPreparation']['residenceDocument']);
$this->assertNotEmpty($book['history']);
file_put_contents(base_path('outputs/irpc-reliefs/recovered.json'), json_encode($recovered, JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
@@ -0,0 +1,21 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IrpcWithholdingDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_irpc_recovers_private_retentions_payments_and_history_without_changing_installed_books():void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$d=json_decode(file_get_contents(base_path('tests/frontend/fixtures/irpc-l5-preserved.json')),true,flags:JSON_THROW_ON_ERROR);$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');$this->assertSame($d['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);
$s=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$key=$d['context_opportunity'];$b=$s['irpcWithholdings'][$key];$this->assertSame('calculated',$b['result']['rows'][0]['status']);$this->assertSame(['numerator'=>'10000','denominator'=>'1'],$b['result']['rows'][0]['tax']);$this->assertSame(['numerator'=>'6000','denominator'=>'1'],$b['result']['rows'][0]['settled']);$this->assertSame(['numerator'=>'4000','denominator'=>'1'],$b['result']['rows'][0]['outstanding']);$this->assertSame('2026-10',$b['result']['rows'][0]['period']);$this->assertSame('received',$b['result']['rows'][1]['direction']);$this->assertSame(['numerator'=>'2000','denominator'=>'1'],$b['result']['rows'][1]['tax']);$this->assertSame(['numerator'=>'500','denominator'=>'1'],$b['result']['rows'][1]['outstanding']);
$old=json_decode(file_get_contents(base_path('tests/frontend/fixtures/ispc-residual-preserved.json')),true,flags:JSON_THROW_ON_ERROR);foreach(json_decode($old['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR)as$k=>$v)$this->assertSame($v,$s[$k],$k.' must be preserved');
if(is_dir(base_path('outputs/irpc-l5-20261025')))file_put_contents(base_path('outputs/irpc-l5-20261025/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IspcQuarterDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_quarter_and_option_recover_privately_without_changing_accepted_fiscal_books(): void
{
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);$this->assertSame(55441,(int)$target->port);
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$actor=User::factory()->create(['email_verified_at'=>now()]);$this->actingAs($actor);
$draft=json_decode(file_get_contents(base_path('tests/frontend/fixtures/ispc-quarter-preserved.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>'collective'];unset($draft['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$draft],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');$this->assertSame($draft['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);
$s=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$r=$s['ispcQuarters']['opportunity:375']['result'];$this->assertSame('calculated',$r['status']);$this->assertSame(['numerator'=>'24000','denominator'=>'1'],$r['tax']);$this->assertSame($r['tax'],$r['payment']);$this->assertTrue($r['declaration']);$this->assertFalse($r['projected']);$this->assertSame('recorded',$r['eligibility']['optionStatus']);$this->assertSame('SYNTHETIC QA opção ISPC2026',$r['eligibility']['input']['optionReference']);$this->assertNotEmpty($s['ispcQuarters']['opportunity:375']['history']);
$seed=json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-l3e-preserved.json')),true,flags:JSON_THROW_ON_ERROR);foreach(json_decode($seed['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR)as$key=>$value)$this->assertSame($value,$s[$key]);
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));$this->getJson('/api/v1/simulation-drafts/'.$id)->assertNotFound();$this->actingAs($actor);$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();
if(is_dir(base_path('outputs/ispc-l4b-20261025')))file_put_contents(base_path('outputs/ispc-l4b-20261025/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class IspcResidualDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_new_residual_books_recover_without_rewriting_installed_habitual_or_L3_results():void
{
$t=DB::selectOne('select current_database() as name,inet_server_port() as port');$this->assertSame('simulator_fiscal_delta_20261021_test',$t->name);$this->assertSame(55441,(int)$t->port);config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
$d=json_decode(file_get_contents(base_path('tests/frontend/fixtures/ispc-residual-preserved.json')),true,flags:JSON_THROW_ON_ERROR);$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');$recovered=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');$this->assertSame($d['modelo_a_snapshot'],$recovered['modelo_a_snapshot']);$s=json_decode($recovered['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);
$own=$s['ispcResiduals']['opportunity:376']['occasional']['result'];$this->assertSame('calculated',$own['status']);$this->assertSame(['numerator'=>'3000','denominator'=>'1'],$own['amounts']['tax']);$this->assertSame('singular',$own['input']['personType']);
$a=$s['ispcResiduals']['opportunity:375']['acquisitions']['result'];$this->assertSame('calculated',$a['status']);$this->assertSame(['numerator'=>'5000','denominator'=>'1'],$a['amounts']['coveredTax']);$this->assertSame(['numerator'=>'20000','denominator'=>'1'],$a['amounts']['excessTax']);$this->assertSame(['numerator'=>'25000','denominator'=>'1'],$a['amounts']['total']);
$this->assertSame('partial',$s['ispcResiduals']['opportunity:375']['formalities']['result']['status']);$this->assertStringContainsString('Indeterminado',$s['ispcResiduals']['opportunity:375']['formalities']['result']['details']['formPeriod']);
$old=json_decode(file_get_contents(base_path('tests/frontend/fixtures/ispc-quarter-preserved.json')),true,flags:JSON_THROW_ON_ERROR);foreach(json_decode($old['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR)as$key=>$value){if($key==='ispcWithholdings')continue;if($key==='ispcEligibility'){foreach($value as$ctx=>$book)$this->assertSame($book,$s[$key][$ctx]);}else$this->assertSame($value,$s[$key]);}
if(is_dir(base_path('outputs/ispc-residuals-20261025')))file_put_contents(base_path('outputs/ispc-residuals-20261025/recovered.json'),json_encode($recovered,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+40
View File
@@ -0,0 +1,40 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {irpcBook,newIrpcRow,recordIrpc,saveIrpcBook,emptyIrpcOrdinaryFacts,irpcCurrent,irpcReportRows,irpcPreparationHtml} from '../../resources/js/lib/irpc-withholdings.ts';
import {convertIrpcAmount,irpcFxSources,updateIrpcFx} from '../../resources/js/lib/irpc-fx.ts';
import {emptyFxSelection,selectFx} from '../../resources/js/lib/iva-fx-selection.ts';
import {currencyEventBook,newCurrencyEvent,saveCurrencyEventBook} from '../../resources/js/lib/iva-currency-events.ts';
const accepted=JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-l5-preserved.json',import.meta.url),'utf8'));
const draft=()=>structuredClone(accepted);
const row=(id='normal')=>({...newIrpcRow(id),counterparty:'SYNTHETIC IRPC counterparty',documentRef:'SYNTHETIC-'+id,base:'100000',kind:'royalty',recipientIrpc:'yes',payerIrpc:'yes',residence:'nonresident',permanentEstablishment:'no',mozambique:'yes',qualificationRef:'SYNTHETIC classified non-digital income,IRPCpayer/recipient,Mozambique source;residence andEP explicitly recorded',specialRelief:'none',eventsComplete:'yes',events:[{kind:'cost',date:'2026-10-02',reference:'SYNTHETIC applicable cost'},{kind:'payment',date:'2026-11-02',reference:'SYNTHETIC payment'}],settlement:'none',settlementRef:'SYNTHETIC no remittance',ordinary:{...emptyIrpcOrdinaryFacts(),nonDigital:'yes',reference:'SYNTHETIC exact category facts;CIRPC62/67'}});
const book=(r=row())=>({version:1,rows:[r],payments:[]});
const calc=r=>recordIrpc(draft(),book(r)).result.rows[0];
const fx=(patch={})=>{const s={...emptyFxSelection(),nature:'commercial',submissionDate:'2026-10-20',bulletinDate:'2026-10-20',bulletinRef:'SYNTHETIC fictional BM bulletin for QA',source:'SYNTHETIC archived QA exemplar',issuer:'Banco de Moçambique',sourceCurrency:'USD',direction:'mzn_per_unit',mean:'64',...patch};return{...s,applied:selectFx(s)};};
test('ordinary nonresident royalties equipment services and nonlisted capitals use20%,not digital10%',()=>{for(const kind of ['royalty','equipment','services','capital']){const r=row();r.kind=kind;if(kind==='capital')r.ordinary.capitalType='unlisted_interest';const v=calc(r);assert.equal(v.status,'calculated');assert.equal(v.rate,20);assert.equal(v.tax.numerator,'20000');assert.equal(v.nature,'definitive');}});
test('resident royalties and ordinary rent are on account;predial nonresident is also on account',()=>{for(const patch of [{kind:'royalty',residence:'resident'},{kind:'rent',residence:'resident'},{kind:'rent',residence:'nonresident'}]){const r={...row(),...patch};r.ordinary.rentOwnPropertyManagement='no';const v=calc(r);assert.equal(v.status,'calculated');assert.equal(v.nature,'on_account');assert.equal(v.tax.numerator,'20000');assert.equal('annualCredit'in v,false);}});
test('identified dispensa branches and unknown facts block only their own income line',()=>{const d=draft(),rs=[{...row('resident-services'),residence:'resident',kind:'services'},{...row('property'),kind:'rent'},{...row('capital'),residence:'resident',kind:'capital',ordinary:{...row().ordinary,capitalType:'unlisted_interest'}},row('independent')];const out=recordIrpc(d,{version:1,rows:rs,payments:[]}).result.rows;assert.ok(out.slice(0,3).every(v=>v.status==='indeterminate'&&v.tax===null));assert.equal(out[3].tax.numerator,'20000');});
test('special categories62(4)a-c retain10% with exact facts,not generic20% or genericinstallation10%',()=>{for(const kind of ['telecom','international_transport','connected_installation','aircraft_maintenance_charter','rural_public_electrification','maritime_fishing_cabotage']){const r={...row(),kind};r.ordinary.specialFacts='yes';const v=calc(r);assert.equal(v.rate,10);assert.equal(v.tax.numerator,'10000');assert.match(v.reason,/62\(4\)/);}const unknown={...row(),kind:'connected_installation'};assert.equal(calc(unknown).tax,null);const generic={...row(),kind:'services'};assert.equal(calc(generic).rate,20);});
test('special62(4) entity condition is distinct from digital noEP/nonattributable branch',()=>{for(const patch of [{residence:'resident'},{permanentEstablishment:'yes',attributable:'no'}]){const r={...row(),kind:'telecom',...patch};r.ordinary.specialFacts='yes';assert.equal(calc(r).tax,null);}});
test('listed debt and other BMsecurities remain distinct;liquidity repos are not assumed',()=>{for(const[capitalType,rate]of [['listed_debt_mz',20],['listed_other_mz',10]]){const r={...row(),kind:'capital'};r.ordinary.capitalType=capitalType;r.ordinary.specialFacts='yes';assert.equal(calc(r).rate,rate);}const resident={...row(),kind:'capital',residence:'resident'};resident.ordinary.capitalType='listed_debt_mz';resident.ordinary.capitalSeatAndManagement='yes';assert.equal(calc(resident).rate,20);assert.equal(calc(resident).nature,'definitive');resident.ordinary.capitalType='liquidity_repo';assert.equal(calc(resident).rate,20);assert.equal(calc(resident).nature,'definitive');});
test('expired2025 agricultural measures do not extend into2026 foreign services/interest',()=>{for(const kind of ['services','capital']){const r={...row(),kind,description:'SYNTHETIC nationalagriculturalcompany / external agricultural financing'};r.ordinary.capitalType='unlisted_interest';const v=calc(r);assert.equal(v.rate,20);assert.match(v.reason,/31\/12\/2025/);}const r=row();r.events[0].date='2025-12-31';assert.equal(calc(r).tax,null);});
test('applied existing BMmean converts base, preserves original and keeps event/date separate',()=>{const r={...row(),currency:'USD',base:'1000',fxSelection:fx()};const v=calc(r);assert.equal(v.base.numerator,'64000');assert.equal(v.tax.numerator,'12800');assert.equal(v.period,'2026-10');assert.equal(v.eventDate,'2026-10-02');assert.equal(v.conversion.date,'2026-10-20');assert.equal(v.conversion.originalAmount,'1000');assert.equal(v.conversion.originalCurrency,'USD');assert.equal(r.base,'1000');assert.equal(r.currency,'USD');});
test('purchase/sale perspective,inverse quote and fiscalexception use deliveredselector',()=>{const opposite=fx({nature:'purchase',relation:'opposite',bulletinPerspective:'SYNTHETIC issuer',buy:'63',sell:'65'});let r={...row(),currency:'USD',base:'100',fxSelection:opposite};assert.equal(calc(r).base.numerator,'6500');const inverse=fx({direction:'units_per_mzn',mean:'0.02'});r.fxSelection=inverse;assert.equal(calc(r).base.numerator,'5000');r.fxSelection=fx({mode:'exception',exceptionRef:'SYNTHETIC identifiedfiscalprovision',exceptionScope:'SYNTHETIC retention scope',exceptionDate:'2026-10-02',exceptionRate:'66'});assert.equal(calc(r).base.numerator,'6600');assert.equal(calc(r).conversion.column,'exception');});
test('unapplied,stale,missingmean,wrongcurrency or undated FX remains indeterminate',()=>{const samples=[undefined,{...fx(),applied:undefined},{...fx(),mean:'65'},{...fx(),sourceCurrency:'EUR'},{...fx(),bulletinDate:'2026-10-19'}];for(const f of samples){const v=calc({...row(),currency:'USD',base:'1000',fxSelection:f});assert.equal(v.tax,null);assert.match(v.reason,/conversão/);}});
test('existing saved FX selections are linked,reused,and changed source marks only linked results stale',()=>{const d=draft(),cb=currencyEventBook(d),s=fx(),f={...newCurrencyEvent('shared-fx','MZN'),fxSelection:s,sourceCurrency:'USD',fxDirection:s.direction,fxRate:s.applied.rate,fxDate:s.applied.date,fxSource:s.applied.source,description:'SYNTHETIC existing FX'};d.modelo_a_snapshot=saveCurrencyEventBook(d,{...cb,rows:[...cb.rows,f]});const source=irpcFxSources(d).find(s=>s.id===f.id),r={...row(),currency:'USD',base:'1000',fxSelection:source.selection,fxLink:{id:source.id,fingerprint:source.fingerprint}},b=recordIrpc(d,book(r));d.modelo_a_snapshot=saveIrpcBook(d,b);assert.equal(irpcCurrent(d,b),true);const current=currencyEventBook(d);d.modelo_a_snapshot=saveCurrencyEventBook(d,{...current,rows:current.rows.map(v=>v.id===f.id?{...v,description:'SYNTHETIC revisedsource'}:v)});assert.equal(irpcCurrent(d,b),false);assert.match(recordIrpc(d,b).result.rows[0].reason,/origem alterada/);const m=recordIrpc(d,book(row('independentMZN')));assert.equal(m.result.rows[0].tax.numerator,'20000');});
test('foreign withholding proof converts available amount once;allocations remainMZN',()=>{const r={...row(),direction:'received',settlement:'complete',settlementRef:'SYNTHETIC provedpartialwithholding',allocations:[{paymentId:'p',amount:'640'}]},p={id:'p',kind:'withholding_proof',reference:'SYNTHETIC-USDproof',date:'2026-10-20',currency:'USD',amount:'10',fxSelection:fx()};const d=draft(),b=recordIrpc(d,{...book(r),payments:[p]});assert.equal(b.result.rows[0].settled.numerator,'640');assert.equal(b.result.rows[0].outstanding.numerator,'19360');assert.equal(b.result.paymentConversions.p.originalAmount,'10');d.modelo_a_snapshot=saveIrpcBook(d,b);assert.match(irpcReportRows(d)[0][3],/SYNTHETIC-USDproof/);assert.match(irpcReportRows(d)[0][3],/Original: 10 USD/);});
test('foreign payment to beneficiary or purported ATremittance is never converted into taxproof',()=>{for(const kind of ['beneficiary','remittance']){const r={...row(),settlement:'complete',allocations:[{paymentId:'p',amount:'640'}]},p={id:'p',kind,reference:'SYNTHETIC-wrongpayment',date:'2026-10-20',currency:'USD',amount:'10',fxSelection:fx()};assert.equal(recordIrpc(draft(),{...book(r),payments:[p]}).result.rows[0].status,'indeterminate');}});
test('converted shared proof cannot exceed availableMZN or change FX between contexts',()=>{const d=draft(),p={id:'p',kind:'withholding_proof',reference:'SYNTHETIC-sharedUSD',date:'2026-10-20',currency:'USD',amount:'10',fxSelection:fx()},r={...row('one'),direction:'received',settlement:'complete',allocations:[{paymentId:'p',amount:'400'}]};d.modelo_a_snapshot=saveIrpcBook(d,recordIrpc(d,{...book(r),payments:[p]}));d.context_opportunity='other';const other={...row('two'),direction:'received',settlement:'complete',allocations:[{paymentId:'p',amount:'300'}]};assert.equal(recordIrpc(d,{...book(other),payments:[p]}).result.rows[0].status,'indeterminate');other.allocations[0].amount='200';assert.equal(recordIrpc(d,{...book(other),payments:[p]}).result.rows[0].status,'calculated');assert.equal(recordIrpc(d,{...book(other),payments:[{...p,fxSelection:fx({mean:'65'})}]}).result.rows[0].status,'indeterminate');});
test('accepted v1MZN10% results remain current and bytepreserved without recomputation',()=>{const d=draft(),b=irpcBook(d),before=JSON.stringify(b);assert.equal(irpcCurrent(d,b),true);assert.equal(JSON.stringify(irpcBook(d)),before);assert.deepEqual(irpcBook({...d,modelo_a_snapshot:saveIrpcBook(d,b)}),b);});
test('new normal/FX result preserves old maps and acceptedresult in history,report frozen after change',()=>{const d=draft(),b=irpcBook(d),old=structuredClone(b.result),s=JSON.parse(d.modelo_a_snapshot);const next=recordIrpc(d,{...b,rows:[...b.rows,{...row('fx'),currency:'USD',base:'1000',fxSelection:fx()}]});d.modelo_a_snapshot=saveIrpcBook(d,next);for(const[k,v]of Object.entries(s))if(k!=='irpcWithholdings')assert.deepEqual(JSON.parse(d.modelo_a_snapshot)[k],v);assert.deepEqual(next.history.at(-1),old);next.rows.at(-1).fxSelection.mean='65';assert.equal(irpcCurrent(d,next),false);d.modelo_a_snapshot=saveIrpcBook(d,next);const report=irpcReportRows(d).at(-1);assert.match(report[2],/12800.00/);assert.match(report[3],/Histórico/);assert.match(report[3],/taxa: 64/);});
test('export keeps currencies,normal/special distinctions,payment refs and externalformalities separate',()=>{const d=draft(),r={...row(),currency:'USD',base:'1000',fxSelection:fx()};d.modelo_a_snapshot=saveIrpcBook(d,recordIrpc(d,book(r)));const h=irpcPreparationHtml(d);assert.match(h,/Original: 1000 USD/);assert.ok(!h.includes("selectionKey"));assert.match(h,/20%/);assert.match(h,/CER/);assert.match(h,/sem submissão/);assert.match(h,/2026-10/);});
if(process.env.IRPC_GROUPED_FIXTURE_OUTPUT){
const d=draft(),old=irpcBook(d),s=fx(),f={...newCurrencyEvent('retention-fx','MZN'),description:'SYNTHETIC existing BMselection for retention',fxSelection:s,sourceCurrency:'USD',fxDirection:s.direction,fxRate:s.applied.rate,fxDate:s.applied.date,fxSource:s.applied.source};const cb=currencyEventBook(d);d.modelo_a_snapshot=saveCurrencyEventBook(d,{...cb,rows:[...cb.rows,f]});const source=irpcFxSources(d).find(v=>v.id===f.id);
const foreign={...row('foreign-royalty'),currency:'USD',base:'1000',fxSelection:source.selection,fxLink:{id:source.id,fingerprint:source.fingerprint},settlement:'complete',settlementRef:'SYNTHETIC IRPC remittance5000',allocations:[{paymentId:'p3',amount:'5000'}]},special={...row('special-telecom'),kind:'telecom',ordinary:{...row().ordinary,specialFacts:'yes'}},resident={...row('resident-royalty'),residence:'resident',base:'50000'},received={...row('received-foreign-royalty'),direction:'received',currency:'USD',base:'100',fxSelection:s,settlement:'complete',settlementRef:'SYNTHETIC proof10USD converted640MZN',allocations:[{paymentId:'p4',amount:'640'}]};
const b=recordIrpc(d,{...old,rows:[...old.rows,foreign,special,resident,received],payments:[...old.payments,{id:'p3',kind:'remittance',reference:'SYNTHETIC-IRPC-AT5000',date:'2026-10-20',amount:'5000',currency:'MZN'},{id:'p4',kind:'withholding_proof',reference:'SYNTHETIC-IRPC-USD10',date:'2026-10-20',amount:'10',currency:'USD',fxSelection:s}]});d.modelo_a_snapshot=saveIrpcBook(d,b);fs.writeFileSync(process.env.IRPC_GROUPED_FIXTURE_OUTPUT,JSON.stringify(d,null,2)+'\n');
}
test("62(3) definitive capital needs exact seat/management facts and is not an annual credit",()=>{const r={...row(),residence:"resident",kind:"capital"};r.ordinary.capitalType="listed_debt_mz";assert.equal(calc(r).tax,null);r.ordinary.capitalSeatAndManagement="yes";assert.equal(calc(r).nature,"definitive");assert.equal(calc(r).rate,20);assert.equal("annualCredit"in calc(r),false);});
test('confirming unchanged FX preserves source link;deliberate input change detaches only that selection',()=>{const input={currency:'USD',fxSelection:fx(),fxLink:{id:'saved',fingerprint:'original'}};const confirmed={...input.fxSelection,applied:selectFx(input.fxSelection)};assert.deepEqual(updateIrpcFx(input,confirmed).fxLink,input.fxLink);assert.equal(updateIrpcFx(input,{...input.fxSelection,mean:'65'}).fxLink,undefined);assert.equal(input.fxSelection.mean,'64');assert.equal(input.fxLink.id,'saved');});
+63
View File
@@ -0,0 +1,63 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {newIrpcRow,emptyIrpcOrdinaryFacts,recordIrpc,saveIrpcBook,irpcBook,irpcCurrent,irpcReportRows} from '../../resources/js/lib/irpc-withholdings.ts';
import {newMrftaInput,recordMrfta,mrftaCurrent,mrftaHtml,prepareMrfta} from '../../resources/js/lib/irpc-mrfta.ts';
import {newIrpcInterestRule,calculateIrpcInterest} from '../../resources/js/lib/irpc-interest.ts';
import {mrftaCases,mrftaCaseHtml} from '../../resources/js/lib/irpc-mrfta-cases.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const draft=()=>JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-grouped-preserved.json',import.meta.url),'utf8'));
const rule=()=>({...newIrpcInterestRule(),annualRate:'10',rateSource:'QA parâmetro fictício; não é taxa fiscal2026',fiscalBasis:'QA fundamento sintético para ensaio aritmético',validFrom:'2026-01-01',validTo:'2026-12-31',dayBasis:'365',dayBasisRef:'QA fonte sintética da base365',rounding:'total_cent_half_up',roundingRef:'QA fonte sintética do arredondamento do total',retention:'withheld',occurrenceRef:'QA retenção e atraso documentados'});
const row=(id='one')=>({...newIrpcRow(id),counterparty:'QA contraparte',documentRef:'QA-'+id,base:'36500',kind:'royalty',recipientIrpc:'yes',payerIrpc:'yes',residence:'nonresident',permanentEstablishment:'no',mozambique:'yes',qualificationRef:'QA incidência e residência',specialRelief:'none',eventsComplete:'yes',events:[{kind:'cost',date:'2026-10-02',reference:'QA custo'}],settlement:'none',settlementRef:'QA sem entregas',ordinary:{...emptyIrpcOrdinaryFacts(),nonDigital:'yes',reference:'QA royalties não digitais'}});
const book=(payments=[])=>{const r=row();if(payments.length){r.settlement='complete';r.allocations=payments.map(p=>({paymentId:p.id,amount:p.amount}));}return recordIrpc(draft(),{version:1,rows:[r],payments});};
const payment=(amount,date='2026-11-25',id='p')=>({id,kind:'remittance',reference:'QA entrega-'+id,date,amount,currency:'MZN'});
const calc=(b=book(),r=rule(),due='2026-11-20',end='2026-11-30')=>calculateIrpcInterest(b,true,'2026-10',due,'QA prazo documentado',end,r);
const input=()=>({...newMrftaInput(),period:'2026-10',declaration:'initial',timing:'late',nuit:'999999999',name:'QA empresa',taxArea:'QA área fiscal',address:'QA domicílio',completeness:'yes',completenessRef:'QA reconciliação do período',otherRubrics:'none',otherRubricsRef:'QA outras rubricas não devidas',codes:[{rowId:'one',cer:'999',reference:'QA CER fictício, não oficial'}],interest:{...newMrftaInput().interest,mode:'',calculation:'automatic',period:'2026-10',date:'2026-11-30',dueDate:'2026-11-20',dueReference:'QA prazo documentado',reference:'QA ocorrência',automatic:rule()}});
test('daily interest uses documented parameters and explains principal,days and exact arithmetic',()=>{
const v=calc();assert.deepEqual(v.pending,[]);assert.equal(v.total.numerator,'20');assert.equal(v.rows[0].segments[0].from,'2026-11-21');assert.equal(v.rows[0].segments[0].to,'2026-11-30');assert.equal(v.rows[0].segments[0].days,10);assert.equal(v.rows[0].segments[0].principal.numerator,'7300');
});
test('partial remittance reduces principal after its payment day without duplicate daily interest',()=>{
const v=calc(book([payment('3650')]));assert.equal(v.total.numerator,'15');assert.deepEqual(v.rows[0].segments.map(s=>[s.days,s.principal.numerator]),[[5,'7300'],[5,'3650']]);
const sameDay=calc(book([payment('1825','2026-11-25','p1'),payment('1825','2026-11-25','p2')]));assert.equal(sameDay.total.numerator,'15');assert.equal(sameDay.rows[0].segments.length,2);
});
test('full payment stops charges and pre-deadline payment reduces the opening debt',()=>{
assert.equal(calc(book([payment('7300')])).total.numerator,'10');assert.equal(calc(book([payment('3650','2026-11-18')])).total.numerator,'10');
});
test('missing rate,reference,day basis or applicable version never becomes a default tax rate',()=>{
for(const patch of [{annualRate:''},{annualRate:'0'},{annualRate:'-1'},{rateSource:''},{fiscalBasis:''},{dayBasis:''},{dayBasisRef:''},{rounding:''},{roundingRef:''},{validTo:'2017-12-31'},{occurrenceRef:''}]){const v=calc(book(),{...rule(),...patch});assert.equal(v.total,null);assert.ok(v.pending.length);}
assert.equal(calculateIrpcInterest(book(),false,'2026-10','2026-11-20','QA prazo','2026-11-30',rule()).total,null);
});
test('on-account not-withheld cases remain separate;definitive not-withheld uses its own supported branch',()=>{
const r=row();r.residence='resident';const b=recordIrpc(draft(),{version:1,rows:[r],payments:[]});assert.equal(calc(b,{...rule(),retention:'not_withheld'}).total,null);assert.match(calc(b,{...rule(),retention:'not_withheld'}).pending.join(' '),/declaração anual/);assert.equal(calc(b).total.numerator,'20');assert.equal(calc(book(),{...rule(),retention:'not_withheld'}).total.numerator,'20');
});
test('documented actual-year basis splits year boundary including leap year without floating money',()=>{
const r={...rule(),validTo:'2028-12-31',dayBasis:'actual_year'},v=calc(book(),r,'2027-12-30','2028-01-02');assert.deepEqual(v.rows[0].segments.map(s=>[s.days,s.denominator]),[[1,365],[2,366]]);assert.deepEqual(v.total,{numerator:'599',denominator:'100'});
});
test('rounding is explicit,on total only,and matches the documented convention',()=>{
assert.deepEqual(calc(book(),{...rule(),annualRate:'10.0025'}).total,{numerator:'2001',denominator:'100'});assert.equal(calc(book(),{...rule(),annualRate:'10.0025',rounding:'total_cent_down'}).total.numerator,'20');
});
test('unreconciled payments and payments after liquidation keep the affected calculation indeterminate',()=>{
assert.equal(calc(book([payment('100','2026-12-01')])).total,null);const b=book();b.result.rows[0].settled=null;assert.equal(calc(b).total,null);
});
test('distinct rates and CER produce stable working cases,not invented declarations or merged rates',()=>{
const b={...book(),mrfta:input()};const second={...b.result.rows[0],id:'two',rate:10};b.result.rows.push(second);b.result.inputs.push(row('two'));b.mrfta.codes.push({rowId:'two',cer:'998',reference:'QA second fictionalCER'});const m=prepareMrfta(b,true),cases=mrftaCases(m);assert.equal(cases.length,2);assert.notEqual(cases[0].key,cases[1].key);assert.deepEqual(cases.map(c=>[c.rate,c.cer]),[[20,'999'],[10,'998']]);assert.equal(m.total,null);const html=mrftaCaseHtml(m,cases[0].key);assert.match(html,/Não é uma declaração autónoma/);assert.ok(html.includes('Pendências do período'));assert.deepEqual(mrftaCases({...m,lines:[...m.lines].reverse()}).map(c=>c.key).sort(),cases.map(c=>c.key).sort());
});
test('missing CER references remain visible within each case sheet without presumed correspondence',()=>{
const b={...book(),mrfta:input()};b.mrfta.codes[0].reference='';const m=prepareMrfta(b,true);assert.match(mrftaCases(m)[0].pending,/referência por corresponder/);b.mrfta.codes=[];assert.match(mrftaCases(prepareMrfta(b,true))[0].pending,/sem preenchimento presumido/);
});
test('automatic result persists,recovers and reaches dossier with traceable parameters and history',()=>{
const d=draft(),b=recordMrfta({...book([payment('3650')]),mrfta:input()},true);d.modelo_a_snapshot=saveIrpcBook(d,b);const recovered=JSON.parse(JSON.stringify(d)),saved=irpcBook(recovered);assert.equal(irpcCurrent(recovered,saved),true);assert.equal(mrftaCurrent(saved,true),true);assert.equal(saved.mrftaResult.model.interest.numerator,'15');assert.equal(saved.mrftaResult.model.total.numerator,'3665');assert.equal(saved.mrftaResult.model.automatic.rows[0].segments.length,2);
const report=JSON.stringify(irpcReportRows(recovered));assert.match(report,/Taxa anual:10%/);assert.match(report,/QA parâmetro fictício/);assert.match(report,/5dias\/365/);assert.match(report,/metade por excesso/);assert.ok(!report.includes('total_cent_half_up'));assert.match(JSON.stringify(createProjectDossierReport(recovered,{selectedSections:new Set(['finance'])})),/3665/);assert.match(mrftaHtml(saved,true),/Juros calculados por parâmetros documentados/);assert.match(mrftaHtml(saved,true),/simulação pelos pressupostos introduzidos, sem confirmação fiscal/);assert.match(mrftaHtml(saved,true),/Códigos provisórios ou de simulação não são correspondências oficiais/);assert.match(report,/sem validação por catálogo oficial/);assert.match(mrftaCases(saved.mrftaResult.model)[0].pending,/Código provisório ou de simulação não é correspondência oficial/);
saved.mrfta.interest.automatic.annualRate='';assert.equal(mrftaCurrent(saved,true),false);const changed=recordMrfta(saved,true);assert.equal(changed.mrftaResult.model.interest,null);assert.deepEqual(changed.mrftaHistory.at(-1),b.mrftaResult);
fs.mkdirSync('outputs/irpc-interest-cer',{recursive:true});fs.writeFileSync('outputs/irpc-interest-cer/calculated.json',JSON.stringify(recovered));fs.writeFileSync('outputs/irpc-interest-cer/preparation.html',mrftaHtml(b,true));
});
test('new parameters reject malformed persisted values while the installed snapshot remains current',()=>{
const d=JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-mrfta-preserved.json',import.meta.url),'utf8'));const b=irpcBook(d);assert.equal(irpcCurrent(d,b),true);assert.equal(mrftaCurrent(b,true),true);const invalid={...book(),mrfta:input()};invalid.mrfta.interest.automatic.annualRate=10;assert.throws(()=>saveIrpcBook(draft(),invalid));
});
test('two calculated incomes with different treaty/internal rates remain separate without an invented declaration total',()=>{
const d=draft(),first={...row(),settlement:'complete',allocations:[{paymentId:'p',amount:'3650'}]},second={...row('two'),specialRelief:'claimed',reliefPreparation:{kind:'treaty',rule:'ptMz12',instrument:'QA CDT PT-MZ e Protocolo',article:'12',country:'PT',residenceDocument:'QA certificado Portugal2026',validFrom:'2026-01-01',validTo:'2026-12-31',conditions:'QA royalties qualificadas semEP',evidence:'QA contrato e residência',facts:{treatyResident:'yes',beneficialOwner:'yes',payerResidentMz:'yes',armLength:'yes',royaltyDefinition:'yes'}}};
const b=recordMrfta({...recordIrpc(d,{version:1,rows:[first,second],payments:[payment('3650')]}),mrfta:{...input(),codes:[...input().codes,{rowId:'two',cer:'998',reference:'QA CER998 fictício, não oficial'}]}},true);const m=b.mrftaResult.model;
assert.deepEqual(b.result.rows.map(r=>r.rate),[20,10]);assert.equal(m.interest.numerator,'25');assert.equal(m.total,null);assert.deepEqual(mrftaCases(m).map(c=>[c.rate,c.cer]),[[20,'999'],[10,'998']]);assert.match(m.pending.join(' '),/taxas ou CER distintos/);
d.modelo_a_snapshot=saveIrpcBook(d,b);fs.writeFileSync('outputs/irpc-interest-cer/mixed.json',JSON.stringify(d));
});
+54
View File
@@ -0,0 +1,54 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {newIrpcRow,emptyIrpcOrdinaryFacts,recordIrpc,saveIrpcBook,irpcBook,irpcCurrent,irpcReportRows} from '../../resources/js/lib/irpc-withholdings.ts';
import {newMrftaInput,prepareMrfta,recordMrfta,mrftaCurrent,mrftaHtml} from '../../resources/js/lib/irpc-mrfta.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const draft=()=>JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-grouped-preserved.json',import.meta.url),'utf8'));
const row=(id='principal')=>({...newIrpcRow(id),counterparty:'QA contraparte',documentRef:'QA-'+id,base:'100000',kind:'royalty',recipientIrpc:'yes',payerIrpc:'yes',residence:'nonresident',permanentEstablishment:'no',mozambique:'yes',qualificationRef:'QA contrato e residência',specialRelief:'none',eventsComplete:'yes',events:[{kind:'cost',date:'2026-10-02',reference:'QA custo'}],settlement:'complete',settlementRef:'QA reconciliação',allocations:[{paymentId:'p',amount:'3000'}],ordinary:{...emptyIrpcOrdinaryFacts(),nonDigital:'yes',reference:'QA royalties não digitais'}});
const input=()=>({...newMrftaInput(),period:'2026-10',declaration:'initial',timing:'late',nuit:'999999999',name:'QA sujeito passivo',commercialName:'QA',taxArea:'QA área fiscal',address:'QA domicílio',contact:'qa@example.invalid',completeness:'yes',completenessRef:'QA conferência do período e livros',otherRubrics:'none',otherRubricsRef:'QA ausência documentada de IRPS/tributação autónoma/outros valores',codes:[{rowId:'principal',cer:'999',reference:'QA CER fictício, apenas teste'}],interest:{...newMrftaInput().interest,mode:'assessment',period:'2026-10',amount:'500',date:'2026-11-25',reference:'QA liquidação de juros compensatórios'}});
function book(rows=[row()]){return {...recordIrpc(draft(),{version:1,rows,payments:[{id:'p',kind:'remittance',reference:'QA entrega IRPC',date:'2026-11-15',amount:'3000',currency:'MZN'}]}),mrfta:input()};}
test('MRFTA fills one period with principal, documented interest, payment and balance separately',()=>{
const b=book(),m=prepareMrfta(b,true);assert.deepEqual(m.pending,[]);assert.equal(m.principal.numerator,'20000');assert.equal(m.paid.numerator,'3000');assert.equal(m.interest.numerator,'500');assert.equal(m.total.numerator,'17500');assert.equal(m.lines[0].rate,20);assert.equal(m.lines[0].cer,'999');assert.match(m.interestReason,/transcritos/);
});
test('unknown MAIBOR2026 never becomes zero or MIMO; independent principal remains calculated',()=>{
const b=book();b.mrfta.interest.mode='';const m=prepareMrfta(b,true);assert.equal(m.interest,null);assert.equal(m.total,null);assert.equal(m.principal.numerator,'20000');assert.equal(b.result.rows[0].status,'calculated');assert.match(m.pending.join(' '),/MAIBOR2026/);
});
test('insufficient CER or contradictory rate per rubric blocks total without losing rows',()=>{
const b=book();b.mrfta.codes=[];let m=prepareMrfta(b,true);assert.equal(m.total,null);assert.equal(m.lines.length,1);assert.match(m.pending.join(' '),/CER/);
const other=structuredClone(b.result.rows[0]);other.id='other';other.rate=10;other.tax={numerator:'10000',denominator:'1'};b.result.rows.push(other);b.result.inputs.push({...row('other'),allocations:[]});b.mrfta.codes=[{rowId:'principal',cer:'999',reference:'QA ref'},{rowId:'other',cer:'999',reference:'QA ref'}];m=prepareMrfta(b,true);assert.equal(m.lines.length,2);assert.match(m.pending.join(' '),/taxas ou CER distintos/);assert.equal(m.total,null);
});
test('other months,suffered withholdings and documented dispensas stay outside payable rows',()=>{
const b=book();for(const[id,patch,original]of [['other-month',{period:'2026-11'},{}],['suffered',{}, {direction:'received'}],['dispensed',{treatment:'dispensed',tax:{numerator:'0',denominator:'1'}},{}]]){b.result.rows.push({...b.result.rows[0],id,...patch});b.result.inputs.push({...row(id),...original});}
const m=prepareMrfta(b,true);assert.equal(m.lines.length,1);assert.equal(m.excluded.length,3);assert.equal(m.principal.numerator,'20000');assert.equal(m.total.numerator,'17500');
});
test('unsupported digital and indeterminate cases retain explicit gaps without guessed rubric',()=>{
const b=book();b.result.inputs[0].kind='digital_services';let m=prepareMrfta(b,true);assert.equal(m.lines.length,0);assert.equal(m.total,null);assert.match(m.pending.join(' '),/digital/);b.result.inputs[0].kind='royalty';b.result.rows[0].status='indeterminate';b.result.rows[0].tax=null;m=prepareMrfta(b,true);assert.equal(m.total,null);assert.match(m.pending.join(' '),/indeterminado/);
});
test('timely remittance only yields zero interest with complete proof and explicit applicable deadline',()=>{
const r=row();r.base='15000';const b=book([r]);b.mrfta.interest={...b.mrfta.interest,mode:'timely',period:'2026-10',dueDate:'2026-11-20',dueReference:'QA prazo documentado e calendário'};assert.equal(prepareMrfta(b,true).interest.numerator,'0');assert.equal(prepareMrfta(b,true).total.numerator,'0');
b.mrfta.interest.dueDate='2026-11-10';assert.equal(prepareMrfta(b,true).interest,null);b.mrfta.interest.dueDate='2026-11-20';b.result.rows[0].settled=null;assert.equal(prepareMrfta(b,true).interest,null);
});
test('assessment cannot leak into another period or accept negative amount and missing reference',()=>{
const b=book();for(const patch of [{period:'2026-11'},{amount:'-10'},{reference:''},{date:'2026-02-30'}]){const copy=structuredClone(b);Object.assign(copy.mrfta.interest,patch);assert.equal(prepareMrfta(copy,true).interest,null);assert.equal(prepareMrfta(copy,true).total,null);}
});
test('MRFTA save,recover,history and dossier preserve existing tax maps and freeze evidence',()=>{
const d=draft(),prior=irpcBook(d),original=JSON.parse(d.modelo_a_snapshot);let b=book();b.history=[prior.result];b=recordMrfta(b,true);d.modelo_a_snapshot=saveIrpcBook(d,b);const recovered=JSON.parse(JSON.stringify(d)),saved=irpcBook(recovered);assert.deepEqual(saved,b);assert.equal(irpcCurrent(recovered,saved),true);assert.equal(mrftaCurrent(saved,true),true);
for(const[k,v]of Object.entries(original))if(k!=='irpcWithholdings')assert.deepEqual(JSON.parse(recovered.modelo_a_snapshot)[k],v,k);
const report=irpcReportRows(recovered);assert.match(JSON.stringify(report),/17500/);assert.match(JSON.stringify(createProjectDossierReport(recovered,{selectedSections:new Set(['finance'])})),/MRFTA/);
assert.match(mrftaHtml(saved,true),/Quadro7/);assert.match(mrftaHtml(saved,true),/QA CER fictício/);const before=structuredClone(saved.mrftaResult);saved.mrfta.interest.amount='600';assert.equal(mrftaCurrent(saved,true),false);assert.throws(()=>mrftaHtml(saved,true));const next=recordMrfta(saved,true);assert.deepEqual(next.mrftaHistory.at(-1),before);assert.equal(next.mrftaResult.model.total.numerator,'17600');
fs.mkdirSync('outputs/irpc-mrfta',{recursive:true});fs.writeFileSync('outputs/irpc-mrfta/calculated.json',JSON.stringify(recovered));fs.writeFileSync('outputs/irpc-mrfta/preparation.html',mrftaHtml(b,true));
});
test('malformed persisted MRFTA rejects recovery without replacing originals',()=>{
const b=book();b.mrfta.codes.push({...b.mrfta.codes[0]});assert.throws(()=>saveIrpcBook(draft(),b));b.mrfta.codes=[];b.mrfta.interest.amount=5;assert.throws(()=>saveIrpcBook(draft(),b));
});
test('export escapes identities,documents and assessment references',()=>{
const b=book();b.mrfta.name='<script>QA</script>';b.mrfta.interest.reference='<img src=x onerror=QA>';const html=mrftaHtml(recordMrfta(b,true),true);assert.ok(!html.includes('<script>QA'));assert.ok(html.includes('&lt;script&gt;'));assert.ok(html.includes('&lt;img'));
});
test('other tax rubrics cannot silently become zero and partial rows remain available',()=>{
const b=book();b.mrfta.otherRubrics='pending';const m=prepareMrfta(b,true);assert.equal(m.total,null);assert.equal(m.principal.numerator,'20000');assert.match(m.pending.join(' '),/IRPS,tributação autónoma/);assert.throws(()=>mrftaHtml(recordMrfta(b,false),false));
});
test('same rubric rate and documented CER aggregate without losing document references',()=>{
const other={...row('other'),allocations:[],settlement:'none'},b=book([row(),other]);b.mrfta.codes.push({rowId:'other',cer:'999',reference:'QA segundo documento de CER fictício'});const m=prepareMrfta(b,true);assert.equal(m.lines.length,1);assert.equal(m.lines[0].base.numerator,'200000');assert.equal(m.principal.numerator,'40000');assert.equal(m.total.numerator,'37500');assert.equal(m.lines[0].references.length,2);assert.equal(m.lines[0].documents.length,2);
});
@@ -0,0 +1,16 @@
import test from'node:test';import assert from'node:assert/strict';import fs from'node:fs';
import{normalBook,normalCurrent,calculateNormal,recordNormal,saveNormalBook,normalHtml,normalReportRows}from'../../resources/js/lib/irpc-normal.ts';
import{newNormalAssessmentInput,calculateNormalAssessment}from'../../resources/js/lib/irpc-normal-assessment.ts';
import{fraction}from'../../resources/js/lib/fiscal-rational.ts';import{createProjectDossierReport}from'../../resources/js/lib/project-dossier-report.ts';
const seed=()=>JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-base-preserved.json',import.meta.url),'utf8'));
const input=()=>({...newNormalAssessmentInput(),treatment:'general_61_1',reference:'QA sujeito residente,actividade ordinária,sem taxa reduzida/benefício ou tributação autónoma neste recorte'});
const context=()=>({year:'2026',scope:'resident_general',currency:'MZN'});
test('current base4400 times statutory general32percent yields1408 colecta with explicit2026 period and L8 unknown balance',()=>{const d=seed(),b=normalBook(d);b.assessment=input();const m=calculateNormal(d,b);assert.equal(m.taxableProfit.numerator,'6700');assert.equal(m.taxableBase.numerator,'4400');assert.equal(m.colecta.numerator,'1408');assert.equal(m.tax,null);assert.equal(m.assessment.rate.numerator,'32');assert.deepEqual(m.assessment.period,{year:'2026',from:'2026-01-01',to:'2026-12-31'});assert.match(m.assessment.classification,/artigo61\(1\)/);assert.equal(m.assessment.finalBalance.payable,null);assert.equal(m.assessment.finalBalance.recoverable,null);assert.equal(m.assessment.finalBalance.scope,'L8');});
test('missing classification and special cases do not silently inherit32percent;known upstream base remains',()=>{for(const patch of[{treatment:''},{treatment:'other'},{reference:''}]){const m=calculateNormalAssessment({...input(),...patch},fraction(4400n),context());assert.equal(m.colecta,null);assert.equal(m.taxableBase.numerator,'4400');assert.ok(m.pending.length>0);if(patch.treatment==='other')assert.equal(m.rate,null);}});
test('rate is scoped by period,residence regime and currency,not carried across years or contexts',()=>{for(const patch of[{year:'2025'},{year:'2027'},{scope:'other'},{currency:'USD'}]){const m=calculateNormalAssessment(input(),fraction(4400n),{...context(),...patch});assert.equal(m.colecta,null);if(patch.year)assert.equal(m.rate,null);}});
test('unknown base is not replaced with6700profit;known zero stays zero and fractional cents remain exact',()=>{assert.equal(calculateNormalAssessment(input(),null,context()).colecta,null);assert.equal(calculateNormalAssessment(input(),fraction(0n),context()).colecta.numerator,'0');const m=calculateNormalAssessment(input(),fraction(1n,100n),context());assert.deepEqual(m.colecta,{numerator:'2',denominator:'625'});assert.equal(m.centExact,false);assert.equal(calculateNormalAssessment(input(),fraction(-1n),context()).colecta,null);});
test('an incomplete base calculation only blocks colecta;profit and valid source amounts remain visible',()=>{const d=seed(),b=normalBook(d);b.assessment=input();b.base.benefits={state:'',amount:'',reference:''};const m=calculateNormal(d,b);assert.equal(m.taxableProfit.numerator,'6700');assert.equal(m.taxableBase,null);assert.equal(m.colecta,null);assert.equal(m.assessment.rate.numerator,'32');});
test('retentions,payments and annual credits are not subtracted or resolved by this L6 scope',()=>{const d=seed(),b=normalBook(d);b.assessment=input();const m=calculateNormal(d,b);d.annual_withholdings='999999';d.annual_payments='999999';d.annual_credits='999999';const s=JSON.parse(d.modelo_a_snapshot);for(const w of Object.values(s.irpcWithholdings??{})){w.payments=[];if(w.mrfta)w.mrfta.codes=[];}d.modelo_a_snapshot=JSON.stringify(s);const changed=calculateNormal(d,b);assert.deepEqual(changed.colecta,m.colecta);assert.deepEqual(changed.assessment.finalBalance,m.assessment.finalBalance);assert.equal(changed.tax,null);});
test('legacy3 remains current without recalculation;version4 roundtrip/history/report/dossier preserve prior books and stale guards',()=>{const d=seed(),old=normalBook(d);assert.equal(normalCurrent(d,old),true);assert.equal(old.result.model.version,'IRPC-normal-adjustments/3');const originalStore=JSON.parse(d.modelo_a_snapshot);const b=recordNormal(d,{...old,assessment:input()},'2026-10-25T23:30:00Z');assert.deepEqual(b.history.at(-1),old.result);assert.equal(b.result.model.version,'IRPC-normal-adjustments/4');d.modelo_a_snapshot=saveNormalBook(d,b);assert.deepEqual(JSON.parse(d.modelo_a_snapshot).irpcWithholdings,originalStore.irpcWithholdings);const back=JSON.parse(JSON.stringify(d));assert.equal(normalCurrent(back,normalBook(back)),true);const html=normalHtml(back);assert.match(html,/colecta simulada:1408/);assert.match(html,/saldo final a pagar ou recuperar:Indeterminado \(L8\)/);assert.match(html,/taxa:32%/);assert.match(JSON.stringify(createProjectDossierReport(back,{selectedSections:new Set(['finance'])})),/1408/);assert.match(JSON.stringify(normalReportRows(back)),/Saldo final — âmbito L8/);const changed=normalBook(back);changed.assessment.reference='';back.modelo_a_snapshot=saveNormalBook(back,changed);assert.equal(normalCurrent(back,normalBook(back)),false);assert.throws(()=>normalHtml(back));const again=recordNormal(back,normalBook(back));assert.equal(again.result.model.colecta,null);assert.deepEqual(again.history.at(-1),b.result);
fs.mkdirSync('outputs/irpc-l6-colecta',{recursive:true});fs.writeFileSync('outputs/irpc-l6-colecta/calculated.json',JSON.stringify(d));fs.writeFileSync('outputs/irpc-l6-colecta/preparation.html',normalHtml(d));const md=structuredClone(d),missing=normalBook(md);missing.assessment.treatment='';md.modelo_a_snapshot=saveNormalBook(md,recordNormal(md,missing));fs.writeFileSync('outputs/irpc-l6-colecta/missing.json',JSON.stringify(md));});
test('unsupported input versions and malformed classification fail without replacing originals',()=>{const d=seed(),b=normalBook(d);b.assessment=input();b.assessment.version=2;assert.throws(()=>saveNormalBook(d,b));b.assessment.version=1;b.assessment.treatment='general20';assert.throws(()=>saveNormalBook(d,b));});

Some files were not shown because too many files have changed in this diff Show More