Compare commits

..
24 changed files with 3751 additions and 14 deletions
@@ -920,3 +920,104 @@ Conferência autenticada por leitura em `2026-10-26T13:56:51.412248+02:00` (Afri
**Próximo conjunto delimitado para implementaçãoQA:CBF16 com duodécimos.** Reutilizar activos,tabela/taxa normal máxima,método constante,qualificaçãoCBF e periodizaçãoL6 existentes. Primeiro caso:exercício anual civil2026 com entrada em uso durante o ano;imóvel novo do projecto ou máquina industrial/agro-industrial já suportada;sem quotas anteriores,saída ou cumulação de outros benefícios. Ligar a quota mensalL6 ao incrementoCBF16,limitando ao contabilizado/saldo fiscal e mostrando apenas a diferença adicional. Demonstrar condição satisfeita,negativa,informação em falta e ausência declarada,cálculo→gravação→recuperação→relatório,efeitos no lucro/base/colecta e conservação dos históricos. Este conjunto está apenas delimitado:não é novo cálculo instalado.
Degressivo,reabilitados/usados/reavaliados,quotas anteriores e cumulação cooperativa+CBF16 continuam nos casos próprios. O saldo anterior de sete grupos de código e quatro dependências documentais permanece na mesma matriz,com exemplos/condições de retoma;nenhuma pendência foi apagada. Documento individual em falta limita só o activo/caso dependente. Localização não concede benefício. **L6 operacional delimitado;L7 parcial;retenções,pagamentos,créditos anuais e saldo final emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-server-state-20261026.json`.
## 26/10/2026 — CBF16 com duodécimos demonstrado em QA
**QA preparado, sem instalação.** O portal mantém `e07f89da`, incluindo o primeiro conjuntoL7 `ab2ff2fd`. Este incremento implementa a ligação CBF16–duodécimos delimitada no recibo `irpc-l7-server-state-20261026.json`. L6 permanece operacional no âmbito aceite;L7 continua parcial;L8 conserva retenções,pagamentos,aplicação anual de créditos e saldo final a pagar/recuperar. SGF TEMPO não foi afectado.
**Reutilização e condições:** a opção «Preparar CBF16 com duodécimos» é explícita e conserva os activos,datas,valores e restantes escolhas. O utilizador confirma a reutilização dos meses e da opção mensal do mapaL6. Sem essa opção,os livros/resultados entregues permanecem na fotografia10,com a mesma chave e valores. Com ela,a fotografia11 guarda a preparação,o cálculo e o histórico10 anterior. É possível manter a preparação anual sem alterar automaticamente activos ou apagar resultados anteriores.
Recorte demonstrado:exercício anual civil2026,activo novo já suportado emL6,imóvel novo afecto ao projecto ou máquina industrial/agro-industrial das categorias correspondidas,método constante pela taxa normal máxima,entrada emuso durante2026,sem saída,quotas anteriores ou cumulação de outros benefícios. Mantêm-se prova das condiçõesCBF3/9,reconhecimento10 quando exigido (ou excepção identificada),afectação e período. Localização/sector não activam benefício. Os meses calculados por L6 incluem o mês da entrada emuso;não se introduz cálculo diário nem uma segunda agenda de amortização.
**Cálculo:** usa o motor de amortizaçõesL6 existente,com taxa normal×1,5 e os mesmos duodécimos/12. Mantém base depreciável,terreno/residual,limite contabilístico e saldo fiscal. L7 aplica apenas a diferença entre a dedução fiscal normal e a acelerada;não cria outro activo ou uma segunda depreciação contabilística. Os outros activos do mapa conservam a quota normal. O resultado de referênciaL6 e o resultado apósL7 são apresentados separadamente.
| Caso sintético | Valores demonstrados |
| --- | --- |
| Máquina existente:base1000,taxa normal10%,entrada15/07/2026,6duodécimos,contabilizado60 | Quota normal50;quotaCBF16 75;dedução limitada60;diferença adicional10MZN. Lucro/base de referência6310 e colecta2019,20;apósL7 lucro/base6300 e colecta2016,00MZN. Saldo finalL8indeterminado. |
| Entrada emOutubro,3duodécimos | Quota normal25;quotaCBF16 37,50;diferença12,50 quando o contabilizado a suporta. |
| Entrada emDezembro,1duodécimo | Quota normal25/3,quotaCBF16 25/2;diferença exacta25/6MZN,sem arredondamento fiscal presumido. Aproximação de apresentação e valor exacto permanecem distintos. |
| Imóvel novo já classificado emL6 | Terreno/residual e base são reutilizados;taxa e meses aplicam-se à mesma base. O exemplo confirma quota40→60,limitada50,com diferença10. |
| Falta de suporte da opção/datas/condições | CBF16 fica indeterminado;entradas e referênciaL6 conhecidas conservadas. Não substituir desconhecido por zero. |
| Condição negativa / ausência declarada | Estados distintos e documentados;nenhuma taxaCBF16 aplicada à parcela negativa;ausência produz efeito zero justificado. |
**Demonstração executada:**15testes dirigidos novos,com comparação exacta dos três livros10 aceites (despesa autónoma,cooperativa e amortização anual),sem repetir as suas suites funcionais. API privada:1teste/89asserções,cinco casos mensal/fracção/falta/negativa/ausência,em `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441,guarda de identidade/base e transacção com rollback. Cálculo→gravação→recuperação→HTML e dossier financeiro conferidos a partir dos casos recuperados,com plano/activos/históricos conservados. Recalcular não acumula a diferença adicional. Alterar a data invalida a fotografia corrente sem alterar a anterior.
UI do componente real:opção explícita/cancelamento,alteração das datas e opção mensal no activoL6,informação em falta,6→3duodécimos,limite75→60,diferença10,fracção25/6,gravação/recuperação local e download do relatório;sem erros de página. Esta prova local é distinta da API. Wayfinder`--with-form`,TypeScript e buildQA passaram. Não houve escrita no activo,migração,importação,activação por consulta de fonte ou nova ronda das provas não afectadas deL3/ISPC/câmbio/L5/L6. O motor de amortizaçõesL6 não foi alterado.
**Saldo e condição de retoma:** este recorte cobre duodécimos em exercício anual civil2026;períodos fiscais curtos/autorizados distintos,saídas,anos posteriores,quotas anteriores,quota escolhida inferior à máxima,degressivo,reabilitados/usados/reavaliados e cumulações mantêm correspondência própria. Retomar cada caso quando a respectiva regra/período/contabilização e compatibilidade estiverem ligados ao activo/documentos já existentes,e demonstrar só o seu efeito novo. Uma pendênciaL6 afecta apenas o activo dependente. Os restantes grupos do saldoL7 e os camposM20/M22 ainda sem correspondência mantêm-se;este lote não preenche campos oficiais por aproximação nem conclui o IRPC.
**Entrega agrupada:** os casos compatíveis mensal/fracção/negativa/ausência/informação insuficiente acompanham o mesmo candidato. A capacidade remota de5,52GiB/21448231inodes observada às13:56:51 de26/10 é histórica,não confirmação para nova instalação. Antes da próxima entrega,medir outra vez espaço/inodes na partição de release+backup+temporários,confrontar com o limiar existente5GiB e o backup/carga dessa execução,conferir o main então actual e executar backup/restauro fresco. Manter a versão activa até a nova ficar pronta. Não executar limpeza local ou doSGF para substituir esse controlo remoto.
Fontes e inventário8143 reutilizados dos cotejos aceitesCBF16 eDecreto72/2013art9;originais preservados,sem pesquisa transversal repetida. Recibo:`docs/investmoz/simulations/irpc-l7-months-qa-20261026.json`;provas locais:`outputs/irpc-l7-months/`. Reprodução dirigida: `node --test tests/frontend/irpc-special-months.test.mjs`; `php tools/irpc-special-months-qa.php routes`; `php tools/irpc-special-months-qa.php test`; `tsc --noEmit`; build com `INVESTMOZ_QA_BUILD=1`.
## 26/10/2026 — CBF16 com duodécimos instalado pelo Git
Instalado `0bd5d495505d512088887efd3dc5c61f645b1647`,com `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd` preservado como versão anterior. O main não apresentava divergência;integração por fast-forward sem alterações de código à candidataQA. Backup fresco `2026-10-26T12:34:42Z` e restauro isolado sem rede/55441:174tabelas e369ficheiros/configuração conferidos. Capacidade medida imediatamente antes:5.50GiB e21448052inodes;depois do backup:5.33GiB,acima do limiar existente5GiB,com inodes disponíveis confrontados com a carga observada. Sem limpeza local/remota ou intervençãoSGF.
Conferidos3ficheiros do delta,60ficheiros de execução protegidos e31originais. Schema,roles/grants e permissões iguais;172tabelas de negócio mantêm o backup,cache/sessões reconciliadas com eventos operacionais/acessos públicos. Revisão/manifest,marcadoresCBF16 e suporte10,assets e simuladorHTTP200 conferidos. Sem migrações,importações,recálculo de históricos ou escrita privada sintética no activo. Reutilizadas as provasQA15testes/API89/UI/tipos/build;apenas os controlos automáticos obrigatórios do procedimentoGit e a conferência do delta instalado.
O exemplo mantém quota normal50,quotaCBF16 75 limitada ao contabilizado60:dedução adicional**60−50=10MZN**,não75 nem uma segunda amortização. Lucro/base apósL7 6300 e**colecta simulada2016MZN**;saldo final a pagar/recuperar por determinar emL8. Os tratamentos de despesas autónomas,cooperativas abrangidas e amortizações anuais anteriores permanecem disponíveis,com fotografias/históricos conservados. O estadoQAsem instalação é histórico para este incremento.
**SaldoL7:**CBF16 anual com duodécimos entregue;continuam fora deste recorte períodos curtos/não civis,saídas,anos/quotas anteriores,métodos/categorias não correspondidos,cumulações e restantes famílias/transportesM20M22 já discriminados na mesma matriz. Retoma por regra/período/contabilização e compatibilidade do caso;documentos em falta só limitam o dependente. O próximo conjunto a executar emQA é**CBF16 em período curto por início de actividade de residente em2026**,reutilizando tipo/período e mesesL6,sem anualizar base ou taxa. Cessação,transição e outras extensões conservam âmbito próprio. L6operacional delimitado;L7parcial;localização não concede benefício;L8conserva liquidação final. Recibo:`docs/investmoz/simulations/irpc-l7-months-delivery-20261026.json`.
## 26/10/2026 — CBF16 no início de actividade demonstrado em QA
**QA preparado, sem instalação.** O portal mantém `0bd5d495`, com duodécimos anuais e os tratamentos anteriores preservados. Este incremento cobre apenas CBF16 num período curto por início de actividade de residente em2026,com meses completos até31/12. Reutiliza período,tipo,suporte e activosL6,sem anualizar resultados. Não altera o motor cambial/de amortizaçõesL6 nem volta a pesquisar fontes/provas aceites.
A preparação é explícita dentro dos duodécimosCBF16. Pode reutilizar o suporte já declarado emL6 por acção do utilizador,sem modificar datas,activos ou qualificação. Exige condiçõesCBF3/9,reconhecimento10 quando aplicável ou excepção identificada,afectação do activo e suporte do período. Activo novo já correspondido,entrada emuso no período,método constante pela taxa normal máxima,sem quotas anteriores,saída ou cumulação. A localização não activa benefícios. Sem a nova opção,as fotografias10/11 mantêm chaves e resultados;com ela,a fotografia12 conserva o resultado11 e todo o histórico anterior.
| Caso novo | Efeito demonstrado |
| --- | --- |
| Início1Julho;máquina com entrada15Julho,base1000,taxa10%,contabilizado60 | 6mesesL6;quota normal50,acelerada75,limitada60:dedução adicional10MZN. Lucro/baseL6 3130→L7 3120;colecta simulada1001,60→998,40MZN. Saldo finalL8indeterminado. |
| InícioOutubro / Dezembro | 3 /1meses efectivos;sem anualização. Dedução adicional5 /5/3MZN,com fracção exacta e aproximação de apresentação separadas. |
| Suporte em falta | SóCBF16 fica indeterminado;referênciaL6 conhecida e entradas conservadas. |
| Condição negativa / ausência declarada | Estados distintos e justificados;efeito zero identificado,sem taxa acelerada aplicada à parcela negativa. |
Provas novas dirigidas:9testes;API privada1teste/97asserções emQA isolada127.0.0.1:55441/base `simulator_fiscal_delta_20261021_test`,com guarda e transacção/rollback. Cinco casos passaram cálculo→gravação→recuperação→HTML e dossier financeiro. Comparação exacta do resultado11 aceite e conservação de todo o histórico,plano,activos e outros livros;recalcular não acumula deduções. Interface real demonstrou preparar/cancelar,reutilizar suporteL6,pendência,limites,fracções,guardar/recuperar e exportar,sem erros. Wayfinder`--with-form`,TypeScript e buildQA passaram. Conferidos584ficheiros protegidos e31originais sem alteração;nenhuma migração/importação/escrita privada no activo. SGF TEMPO separado.
**Saldo concretoL7 — código:**(1)outras origens/parcelas de despesas autónomas;(2)cooperativas mistas/retidas e demais entidades9–14;(3)CBF16 cessação/transição/períodos não civis,saídas,quotas/anos anteriores,quota inferior,métodos/categorias e cumulações;(4)mais-valias61-A/operações54–56/41-A;(5)CBF17–19 e direito potencial15;(6)regimes sectoriais/territoriais;(7)transporteL7M20/M22. A extensão de início de actividade sai deste saldo apenas no recorteQA acima;cessação é um próximo candidato compatível,reutilizando o períodoL6,com regra/quotas/saída próprias a demonstrar antes de se declarar suportada.
**Documentos por caso — exemplos/retoma:**despesa36g sem qualificação61(4)→associar natureza/parcela/período;projecto sem reconhecimento10→instrumento ou norma de excepção exigida;cumulação cooperativa+CBF16→disposição aplicável,ordem e limites;efeitoL7 sem campoM20/M22→exemplar/edição/campo e representação das fracções. Não são novos aprovadores ou revalidações genéricas. A dúvida limita o caso/campo dependente;as demais provas permanecem válidas.
Entrega agrupada preparada para os cinco casos compatíveis,sem instalação deste incremento. Na futura entrega:medir novamente espaço/inodes/carga de compilação e backup,conferir o main então actual e executar backup/restauro fresco,mantendo a versão activa até a nova ficar pronta. O controlo de5,50GiB antes/5,33GiB após backup desta entrega0bd5d495 é histórico,não garantia futura. **L6 operacional delimitado;L7 parcial;colecta distinta do saldo final deL8.** Recibo:`docs/investmoz/simulations/irpc-l7-start-period-qa-20261026.json`;provas:`outputs/irpc-l7-start-period/`. Reprodução dirigida:`node --test tests/frontend/irpc-special-start-period.test.mjs`;`php tools/irpc-special-start-period-qa.php routes`;`php tools/irpc-special-start-period-qa.php test`;`tsc --noEmit`;build com `INVESTMOZ_QA_BUILD=1`.
## 26/10/2026 — CBF16 cessação e quotas anteriores: entrega agrupada preparada em QA
**QA, sem instalação.** O conjunto inclui `ba83afe7` (início de actividade) e acrescenta cessação da actividade em2026 e quotas anteriores documentadas de activos que entraram emuso em2025. A versão do portal comunicada permanece `0bd5d495`;não se voltou a instalar ou a conferir remotamente o activo nesta passagem. O main entretanto avançou para `ae0d74bb`;a candidata incorpora a alteração visual de «Porquê investir»,a nota do manual e a linhaV2-01 da matriz,sem perda das notas fiscais. Nenhum ficheiro dessa alteração foi substituído pelo incrementoL7.
**Condições e reutilização.** Preparação opcional13,distinta de início12 e do recorte mensal11,sem alteração das chaves/resultados anteriores. Usa sujeito/período/activos/quotas e saldosL6. CBF3/9/10/16,Decreto72/2013 art3(3),9(1–3) e10 eCIRPC7(4):condições/afectação/reconhecimento ou excepção identificados,ano civil2026 ou cessação de residente desde1Janeiro até ao último mês completo,contabilização/saldos reconciliados,método constante pela taxa normal máxima,duodécimos desde entrada emuso e ausência de cumulação. Localização não concede benefício.
O recorte de implementação admite activos novos a custo histórico com entrada2025/2026. A selecção destes anos é coberturaQA,não um limite legal inventado para os restantes activos. Valores anteriores contabilísticos,fiscais,parcela temporariamente tributada e suporte são reutilizados deL6;não se recalculam taxas/benefícios de exercícios passados. Uma entrada em2026 com quotas anteriores positivas fica por reconciliar. Informação em falta não é zero;condição negativa e ausência declarada permanecem distintas.
**Cessação não é saída do activo.** O termo do período limita os meses efectivos,sem preencher transmissão/inutilização por presunção. Uma saída de activo documentada dentro do período reutiliza a dataL6 e exclui o mês do evento,conformeart9(2);sem ela,reutiliza os meses do período. Este ramo só apura a amortização,não calcula uma mais-valia ou operação de transmissão por aproximação.
| Caso sintético novo | Efeito no cálculo |
| --- | --- |
| Cessação30Junho,activo emuso desdeJaneiro2026,sem quotas anteriores,contabilizado60 | 6meses;quota normal50,acelerada75 limitada60;diferença adicional10MZN. Lucro/base3130→3120;colecta simulada1001,60→998,40MZN. Sem saída do activo presumida. |
| Mesmo período,activo2025;quotas anteriores contabilísticas150,fiscais100,parcela recuperável50 | Dedução normal50;acelerada75,incluindo15 de parcela anterior. Diferença adicional25MZN,sem somar novamente os15. Saldo anterior aritmético50→35;saldo fiscal após dedução850→825. Lucro/base3130→3105;colecta simulada1001,60→993,60MZN. Os saldos declarados150/100/50 permanecem intactos. |
| Ano civil2026,mesmos saldos anteriores,contabilizado120 | Dedução100→150,incluindo30 de parcela anterior;diferença adicional50MZN e saldo anterior aritmético20. Lucro/base6260→6210;colecta simulada2003,20→1987,20MZN. |
| CessaçãoJunho com saída do activo documentada20Junho | 5meses;quota normal125/3 eacelerada125/2;diferença125/6MZN. Fracção exacta preservada,sem arredondamento fiscal presumido. |
| Saldo fiscal remanescente20 ou contabilização/parcela anterior insuficiente | Ambos os cálculos respeitam os mesmos limites;dedução adicional pode ser zero,sem exceder a base nem consumir saldos oficiais. |
| Suporte em falta / condição negativa / ausência declarada | Estados e efeitos separados;uma falta de suporteCBF16 mantém a referênciaL6 conhecida e limita apenas o benefício dependente. Um saldoL6 desconhecido limita também os cálculos que dele dependem. |
**Provas novas:**11testes dirigidos,API privada1teste/123asserções,sete casos cálculo→gravação→recuperação→HTML/dossier financeiro. BaseQA `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441,guarda de identidade e transacção com rollback. Comparação exacta do resultado12 aceite,conservação de todo o histórico,activos,plano e outros livros;recalcular não acumula a dedução nem reduz os saldos declarados. Interface real:preparar/cancelar,preencher apenas os suportes novos,pendência,recuperação15/saldo35,saída5meses/fracção,gravação/recuperação/exportação e ausência/negativa,sem erros. Wayfinder`--with-form`,TypeScript ebuildQA passaram;build/tipos conferidos também após incorporar o main. Reutilizadas,sem repetir,as provas aceites de `ba83afe7` e dos restantes percursos. MotoresL6 de amortizações/periodização/câmbio,schema,configuração,permissões,originais e provas anteriores preservados. SGF TEMPO separado;nenhuma escrita no activo,migração ou importação.
**Saldo concreto — código:**(1)outras origens/segregações de despesas autónomas;(2)cooperativas mistas/retidas e demais entidades9–14;(3)CBF16 com activos anteriores a2025,períodos parciais/não civis/transição,saídas fora do recorte,quota inferior,métodos/categorias e cumulações;(4)mais-valias61-A/operações54–56/41-A;(5)CBF17–19 e direito potencial15;(6)regimes sectoriais/territoriais;(7)transporteL7M20/M22. O recorte agora demonstrado deixa de figurar como integralmente por implementar,mas permanece apenas emQA. Retomar extensõesCBF16 com a regra temporal/método/base ligada aos activos e demonstrar o efeito novo;retomar mistos/cumulações com segregação,ordem e limites,sem pesquisar novamente o que já está aceite.
**Dependências documentais por caso:**natureza/parcela/período da operação→associar os factos e o exercício;reconhecimentoCBF10→instrumento ou excepção exigida;quotas anteriores150/100/50 sem suporte→reconciliar a parcela temporariamente tributada,sem incluir exclusões permanentes;cumulação→disposição/ordem/limites aplicáveis;campoM20/M22→exemplar/edição/campo e representação exacta. A falta limita só o caso/campo dependente,não exige aprovadores ou revalidação genérica de fontes.
**Entrega agrupada preparada:**início12 de `ba83afe7` mais cessação/quotas anteriores13,com as provas aceites e novas separadas no mesmo pacote. Antes de instalar,voltar a conferir main,espaço/inodes/carga de compilação ebackup,executar backup/restauro fresco e manter a versão activa até a nova ficar pronta. **L6 operacional delimitado;L7 parcial;colecta simulada não é saldo final:retenções,pagamentos,créditos anuais e saldo a pagar/recuperar permanecem emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-cessation-prior-qa-20261026.json`;provas:`outputs/irpc-l7-cessation-prior/`. Reprodução só do delta:`node --test tests/frontend/irpc-special-cessation-prior.test.mjs`;`php tools/irpc-special-cessation-prior-qa.php routes`;`php tools/irpc-special-cessation-prior-qa.php test`;`tsc --noEmit`;build com `INVESTMOZ_QA_BUILD=1`.
## 26/10/2026 — CBF16 início, cessação e quotas anteriores instalado pelo Git
**Instalado `632dc06930d6b4f1b012feb3b4daa3b1cfc53f39`,incluindo `ba83afe7`.** Entrega única do início de actividade,cessação e quotas anteriores no âmbitoQA demonstrado. `0bd5d495` permanece como release anterior;históricos e provas aceites conservados. O main `ae0d74bb` e a alteração visual de «Porquê investir» foram incorporados,preservando texto/cor/geometria e a linhaV2-01 da matriz. Sem instalação separada dos dois incrementos.
**Capacidade e recuperação:**a primeira medição confirmou 4.32GiB,abaixo do mínimo existente5GiB,e a falha anteriorae0d74bb por falta de espaço;versão activa preservada. Conferidas ausência de instalaçõesnpm e de ficheiros abertos,só a cache regenerável `/root/.npm/_cacache` foi limpa pelo comando npm próprio. Recuperados 2.82GiB;32logs npm anteriores e `_npx` preservados. Sem apagar releases,backups,dependências dos projectos,provas únicas ou ficheirosSGF. Nova medição:7.15GiB e21431150inodes;após backup:6.99GiB,acima do limiar5GiB,com capacidade de backup/compilação e escala de inodes conferidas. O limiar do instalador não foi reduzido.
Backup fresco `2026-10-26T13:29:24Z`:174tabelas e369ficheiros/configuração conferidos;restauro isolado sem rede/porta55441 com174checksums iguais. Schema,roles/grants e permissões mantidos. Só depois destas guardas,integraçãoGit por fast-forward sem forçar o histórico. A release anterior ficou activa até a nova estar pronta. Revisão/manifest servidos,marcadores12/13 e restantes leitores,assets e simuladorHTTP200 conferidos após instalação. Três ficheiros do delta fiscal,60ficheiros protegidos/enquadrados no main e31originais correspondem ao destino preparado. Dados de negócio comparados com o backup;cache/sessões reconciliadas com eventos operacionais/acessos públicos. Sem migrações,importações ou escrita privada sintética no activo.
**Resultado demonstrado preservado:**dedução normal50MZN→acelerada75MZN;**75−50=25MZN adicionais**. Os15MZN recuperados de quotas anteriores **já estão incluídos nos75**,não são somados novamente. Saldo anterior aritmético35MZN;valores declarados150/100/50 e históricos mantidos,sem consumo de saldos oficiais. Lucro/base3105MZN e**colecta simulada993,60MZN**;saldo final a pagar/recuperar permanece indeterminado emL8. Cessação da actividade não presume transmissão/inutilização dos activos;saída só quando documentada no mapa existente.
Reutilizadas as provas aceites:início12 (9testes/API97) e cessação/quotas13 (11testes/API123),UI real,gravação/recuperação/relatórios,tipos/build. Não se repetiram as respectivas suites por iniciativa desta entrega;apenas os controlos automáticos obrigatórios do procedimentoGit e a conferência do delta instalado. Os motoresL6 de amortizações,periodização e câmbio mantêm-se;L3,ISPC,L5 e demais provas aceites não foram reabertos. Recibo:`docs/investmoz/simulations/irpc-l7-grouped-delivery-20261026.json`;provas locais:`outputs/irpc-l7-grouped-delivery-20261026/`.
**SaldoL7 e próxima retoma:**continuam próprios as cumulações (por exemplo cooperativa+CBF16:identificar disposição,parcela elegível,ordem e limites antes de combinar),outras origens/segregações de despesas autónomas,cooperativas mistas/retidas e demais entidades,extensõesCBF16fora dos anos/períodos/métodos/categorias demonstrados,mais-valias61-A/operações54–56/41-A,CBF17–19/direito potencial15,regimes sectoriais/territoriais e transporteM20/M22. Mantém-se a separação entre código por implementar e documentos por caso:natureza/parcela/período,reconhecimento ou excepção exigida,saldos anteriores temporariamente tributados,norma/ordem/limites de cumulação e edição/campo/fracção. Uma falta limita só o caso/campo dependente;sem pesquisa transversal repetida ou aprovador genérico. **L6 operacional delimitado;L7 parcial;L8 conserva retenções,pagamentos,créditos anuais e saldo final.** Cada futura entrega volta a medir capacidade e executar backup/restauro fresco.
@@ -0,0 +1,861 @@
{
"status": "grouped_QA_ready_not_installed",
"date": "2026-10-26",
"branch": "codex/irpc-l7-cessation-prior-qa-20261026",
"installed_baseline_reported": "0bd5d495505d512088887efd3dc5c61f645b1647",
"accepted_QA_included": "ba83afe7d8a90fd016fd0cf424418811279285cd",
"runtime_commit": "992c97ad",
"main_incorporated": "ae0d74bb3a5e0220c886dd72801a6550dd4ccbbe",
"merge_commit": "ff84ab64",
"main_presentation_and_V2_01_preserved": true,
"remote_installation_or_recheck_this_pass": false,
"version": "IRPC-normal-adjustments/13",
"scope": "resident annual2026 or fullmonth cessation2026;new historicalcost assets entering2025/2026;constant maximum normalrate,monthlyfromstart,documented prioraccounting/fiscal/recoverable balances;no cumulation",
"scope_choice": "2025/2026 is demonstrated implementation coverage,not a new legal date restriction",
"optional_input": "acceleration.monthly.continuation version1/period/reference/historyReference/monthlyFromStart;exclusive of startPeriod",
"versions10_11_12_keys_results_histories_preserved": true,
"runtime_delta": {
"resources/js/lib/irpc-special.ts": "5b729a8a330765a4adb5c367a25d050c1c5286249187cbeacd820b0436aa6711",
"resources/js/lib/irpc-normal.ts": "b76ecbda7aff09a12ec9d88cd5f6bf099f4ee1ed22a0ab7fd6113422f0085ea2",
"resources/js/components/simulation-irpc-special.tsx": "10afdc4544405dc59a58efeae190c62a90d4c75e71b53dbc0b528cbb50d30991"
},
"L6_depreciation_period_fx_engines_unchanged": true,
"cases_recovered": {
"cessation": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "10",
"denominator": "1"
},
"L7_profit": {
"numerator": "3120",
"denominator": "1"
},
"L7_base": {
"numerator": "3120",
"denominator": "1"
},
"L7_colecta": {
"numerator": "4992",
"denominator": "5"
},
"ledger": [
{
"prior": {
"previousAccounting": "0",
"previousFiscal": "0",
"available": "0",
"reference": "QA ausência declarada de quotas anteriores;activo entrou em2026",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "0",
"denominator": "1"
},
"acceleratedUsed": {
"numerator": "0",
"denominator": "1"
},
"acceleratedRemaining": {
"numerator": "0",
"denominator": "1"
},
"normalFiscalRemaining": {
"numerator": "950",
"denominator": "1"
},
"acceleratedFiscalRemaining": {
"numerator": "940",
"denominator": "1"
}
},
"exit": {
"state": "absent",
"date": ""
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2026-01-15",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": {
"numerator": "75",
"denominator": "1"
},
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": {
"numerator": "60",
"denominator": "1"
},
"additionalDeduction": {
"numerator": "10",
"denominator": "1"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"prior": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "25",
"denominator": "1"
},
"L7_profit": {
"numerator": "3105",
"denominator": "1"
},
"L7_base": {
"numerator": "3105",
"denominator": "1"
},
"L7_colecta": {
"numerator": "4968",
"denominator": "5"
},
"ledger": [
{
"prior": {
"previousAccounting": "150",
"previousFiscal": "100",
"available": "50",
"reference": "QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "50",
"denominator": "1"
},
"acceleratedUsed": {
"numerator": "15",
"denominator": "1"
},
"acceleratedRemaining": {
"numerator": "35",
"denominator": "1"
},
"normalFiscalRemaining": {
"numerator": "850",
"denominator": "1"
},
"acceleratedFiscalRemaining": {
"numerator": "825",
"denominator": "1"
}
},
"exit": {
"state": "absent",
"date": ""
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2025-01-01",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": {
"numerator": "75",
"denominator": "1"
},
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": {
"numerator": "75",
"denominator": "1"
},
"additionalDeduction": {
"numerator": "25",
"denominator": "1"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"annual": {
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"L6_profit": {
"numerator": "6260",
"denominator": "1"
},
"L6_base": {
"numerator": "6260",
"denominator": "1"
},
"L6_colecta": {
"numerator": "10016",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "50",
"denominator": "1"
},
"L7_profit": {
"numerator": "6210",
"denominator": "1"
},
"L7_base": {
"numerator": "6210",
"denominator": "1"
},
"L7_colecta": {
"numerator": "9936",
"denominator": "5"
},
"ledger": [
{
"prior": {
"previousAccounting": "150",
"previousFiscal": "100",
"available": "50",
"reference": "QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "50",
"denominator": "1"
},
"acceleratedUsed": {
"numerator": "30",
"denominator": "1"
},
"acceleratedRemaining": {
"numerator": "20",
"denominator": "1"
},
"normalFiscalRemaining": {
"numerator": "800",
"denominator": "1"
},
"acceleratedFiscalRemaining": {
"numerator": "750",
"denominator": "1"
}
},
"exit": {
"state": "absent",
"date": ""
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2025-01-01",
"months": 12,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "100",
"denominator": "1"
},
"acceleratedQuota": {
"numerator": "150",
"denominator": "1"
},
"normalDeduction": {
"numerator": "100",
"denominator": "1"
},
"acceleratedDeduction": {
"numerator": "150",
"denominator": "1"
},
"additionalDeduction": {
"numerator": "50",
"denominator": "1"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"exit": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "9415",
"denominator": "3"
},
"L6_base": {
"numerator": "9415",
"denominator": "3"
},
"L6_colecta": {
"numerator": "15064",
"denominator": "15"
},
"status": "calculated",
"additional_deduction": {
"numerator": "125",
"denominator": "6"
},
"L7_profit": {
"numerator": "6235",
"denominator": "2"
},
"L7_base": {
"numerator": "6235",
"denominator": "2"
},
"L7_colecta": {
"numerator": "4988",
"denominator": "5"
},
"ledger": [
{
"prior": {
"previousAccounting": "150",
"previousFiscal": "100",
"available": "50",
"reference": "QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "50",
"denominator": "1"
},
"acceleratedUsed": {
"numerator": "5",
"denominator": "2"
},
"acceleratedRemaining": {
"numerator": "95",
"denominator": "2"
},
"normalFiscalRemaining": {
"numerator": "2575",
"denominator": "3"
},
"acceleratedFiscalRemaining": {
"numerator": "1675",
"denominator": "2"
}
},
"exit": {
"state": "known",
"date": "2026-06-20"
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2025-01-01",
"months": 5,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "125",
"denominator": "3"
},
"acceleratedQuota": {
"numerator": "125",
"denominator": "2"
},
"normalDeduction": {
"numerator": "125",
"denominator": "3"
},
"acceleratedDeduction": {
"numerator": "125",
"denominator": "2"
},
"additionalDeduction": {
"numerator": "125",
"denominator": "6"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"missing": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "indeterminate",
"additional_deduction": null,
"L7_profit": null,
"L7_base": null,
"L7_colecta": null,
"ledger": [
{
"prior": {
"previousAccounting": "150",
"previousFiscal": "100",
"available": "50",
"reference": "QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "50",
"denominator": "1"
},
"acceleratedUsed": null,
"acceleratedRemaining": null,
"normalFiscalRemaining": {
"numerator": "850",
"denominator": "1"
},
"acceleratedFiscalRemaining": null
},
"exit": {
"state": "absent",
"date": ""
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2025-01-01",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": null,
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": null,
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": null,
"additionalDeduction": null,
"applied": false,
"reason": "CBF16 cessação/quotas anteriores:identifique período,suporte da vigência/condições e das quotas anteriores ou ausência;duodécimos desde a entrada emuso por documentar. Sem recalcular ou presumir saldos anteriores."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"negative": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"L7_profit": {
"numerator": "3130",
"denominator": "1"
},
"L7_base": {
"numerator": "3130",
"denominator": "1"
},
"L7_colecta": {
"numerator": "5008",
"denominator": "5"
},
"ledger": [
{
"prior": {
"previousAccounting": "150",
"previousFiscal": "100",
"available": "50",
"reference": "QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos",
"normalUsed": {
"numerator": "0",
"denominator": "1"
},
"normalRemaining": {
"numerator": "50",
"denominator": "1"
},
"acceleratedUsed": null,
"acceleratedRemaining": null,
"normalFiscalRemaining": {
"numerator": "850",
"denominator": "1"
},
"acceleratedFiscalRemaining": null
},
"exit": {
"state": "absent",
"date": ""
},
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2025-01-01",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": null,
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": null,
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": null,
"additionalDeduction": {
"numerator": "0",
"denominator": "1"
},
"applied": false,
"reason": "Condição negativa documentada;quota normal mantida."
}
],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"absent": {
"period": {
"from": "2026-01-01",
"to": "2026-06-30",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "absent",
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"L7_profit": {
"numerator": "3130",
"denominator": "1"
},
"L7_base": {
"numerator": "3130",
"denominator": "1"
},
"L7_colecta": {
"numerator": "5008",
"denominator": "5"
},
"ledger": [],
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
}
},
"checks": {
"new_frontend_tests": 11,
"API_tests": 1,
"API_assertions": 123,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_host": "127.0.0.1",
"API_port": 55441,
"transaction_rollback": true,
"wayfinder_with_form": true,
"typescript_after_main": true,
"build_after_main": true,
"HTML_financial_dossier_from_7_API_recoveries": true,
"UI": {
"actualComponent": true,
"explicitPreparationAndCancel": true,
"missingOnlyDependentL7": true,
"assetsAndPeriodNotEdited": true,
"prior15RecoveredWithin75DeductionAdditional25": true,
"prior35RemainingNotConsumed": true,
"annual30RecoveredWithin150DeductionAdditional50": true,
"cessationDoesNotImplyAssetExit": true,
"documentedExit5MonthsExact125over6": true,
"saveRecoverDownload": true,
"negativeAbsenceDistinct": true,
"accepted12DoesNotGainConflictingInput": true,
"L8FinalUnknown": true,
"errors": []
},
"accepted_ba83_proofs_reused_not_rerun": true
},
"preservation": {
"tracked_files_compared_before_documentation": 2816,
"unchanged": 2810,
"changed": [
"docs/investmoz/unification/traceability-and-manual.md",
"docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
"resources/js/components/simulation-irpc-special.tsx",
"resources/js/lib/irpc-normal.ts",
"resources/js/lib/irpc-special.ts",
"resources/js/pages/portal/why-invest.tsx"
],
"main_changes_reconciled_separately": [
"docs/investmoz/unification/traceability-and-manual.md",
"docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
"resources/js/pages/portal/why-invest.tsx"
],
"original_files": {
"docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
"docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
"docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
"docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
"docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
"docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
"docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
"docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
"docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
"docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
"docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
"docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
"docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
"docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
"docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
"docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
"docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
"docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
"docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
"docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
"docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
"docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
"docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
"docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
"docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
},
"histories_plan_assets_and_declared_balances_unchanged": true,
"official_balances_not_consumed": true,
"active_migrations": 0,
"active_writes": 0,
"SGF_TEMPO_touched": false
},
"source_reused": {
"decree": "Decreto72/2013",
"articles": [
"3(3)",
"9(1-3)",
"10"
],
"visual_reused_pages": [
2,
3
],
"local_original": "C:\\laragon\\www\\portal-investidor-irpc-l6-depreciation-qa-20261026\\outputs\\irpc-l6-depreciation\\decreto-72-2013.pdf",
"sha256": "922ef67cb0c1111405c3c0a092d8c302a74fba8a34d627b6e9e13223612e0659",
"CBF": "accepted APIEX compilation,articles3/9/10/16",
"CIRPC": "accepted period7(4)",
"inventory_files": 8143,
"no_broad_research_repeated": true
},
"remaining_code": [
"other autonomousexpense origins/parcels",
"mixed/withheld cooperative income and other9-14entities",
"CBF16 pre2025entries,otherperiods/partialmonths/transition,exits outside demonstratedscope,lowerquota,methods/categories/cumulation",
"capitalgains61-A and specialoperations54-56/41-A",
"CBF17-19 and potential15entitlement;annualuseL8",
"sector/territorial/specificregimes",
"official L7 M20/M22 transport"
],
"document_conditions": [
"nature/parcels/period",
"required recognition or exception",
"reconciliation of actual prioraccounting/fiscal/temporaryrecoverable balances",
"specific normativeperiod/cumulationorder/limits",
"form edition/field/fraction representation"
],
"future_delivery_requires": [
"current main compatibility recheck",
"fresh space/inodes/build/backup capacity",
"fresh backup/restore",
"keep active until new ready"
],
"L6_operational_delimited": true,
"L7_partial": true,
"L8_final_balance_separate": true,
"evidence_directory": "outputs/irpc-l7-cessation-prior"
}
@@ -0,0 +1,937 @@
{
"status": "CBF16_start_cessation_prior_group_installed",
"installed": {
"status": "installed",
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"release": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"previous_release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"database_migrations": 0,
"content_imports": 0
},
"previous_installed": "0bd5d495505d512088887efd3dc5c61f645b1647",
"included_QA": [
"ba83afe7d8a90fd016fd0cf424418811279285cd",
"632dc06930d6b4f1b012feb3b4daa3b1cfc53f39"
],
"main_preserved_before_integration": "ae0d74bb3a5e0220c886dd72801a6550dd4ccbbe",
"backup": {
"stage": "/var/backups/investmoz-irpc-l7-grouped-delivery-20261026/backup",
"created_at": "2026-10-26T13:29:24Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "80e6149d9d1eb001b32893e40ae484bcb6ed618d41bff1489ab7a5bccbdf306e",
"files_sha256": "2f0d1fff3e0b6237b01af52377ea71718e9970550f9b017b58817ec2a560adcf",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l7_grouped_restore_20261026",
"port": 55441,
"source_dump_sha256": "80e6149d9d1eb001b32893e40ae484bcb6ed618d41bff1489ab7a5bccbdf306e",
"active_database_writes": 0
},
"capacity_block_before": {
"checked_at_UTC": "2026-10-26T13:25:42.513605+00:00",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"release_revision": {
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"branch": "main",
"built_at": "2026-10-26T12:39:22.332516+00:00",
"manifest_sha256": "ce3110f77afcaefb5943e50fff77cc8feb34b4c1af20aea1fb64602ffa739264"
},
"service": "MainPID=0\nExecMainStatus=1\nActiveState=failed\nSubState=failed\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 4636987392,
"available_inodes": 21416284,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 4636987392,
"available_inodes": 21416284,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 4636987392,
"available_inodes": 21416284,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 4636987392,
"available_inodes": 21416284,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 4636987392,
"available_inodes": 21416284,
"total_inodes": 29089792
}
],
"free_bytes": 4636987392,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917995,
"same_partition_release_and_backup": true,
"space_guard_satisfied": false,
"current_release_entry_reference": 31197,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"regenerable_npm_cache_recovery": {
"at_UTC": "2026-10-26T13:28:45.839223+00:00",
"target": "/root/.npm/_cacache",
"method": "npm cache clean --force with separate new log directory",
"free_before": 4648849408,
"free_after": 7681077248,
"recovered_bytes": 3032227840,
"old_npm_logs_verified": 32,
"npx_bytes_preserved": 109912064,
"installed_record_unchanged": true,
"project_dependencies_releases_backups_untouched": true,
"active_business_writes": 0
},
"capacity_before": {
"checked_at_UTC": "2026-10-26T13:29:08.917728+00:00",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"release_revision": {
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"branch": "main",
"built_at": "2026-10-26T12:39:22.332516+00:00",
"manifest_sha256": "ce3110f77afcaefb5943e50fff77cc8feb34b4c1af20aea1fb64602ffa739264"
},
"service": "MainPID=0\nExecMainStatus=1\nActiveState=failed\nSubState=failed\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7680946176,
"available_inodes": 21431150,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7680946176,
"available_inodes": 21431150,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7680946176,
"available_inodes": 21431150,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7680946176,
"available_inodes": 21431150,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7680946176,
"available_inodes": 21431150,
"total_inodes": 29089792
}
],
"free_bytes": 7680946176,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917995,
"same_partition_release_and_backup": true,
"space_guard_satisfied": true,
"current_release_entry_reference": 31197,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"capacity_after_backup": {
"checked_at_UTC": "2026-10-26T13:30:52.665710+00:00",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"release_revision": {
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"branch": "main",
"built_at": "2026-10-26T12:39:22.332516+00:00",
"manifest_sha256": "ce3110f77afcaefb5943e50fff77cc8feb34b4c1af20aea1fb64602ffa739264"
},
"service": "MainPID=0\nExecMainStatus=1\nActiveState=failed\nSubState=failed\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7501979648,
"available_inodes": 21431137,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7501979648,
"available_inodes": 21431137,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7501979648,
"available_inodes": 21431137,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7501979648,
"available_inodes": 21431137,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 7501979648,
"available_inodes": 21431137,
"total_inodes": 29089792
}
],
"free_bytes": 7501979648,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917995,
"same_partition_release_and_backup": true,
"space_guard_satisfied": true,
"current_release_entry_reference": 31197,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"capacity_after_installation": {
"checked_at_UTC": "2026-10-26T13:36:32.849652+00:00",
"installed": {
"status": "installed",
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"release": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"previous_release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"release_revision": {
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"branch": "main",
"built_at": "2026-10-26T13:34:38.155848+00:00",
"manifest_sha256": "a19a56e9ecf5e15cdbac92baefa483af70905a530c39927d30f0abfaaebcdf3f"
},
"service": "MainPID=0\nExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 6477869056,
"available_inodes": 21399599,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 6477869056,
"available_inodes": 21399599,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 6477869056,
"available_inodes": 21399599,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 6477869056,
"available_inodes": 21399599,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 6477869056,
"available_inodes": 21399599,
"total_inodes": 29089792
}
],
"free_bytes": 6477869056,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917995,
"same_partition_release_and_backup": true,
"space_guard_satisfied": true,
"current_release_entry_reference": 31234,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"backup_restore_verified": true,
"fiscal_runtime_delta": [
{
"path": "resources/js/lib/irpc-special.ts",
"sha256_LF": "89f1eafa35111b92ec739d8e36c3279f20224024a1629869b85199566d642c24"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "5b182929ed984f41abe17c9b744c2b76a75532aefd00e2d967063e2b03f76322"
},
{
"path": "resources/js/components/simulation-irpc-special.tsx",
"sha256_LF": "5baedb1df299babef8850022a06f88845f747c008d7773bc226ce9fe9210b5b0"
}
],
"concurrent_main_presentation_delta_preserved": [
"resources/js/pages/portal/why-invest.tsx"
],
"preservation": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"installed": {
"status": "installed",
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"release": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"previous_release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 3,
"preserved_L3_ISPC_FX_runtime_files_verified": 60,
"documentary_files_verified": 31,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "d0ab7ac01e245cd9a1b545db96cbdf2c"
},
"after": {
"rows": 106,
"checksum": "b725d24eab666bda380f94df620c7b1c"
}
},
"sessions": {
"before": {
"rows": 22,
"checksum": "7ad93d9dd3b3b34dee00d256213cf6a2"
},
"after": {
"rows": 10,
"checksum": "3034d8ede70cb5c6aa4cccb181d828b2"
}
}
},
"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_after": {
"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;requestthrottle;identical home-sector cached value with refreshed expiry(HomeController remember10min);no deletedcache",
"sessions": "anonymous sessions from delivery user-agent or exactUA/time correlated with nginx public request;deleted sessions individually expired beyond configured lifetime,normal database session garbage collection(config/session lottery2/100)",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"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,
"same_value_home_cache_expiry_refresh": false
}
]
},
"sessions": {
"before_rows": 22,
"after_rows": 11,
"changes": [
{
"key_sha256": "dd5c5235e9b48e28573884145b201d1f92cdabfea21a1602307c2569efe5d56c",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "d3d49a6f04c09c9852119084de7f840a69a14872847f363523457bcc567f2220",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "d1963bf84cb07dfc540935a88fbeb14f272763938b4db1fb68ffd28e6be9e157",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "5b744c29cc4e8a7d20f33814b52fa522e2c04dc525e7e82fa1c00e18ba91d528",
"kind": "updated",
"fields": [
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "7cd11e7b663d5c5b1b6b31703b8b702ccef9a51f5ae9003f6ea177f3bde8c576",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "3da37b843afdc870f2c0b1336344e97218a264ab5a7b44825a194c89a48fab32",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "6e12944bc8f670195d0c6d2638337e2bf922261a158d130ba09f640a5722f0df",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "cd8c2106a4f4ab7802317e6602c26cfa4cf82a23a86f67a0abbc27fbd82edfb8",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "8cb63d0938103966b238f3aef867a970f2d3f3f66fe62b663457b3f7f2814b10",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "11bbe5f81c536cf605ed71f402fbaa6e9ef551d97c0a76e098078521d9f37f71",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "0efd8f20e81562999badc07fe5af262be1705f08554208e03d281055cd38e34e",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "a89dca10cb8a95f4451ff60eeefe7ac3cd7751b779b0bf97a7e5f5b894f9b115",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "f8e1fa11cf234c2c9f498402557b4c4aed3b89c83dace57af783ae840e4dc821",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "6827c4d8b9a804dc85c3ba12ec33f715b5e753ca00ad0f707e7cbd0e48e5e173",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "9bb5ab5f9a5a161579f25f0d029de6a3a5a9b6a8d03868682bf3fc73c9af6720",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "d0a4dbafaf19e2eee3af4ea41ce9aabf52cb42d5a61a598c54b37d8863b533d7",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "7fb2119013f872a5e4dd70952cc896a4ac8291134e02362bd60805eb77e9587a",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
},
{
"key_sha256": "9bce01e56add682b9d4f3f1829ee83129ab6b18a21c6cf221b04357a8b1232c6",
"kind": "deleted",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": true,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": false
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"branch": "main",
"built_at": "2026-10-26T13:34:38.155848+00:00",
"manifest_sha256": "a19a56e9ecf5e15cdbac92baefa483af70905a530c39927d30f0abfaaebcdf3f"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"IRPC-normal-adjustments/12": [
"assets/project-dossier-MN0piFXE.js"
],
"IRPC-normal-adjustments/13": [
"assets/project-dossier-MN0piFXE.js"
],
"Preparar CBF16 para início de actividade": [
"assets/services-Dwp9X13w.js"
],
"Preparar CBF16 para cessação e quotas anteriores": [
"assets/services-Dwp9X13w.js"
],
"sem consumo de saldos oficiais": [
"assets/project-dossier-MN0piFXE.js"
],
"Preparar CBF16 com duodécimos": [
"assets/services-Dwp9X13w.js"
],
"CBF16 — duodécimos reutilizados de L6": [
"assets/project-dossier-MN0piFXE.js"
],
"Suporte dos duodécimos CBF16": [
"assets/services-Dwp9X13w.js"
],
"Manter preparação anual CBF16": [
"assets/services-Dwp9X13w.js"
],
"CBF16 por duodécimos — ": [
"assets/project-dossier-MN0piFXE.js"
],
"diferença adicional:": [
"assets/project-dossier-MN0piFXE.js"
],
"IRPC-normal-adjustments/10": [
"assets/project-dossier-MN0piFXE.js"
]
},
"assets": [
{
"file": "assets/project-dossier-document-CNhBEvbI.js",
"status": 200,
"sha256": "b9b847d250ac7868f3751371cd49009a3b7d6ad88bdbcb18890b711157508074"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/services-Dwp9X13w.js",
"status": 200,
"sha256": "3b102fdc35d71ba203451d784264e949f2fec8ad55de84ecdee44a4920dc35c2"
},
{
"file": "assets/project-dossier-MN0piFXE.js",
"status": 200,
"sha256": "7dc6c894ba3b9cd83dea620c0f6412fdb219d75970e15a5e2e81af479066c3d6"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-BLx8DOj2.js",
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"pipeline": {
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"installed": {
"status": "installed",
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"release": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"previous_release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"database_migrations": 0,
"content_imports": 0
},
"latest_report": {
"status": "installed",
"commit": "632dc06930d6b4f1b012feb3b4daa3b1cfc53f39",
"release": "/var/www/investmoz-homologacao/releases/632dc06930d6b4f1b012feb3b4daa3b1cfc53f39-4c020686",
"previous_release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"632dc06930d6b4f1b012feb3b4daa3b1cfc53f39"
],
"finished_at": "2026-10-26T13:34:41.383616+00:00"
},
"log_file": "1793021473834371945.log",
"summaries": [
"OK (1 test, 3106 assertions)",
"built in 32.94s",
"OK (59 tests, 317 assertions)",
"# tests 1042",
"# pass 1042",
"# fail 0"
],
"log_bytes": 296124
},
"accepted_QA_proofs_reused": {
"irpc-l7-start-period-qa-20261026.json": {
"new_frontend_tests": 9,
"API_tests": 1,
"API_assertions": 97,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_host": "127.0.0.1",
"API_port": 55441,
"API_transaction_rollback": true,
"wayfinder_with_form": true,
"typescript": true,
"isolated_build": true,
"HTML_financial_dossier_from_5_API_recoveries": true,
"actual_component": {
"actualComponent": true,
"explicitStartOptionAndCancel": true,
"reuseL6PeriodEvidenceExplicit": true,
"assetsAndPeriodUnchanged": true,
"missingPreservesNormal1001_60": true,
"sixActualMonths50Normal75Accelerated60Cap10Additional": true,
"simulatedColecta998_40": true,
"exactFraction5over3": true,
"saveRecoveryDownload": true,
"negativeAbsenceDistinct": true,
"L8FinalUnknown": true,
"errors": []
}
},
"irpc-l7-cessation-prior-qa-20261026.json": {
"new_frontend_tests": 11,
"API_tests": 1,
"API_assertions": 123,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_host": "127.0.0.1",
"API_port": 55441,
"transaction_rollback": true,
"wayfinder_with_form": true,
"typescript_after_main": true,
"build_after_main": true,
"HTML_financial_dossier_from_7_API_recoveries": true,
"UI": {
"actualComponent": true,
"explicitPreparationAndCancel": true,
"missingOnlyDependentL7": true,
"assetsAndPeriodNotEdited": true,
"prior15RecoveredWithin75DeductionAdditional25": true,
"prior35RemainingNotConsumed": true,
"annual30RecoveredWithin150DeductionAdditional50": true,
"cessationDoesNotImplyAssetExit": true,
"documentedExit5MonthsExact125over6": true,
"saveRecoverDownload": true,
"negativeAbsenceDistinct": true,
"accepted12DoesNotGainConflictingInput": true,
"L8FinalUnknown": true,
"errors": []
},
"accepted_ba83_proofs_reused_not_rerun": true
}
},
"no_custom_QA_suite_repeated": true,
"demonstrated_example": {
"normal_deduction_MZN": "50",
"accelerated_deduction_MZN": "75",
"prior_recovered_included_in_75_MZN": "15",
"additional_deduction_MZN": "25",
"prior_remaining_arithmetic_MZN": "35",
"colecta_simulated_MZN": "993.60",
"declared_prior_balances_unchanged": [
"150",
"100",
"50"
],
"official_balances_consumed": false,
"final_balance": "L8_not_calculated"
},
"remaining_L7": "cumulation and remaining implementation/document dependencies retained in same matrix;no full completion",
"next_scope": "qualify combinations per applicable dispositions and segregated parcels;do not add positive benefits or apply automatic global cumulation",
"L6_operational_delimited": true,
"L7_partial": true,
"L8_final_separate": true,
"SGF_TEMPO_untouched": true
}
@@ -0,0 +1,532 @@
{
"status": "CBF16_monthly_installed",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"previous_installed": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"backup": {
"stage": "/var/backups/investmoz-irpc-l7-months-delivery-20261026/backup",
"created_at": "2026-10-26T12:34:42Z",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "a4e23c6647eeb88ad14b697fafb4728be34118ad0fcfb73f02430fdc8a29135c",
"files_sha256": "11143477968fecb78ddccaba1d36842fa18c1ccf0f2c84ae60704b4cbe4c8274",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "irpc_l7_months_restore_20261026",
"port": 55441,
"source_dump_sha256": "a4e23c6647eeb88ad14b697fafb4728be34118ad0fcfb73f02430fdc8a29135c",
"active_database_writes": 0
},
"capacity_before": {
"checked_at_UTC": "2026-10-26T12:33:43.711257+00:00",
"installed": {
"status": "installed",
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"release_revision": {
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"branch": "main",
"built_at": "2026-10-26T11:02:32.435267+00:00",
"manifest_sha256": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5"
},
"service": "MainPID=0\nExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5901660160,
"available_inodes": 21448052,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5901660160,
"available_inodes": 21448052,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5901660160,
"available_inodes": 21448052,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5901660160,
"available_inodes": 21448052,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5901660160,
"available_inodes": 21448052,
"total_inodes": 29089792
}
],
"free_bytes": 5901660160,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917329,
"same_partition_release_and_backup": true,
"space_guard_satisfied": true,
"current_release_entry_reference": 31179,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"capacity_after_backup": {
"checked_at_UTC": "2026-10-26T12:35:49.897136+00:00",
"installed": {
"status": "installed",
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"release_revision": {
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"branch": "main",
"built_at": "2026-10-26T11:02:32.435267+00:00",
"manifest_sha256": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5"
},
"service": "MainPID=0\nExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"volumes": [
{
"path": "/var/www/investmoz-homologacao/releases",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5723119616,
"available_inodes": 21448040,
"total_inodes": 29089792
},
{
"path": "/var/lib/investmoz-deploy",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5723119616,
"available_inodes": 21448040,
"total_inodes": 29089792
},
{
"path": "/var/backups",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5723119616,
"available_inodes": 21448040,
"total_inodes": 29089792
},
{
"path": "/tmp",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5723119616,
"available_inodes": 21448040,
"total_inodes": 29089792
},
{
"path": "/var/lib/docker",
"mount": "/dev/md2 / ext4",
"device": 2306,
"available_bytes": 5723119616,
"available_inodes": 21448040,
"total_inodes": 29089792
}
],
"free_bytes": 5723119616,
"existing_pipeline_minimum_bytes": 5368709120,
"observed_previous_backup_bytes": 175917329,
"same_partition_release_and_backup": true,
"space_guard_satisfied": true,
"current_release_entry_reference": 31179,
"inodes_available_vs_reference": true,
"inode_note": "Observed current release footprint for scale;no new arbitrary inode threshold. Capacity rechecked after fresh backup.",
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
"active_writes": 0
},
"delta": [
{
"path": "resources/js/lib/irpc-special.ts",
"sha256_LF": "a6efbece159a118c5900a6c0d1ebd7b57091b62853c0ad589538546b377aa184"
},
{
"path": "resources/js/lib/irpc-normal.ts",
"sha256_LF": "f21868298d050c72149bcc814858123cb5c7320a93399b30c994b09b5117087c"
},
{
"path": "resources/js/components/simulation-irpc-special.tsx",
"sha256_LF": "da8160778c75935e8b7061ed5722616240189be818e1e04f5711d5b14ec6672d"
}
],
"preservation": {
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"runtime_files_verified": 3,
"preserved_L3_ISPC_FX_runtime_files_verified": 60,
"documentary_files_verified": 31,
"persistent_files_and_env_verified": 369,
"tables_compared": 174,
"changed_tables": {
"cache": {
"before": {
"rows": 106,
"checksum": "716daf400150d9b23980e9c93b3e2f69"
},
"after": {
"rows": 106,
"checksum": "512b1ff328aa6bd8c495408be1ab804f"
}
},
"sessions": {
"before": {
"rows": 17,
"checksum": "7fa218eac3ce56d098b61c1dd270c47d"
},
"after": {
"rows": 20,
"checksum": "8f0c8ef146080d0b1bea08aaaddf0446"
}
}
},
"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_after": {
"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;requestthrottle;identical home-sector cached value with refreshed expiry(HomeController remember10min);no deletedcache",
"sessions": "anonymous sessions from delivery user-agent or exactUA/time correlated with nginx public request;deleted sessions individually expired beyond configured lifetime,normal database session garbage collection(config/session lottery2/100)",
"delta": {
"cache": {
"before_rows": 106,
"after_rows": 106,
"changes": [
{
"key_sha256": "dbb99b7e17f5b4b9bb7a8bdf9350d9b2ae368aaa4bc44593a2522d87617d8461",
"kind": "updated",
"fields": [
"expiration"
],
"key_pattern": "investemoz-cache-{hash}",
"is_queue_restart_key": false,
"expiration_unchanged": false,
"throttle_timer_pair": true,
"same_value_home_cache_expiry_refresh": false
},
{
"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,
"same_value_home_cache_expiry_refresh": false
},
{
"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,
"same_value_home_cache_expiry_refresh": false
}
]
},
"sessions": {
"before_rows": 17,
"after_rows": 20,
"changes": [
{
"key_sha256": "5b744c29cc4e8a7d20f33814b52fa522e2c04dc525e7e82fa1c00e18ba91d528",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": false,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "26b9b547d6b141fc234b6ea7dac11a679e4bcc54771dfccfcd48a0a5e5abd472",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
},
{
"key_sha256": "db3bcd670b9bafa55a0eb8069cdb3687fd0b7af8640fb4dc464c8adda4aaeccb",
"kind": "added",
"fields": [
"id",
"ip_address",
"user_agent",
"payload",
"last_activity"
],
"anonymous_user": true,
"delivery_user_agent": true,
"expired_before_comparison": false,
"session_lifetime_minutes": 120,
"anonymous_public_request_logged": true
}
]
}
},
"business_tables_to_confirm_separately": 172,
"active_data_writes_by_comparison": 0,
"restore_network": "none"
},
"public": {
"status": "installed_delta_verified",
"served_revision": {
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"branch": "main",
"built_at": "2026-10-26T12:39:22.332516+00:00",
"manifest_sha256": "ce3110f77afcaefb5943e50fff77cc8feb34b4c1af20aea1fb64602ffa739264"
},
"manifest_hash_matches": true,
"compiled_delta_markers": {
"IRPC-normal-adjustments/11": [
"assets/project-dossier-BFw3okex.js"
],
"Preparar CBF16 com duodécimos": [
"assets/services-BDq13GEq.js"
],
"CBF16 — duodécimos reutilizados de L6": [
"assets/project-dossier-BFw3okex.js"
],
"Suporte dos duodécimos CBF16": [
"assets/services-BDq13GEq.js"
],
"Manter preparação anual CBF16": [
"assets/services-BDq13GEq.js"
],
"CBF16 por duodécimos — ": [
"assets/project-dossier-BFw3okex.js"
],
"diferença adicional:": [
"assets/project-dossier-BFw3okex.js"
],
"IRPC-normal-adjustments/10": [
"assets/project-dossier-BFw3okex.js"
]
},
"assets": [
{
"file": "assets/project-dossier-document-BE3GlToo.js",
"status": 200,
"sha256": "ff2cddc6e148022c6358910dc7bc3deb002887fc9851c2a46bb2ce69b9c39aaa"
},
{
"file": "assets/project-dossier-BFw3okex.js",
"status": 200,
"sha256": "7d7263d2fb030111d5ea842eb0ee8b98565e9208b6c8ad7dfd4ff58e4a4b1346"
},
{
"file": "assets/simulation-form-BqVD91Ek.js",
"status": 200,
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
},
{
"file": "assets/services-BDq13GEq.js",
"status": 200,
"sha256": "05d13e2e1f454db1f6430de4882468ade75f130b3044f781e68853e4367a1732"
}
],
"simulator_status": 200,
"simulator_entry": "assets/app-C9i2PsI1.js",
"synthetic_private_writes": 0,
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
},
"pipeline": {
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"installed": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0
},
"latest_report": {
"status": "installed",
"commit": "0bd5d495505d512088887efd3dc5c61f645b1647",
"release": "/var/www/investmoz-homologacao/releases/0bd5d495505d512088887efd3dc5c61f645b1647-ad28558b",
"previous_release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
"database_migrations": 0,
"content_imports": 0,
"requested_commits": [
"0bd5d495505d512088887efd3dc5c61f645b1647"
],
"finished_at": "2026-10-26T12:39:25.297008+00:00"
},
"log_file": "1793018162607468190.log",
"summaries": [
"OK (1 test, 3106 assertions)",
"built in 30.45s",
"OK (59 tests, 317 assertions)",
"# tests 1022",
"# pass 1022",
"# fail 0"
],
"log_bytes": 290854
},
"accepted_QA_proofs_reused": {
"frontend_new_tests": 15,
"API_tests": 1,
"API_assertions": 89,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_port": 55441,
"API_identity_guard": true,
"API_transaction_rollback": true,
"API_to_report_cases": 5,
"UI": {
"actualComponent": true,
"explicitOptionalMonthlyDoesNotEditAssets": true,
"cancelPreservesDeliveredAnnual": true,
"missingSupportPreservesNormalReference": true,
"L6TimingEditedAndReused": true,
"quota75LimitedTo60Additional10": true,
"OctoberUses3MonthsAdditional12_50": true,
"exactFraction25over6": true,
"saveRecoveryDownload": true,
"negativeAbsenceDistinct": true,
"finalL8Unknown": true,
"errors": []
},
"Wayfinder_with_form_generated": true,
"typescript_noEmit": true,
"QA_build": true,
"unaffected_functional_suites_repeated": false
},
"demonstrated_example": {
"normal_quota_MZN": "50",
"CBF16_quota_MZN": "75",
"deduction_after_accounting_cap_MZN": "60",
"additional_deduction_MZN": "10",
"colecta_simulated_MZN": "2016",
"final_balance": "L8_not_calculated"
},
"next_compatible_QA_scope": "CBF16 for a resident beginning activity during2026:documented short period and monthly asset timing reused from L6;explicit scope;no cessation/transition/priorquotas/cumulation",
"L7_partial": true,
"L6_and_first_L7_treatments_preserved": true,
"L8_final_settlement_separate": true,
"SGF_affected": false,
"cleanup_executed": false,
"new_private_synthetic_writes_on_active": 0,
"evidence": {
"backup.txt": "08e14e4dc56973954fdafb3ecca8fb586894e6d50188a0c450f714cc69bd442a",
"baseline.txt": "3838c6d8327fe90ef9f5e19dacaf9c2fcdd61f44d95127520a61da09399bd81c",
"capacity-after-backup.txt": "347647d26d78d4da2c21602f7ca9d58dbfdacf987af1a3dda8d13595790e0f58",
"installed-protected.txt": "d7c47360d40bcf1380ba419dbf55cffb84651bf11b3b073547328bfee0c76cb5",
"installed-public-delta.json": "1a882e238d57af6b7d8b551905011e39e8d5ade96852aeddca7e6c2e76df2df8",
"installed-public.txt": "d79a2ebea5691ed85fb432b3b5ec1e68fc83585431b86caa22b8c07f64e6b852",
"integration.txt": "58473f88aadc2f40d0cb1f6cafc4bad5f19a74fd94fced4007150c8bc4e72033",
"manifest-served.json": "ce3110f77afcaefb5943e50fff77cc8feb34b4c1af20aea1fb64602ffa739264",
"operational-delta.txt": "ec794652c7de2e71ee3126d741c330961cde9b123477185c1f9bdb5b530b9afb",
"preflight.txt": "1bb024b6c1d66fc07ae0a181961729d4af532d3c51570c1aec06ca5b0039033a",
"preparation.json": "22c21051049a495d3aa98c83c3faaddad6ddd0200489647bb137cb5c7fdb5bcc",
"progress-1.txt": "4556381c15abcb5c96d6b675f328b6ee9baa20e9e83495becc58106a224dcaed",
"progress-2.txt": "c882b2b1c75e7e462f59b97fb4b4d570d772fb331c4d4676a660d94619b8c778",
"progress-3.txt": "1e02bd58bf4477f0573cecdcec6ec086820401a2628a02df7518a969d7115dc1",
"restore.txt": "7f987653a5a41b4e586bb88247548a3e4ab1ef94080fbef4d448dc2e249e1baa",
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
"status-final.txt": "3353b0b2e359627d9987fff4df576b5c466ba903235d60bbc40feac5d8082efa"
}
}
@@ -0,0 +1,527 @@
{
"status": "CBF16_monthly_QA_prepared_not_installed",
"date": "2026-10-26",
"branch": "codex/irpc-l7-months-qa-20261026",
"QA_workspace_reused_without_deleting_old_proofs": "C:\\laragon\\www\\portal-investidor-irpc-l7-common-qa-20261026",
"installed_baseline": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
"documentation_baseline": "aed020d19eff800ac970ac43b7e0b7a157df5486",
"version": "IRPC-normal-adjustments/11",
"optional_input": "special.acceleration.monthly version1 and explicit reference;no automatic date/value changes",
"delivered_version10_keys_models_histories_preserved": true,
"runtime_delta": {
"resources/js/lib/irpc-special.ts": "a6efbece159a118c5900a6c0d1ebd7b57091b62853c0ad589538546b377aa184",
"resources/js/lib/irpc-normal.ts": "f21868298d050c72149bcc814858123cb5c7320a93399b30c994b09b5117087c",
"resources/js/components/simulation-irpc-special.tsx": "da8160778c75935e8b7061ed5722616240189be818e1e04f5711d5b14ec6672d"
},
"L6_depreciation_engine_unchanged": true,
"cases_recovered": {
"monthly": {
"L6_reference": {
"taxableProfit": {
"numerator": "6310",
"denominator": "1"
},
"taxableBase": {
"numerator": "6310",
"denominator": "1"
},
"colecta": {
"numerator": "10096",
"denominator": "5"
}
},
"L7_profit": {
"numerator": "6300",
"denominator": "1"
},
"L7_base": {
"numerator": "6300",
"denominator": "1"
},
"L7_colecta": {
"numerator": "2016",
"denominator": "1"
},
"additional_deduction": {
"numerator": "10",
"denominator": "1"
},
"status": "calculated",
"monthly": {
"input": {
"version": 1,
"reference": "QA opção de duodécimos desde a entrada emuso,datas/meses do mesmo activoL6"
},
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"source": "CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.",
"assets": [
{
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2026-07-15",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": {
"numerator": "75",
"denominator": "1"
},
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": {
"numerator": "60",
"denominator": "1"
},
"additionalDeduction": {
"numerator": "10",
"denominator": "1"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
]
},
"final_balance": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"fraction": {
"L6_reference": {
"taxableProfit": {
"numerator": "19055",
"denominator": "3"
},
"taxableBase": {
"numerator": "19055",
"denominator": "3"
},
"colecta": {
"numerator": "30488",
"denominator": "15"
}
},
"L7_profit": {
"numerator": "12695",
"denominator": "2"
},
"L7_base": {
"numerator": "12695",
"denominator": "2"
},
"L7_colecta": {
"numerator": "10156",
"denominator": "5"
},
"additional_deduction": {
"numerator": "25",
"denominator": "6"
},
"status": "calculated",
"monthly": {
"input": {
"version": 1,
"reference": "QA opção de duodécimos desde a entrada emuso,datas/meses do mesmo activoL6"
},
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"source": "CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.",
"assets": [
{
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2026-12-15",
"months": 1,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": {
"numerator": "15",
"denominator": "1"
},
"normalQuota": {
"numerator": "25",
"denominator": "3"
},
"acceleratedQuota": {
"numerator": "25",
"denominator": "2"
},
"normalDeduction": {
"numerator": "25",
"denominator": "3"
},
"acceleratedDeduction": {
"numerator": "25",
"denominator": "2"
},
"additionalDeduction": {
"numerator": "25",
"denominator": "6"
},
"applied": true,
"reason": "Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal."
}
]
},
"final_balance": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"missing": {
"L6_reference": {
"taxableProfit": {
"numerator": "6310",
"denominator": "1"
},
"taxableBase": {
"numerator": "6310",
"denominator": "1"
},
"colecta": {
"numerator": "10096",
"denominator": "5"
}
},
"L7_profit": null,
"L7_base": null,
"L7_colecta": null,
"additional_deduction": null,
"status": "indeterminate",
"monthly": {
"input": {
"version": 1,
"reference": ""
},
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"source": "CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.",
"assets": [
{
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2026-07-15",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": null,
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": null,
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": null,
"additionalDeduction": null,
"applied": false,
"reason": "Falta suporte da reutilização dos meses e da opção por duodécimosCBF16 no mapaL6."
}
]
},
"final_balance": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"negative": {
"L6_reference": {
"taxableProfit": {
"numerator": "6310",
"denominator": "1"
},
"taxableBase": {
"numerator": "6310",
"denominator": "1"
},
"colecta": {
"numerator": "10096",
"denominator": "5"
}
},
"L7_profit": {
"numerator": "6310",
"denominator": "1"
},
"L7_base": {
"numerator": "6310",
"denominator": "1"
},
"L7_colecta": {
"numerator": "10096",
"denominator": "5"
},
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"status": "calculated",
"monthly": {
"input": {
"version": 1,
"reference": "QA opção de duodécimos desde a entrada emuso,datas/meses do mesmo activoL6"
},
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"source": "CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.",
"assets": [
{
"id": "accelerated1",
"assetId": "server",
"assetKey": "asset-server",
"description": "Máquina industrial existente QA",
"start": "2026-07-15",
"months": 6,
"taxBasis": {
"numerator": "1000",
"denominator": "1"
},
"normalRate": {
"numerator": "10",
"denominator": "1"
},
"acceleratedRate": null,
"normalQuota": {
"numerator": "50",
"denominator": "1"
},
"acceleratedQuota": null,
"normalDeduction": {
"numerator": "50",
"denominator": "1"
},
"acceleratedDeduction": null,
"additionalDeduction": {
"numerator": "0",
"denominator": "1"
},
"applied": false,
"reason": "Condição negativa documentada;quota normal mantida."
}
]
},
"final_balance": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"absent": {
"L6_reference": {
"taxableProfit": {
"numerator": "6310",
"denominator": "1"
},
"taxableBase": {
"numerator": "6310",
"denominator": "1"
},
"colecta": {
"numerator": "10096",
"denominator": "5"
}
},
"L7_profit": {
"numerator": "6310",
"denominator": "1"
},
"L7_base": {
"numerator": "6310",
"denominator": "1"
},
"L7_colecta": {
"numerator": "10096",
"denominator": "5"
},
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"status": "absent",
"monthly": {
"input": {
"version": 1,
"reference": "QA opção de duodécimos desde a entrada emuso,datas/meses do mesmo activoL6"
},
"period": {
"kind": "calendar",
"from": "2026-01-01",
"to": "2026-12-31",
"reference": "QA doze meses do plano correspondem ao ano civil completo",
"pending": []
},
"source": "CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.",
"assets": []
},
"final_balance": {
"scope": "L8",
"payable": null,
"recoverable": null
}
}
},
"checks": {
"frontend_new_tests": 15,
"API_tests": 1,
"API_assertions": 89,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_port": 55441,
"API_identity_guard": true,
"API_transaction_rollback": true,
"API_to_report_cases": 5,
"UI": {
"actualComponent": true,
"explicitOptionalMonthlyDoesNotEditAssets": true,
"cancelPreservesDeliveredAnnual": true,
"missingSupportPreservesNormalReference": true,
"L6TimingEditedAndReused": true,
"quota75LimitedTo60Additional10": true,
"OctoberUses3MonthsAdditional12_50": true,
"exactFraction25over6": true,
"saveRecoveryDownload": true,
"negativeAbsenceDistinct": true,
"finalL8Unknown": true,
"errors": []
},
"Wayfinder_with_form_generated": true,
"typescript_noEmit": true,
"QA_build": true,
"unaffected_functional_suites_repeated": false
},
"preservation": {
"tracked_files_compared": 1006,
"unchanged": 1003,
"protected_code_schema_config_routes_contract_files": 584,
"original_files": {
"docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
"docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
"docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
"docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
"docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
"docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
"docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
"docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
"docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
"docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
"docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
"docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
"docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
"docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
"docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
"docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
"docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
"docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
"docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
"docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
"docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
"docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
"docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
"docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
"docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
},
"active_writes": 0,
"migrations": 0,
"imports": 0,
"configuration_or_permission_changes": false,
"SGF_affected": false
},
"sources_reused": {
"inventory_files": 8143,
"evidence_receipts": [
"irpc-l6-depreciation-qa-20261026.json",
"irpc-l7-scope-20261026.json",
"irpc-l7-common-qa-20261026.json"
],
"rules": "CBF16 and Decreto72/2013 art3(3)/9;same L6 monthly timing/maximum normal rate/accounting caps",
"broad_research_repeated": false
},
"remaining_scope": [
"short/noncivil fiscal periods and exits",
"lateryears/priorquotas/selected lower rate/decliningmethod",
"rehabilitated/used/revalued/unmappedassets",
"benefitcumulation,cooperative+CBF16 and other L7 families",
"L7 official M20/M22 field transport"
],
"resume_condition": "Case-specific rule/period/accounting/compatibility and existing evidence linked,then only new effects demonstrated;L6 dependency limits its asset only",
"delivery_prepared_only": true,
"remote_capacity_before_next_installation": {
"last_observed": "2026-10-26T13:56:51.412248+02:00",
"historical_available_bytes": 5922545664,
"historical_available_inodes": 21448231,
"existing_pipeline_guard_bytes": 5368709120,
"mandatory_fresh_check_for_build_and_new_backup": true,
"backup_restore_fresh_required": true,
"main_compatibility_recheck_required": true,
"active_release_preserved_until_ready": true,
"no_local_or_SGF_cleanup_dependency": true
},
"L7_partial": true,
"L8_final_balance_separate": true,
"evidence_directory": "outputs/irpc-l7-months"
}
@@ -0,0 +1,309 @@
{
"status": "QA_ready_not_installed",
"date": "2026-10-26",
"branch": "codex/irpc-l7-start-period-qa-20261026",
"installed_baseline": "0bd5d495505d512088887efd3dc5c61f645b1647",
"documentation_baseline": "eccd95f9e79c871b592839aceca5f968440d067d",
"scope": "CBF16:resident start of activity,short complete-month period ending2026-12-31,new supported asset entering inperiod,constant maximum table rate,no priorquotas/exit/cumulation",
"version": "IRPC-normal-adjustments/12",
"explicit_optional_input": "acceleration.monthly.startPeriod version1/reference;without it versions10/11 retain keys/models/history",
"runtime_delta": {
"resources/js/lib/irpc-special.ts": "052bd703cdfd7fbb10ea8089146d5e52ea247d612ce557b1e2c9c20730600261",
"resources/js/lib/irpc-normal.ts": "290d7d66621668d2b684850729c57c0435cce144acf0704f9fd9e1d4a6d491f3",
"resources/js/components/simulation-irpc-special.tsx": "6f6b203062df36fedbdfa341bba8b8aa7796d2f3169f1bd84395ada8f71fd749"
},
"reused_L6_period_fx_and_depreciation_engines_unchanged": true,
"cases_recovered": {
"start": {
"period": {
"from": "2026-07-01",
"to": "2026-12-31",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "10",
"denominator": "1"
},
"L7_profit": {
"numerator": "3120",
"denominator": "1"
},
"L7_base": {
"numerator": "3120",
"denominator": "1"
},
"L7_colecta": {
"numerator": "4992",
"denominator": "5"
},
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"fraction": {
"period": {
"from": "2026-12-01",
"to": "2026-12-31",
"pending": []
},
"L6_profit": {
"numerator": "1565",
"denominator": "3"
},
"L6_base": {
"numerator": "1565",
"denominator": "3"
},
"L6_colecta": {
"numerator": "2504",
"denominator": "15"
},
"status": "calculated",
"additional_deduction": {
"numerator": "5",
"denominator": "3"
},
"L7_profit": {
"numerator": "520",
"denominator": "1"
},
"L7_base": {
"numerator": "520",
"denominator": "1"
},
"L7_colecta": {
"numerator": "832",
"denominator": "5"
},
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"missing": {
"period": {
"from": "2026-07-01",
"to": "2026-12-31",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "indeterminate",
"additional_deduction": null,
"L7_profit": null,
"L7_base": null,
"L7_colecta": null,
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"negative": {
"period": {
"from": "2026-07-01",
"to": "2026-12-31",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "calculated",
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"L7_profit": {
"numerator": "3130",
"denominator": "1"
},
"L7_base": {
"numerator": "3130",
"denominator": "1"
},
"L7_colecta": {
"numerator": "5008",
"denominator": "5"
},
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
},
"absent": {
"period": {
"from": "2026-07-01",
"to": "2026-12-31",
"pending": []
},
"L6_profit": {
"numerator": "3130",
"denominator": "1"
},
"L6_base": {
"numerator": "3130",
"denominator": "1"
},
"L6_colecta": {
"numerator": "5008",
"denominator": "5"
},
"status": "absent",
"additional_deduction": {
"numerator": "0",
"denominator": "1"
},
"L7_profit": {
"numerator": "3130",
"denominator": "1"
},
"L7_base": {
"numerator": "3130",
"denominator": "1"
},
"L7_colecta": {
"numerator": "5008",
"denominator": "5"
},
"L8_final": {
"scope": "L8",
"payable": null,
"recoverable": null
}
}
},
"checks": {
"new_frontend_tests": 9,
"API_tests": 1,
"API_assertions": 97,
"API_database": "simulator_fiscal_delta_20261021_test",
"API_host": "127.0.0.1",
"API_port": 55441,
"API_transaction_rollback": true,
"wayfinder_with_form": true,
"typescript": true,
"isolated_build": true,
"HTML_financial_dossier_from_5_API_recoveries": true,
"actual_component": {
"actualComponent": true,
"explicitStartOptionAndCancel": true,
"reuseL6PeriodEvidenceExplicit": true,
"assetsAndPeriodUnchanged": true,
"missingPreservesNormal1001_60": true,
"sixActualMonths50Normal75Accelerated60Cap10Additional": true,
"simulatedColecta998_40": true,
"exactFraction5over3": true,
"saveRecoveryDownload": true,
"negativeAbsenceDistinct": true,
"L8FinalUnknown": true,
"errors": []
}
},
"preservation": {
"protected_code_schema_config_routes_contract_files": 584,
"original_files": {
"docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
"docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
"docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
"docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
"docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
"docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
"docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
"docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
"docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
"docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
"docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
"docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
"docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
"docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
"docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
"docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
"docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
"docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
"docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
"docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
"docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
"docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
"docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
"docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
"docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
"docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
"docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
"docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
},
"prior_result_and_entire_history_preserved": true,
"plan_assets_and_other_tax_books_unchanged": true,
"active_migrations": 0,
"active_private_writes": 0,
"SGF_TEMPO_touched": false
},
"sources_reused": [
"CBF3/9/10/16 accepted APIEX compilation pp66-68/72",
"CIRPC7(4) accepted shortperiod implementation",
"Decreto72/2013 art3(3)/9(3),accepted source inventory8143"
],
"remaining_code": [
"other autonomous expense origins/parcels",
"mixed/withheld cooperative income and other CIRPC9-14 entities",
"CBF16 cessation/transition/noncivil/previousquotas/exit/lateryears/lowerquota/othercategories/methods/cumulation",
"capitalgains61-A and specialoperations54-56/41-A",
"CBF17-19 and potential15 entitlement;annualuseL8",
"sector/territorial/specificregimes",
"official L7 M20/M22 transport"
],
"document_conditions": [
"classification/parcels/period evidence",
"statute/recognition required by disposition or exception",
"specific normativeperiod and cumulation order/limits",
"form edition/field/fraction representation"
],
"remote_capacity_before_future_installation": {
"fresh_space_inodes_build_backup_measurement": true,
"main_compatibility_recheck": true,
"fresh_backup_restore": true,
"keep_active_until_ready": true
},
"L6_operational_delimited": true,
"L7_partial": true,
"L8_final_balance_separate": true,
"evidence_directory": "outputs/irpc-l7-start-period"
}
@@ -2523,7 +2523,7 @@ As estimativas são **horas de trabalho técnico**, não calendário nem mediç
| 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 | Disponível5aaf1a56:percurso normal demonstrado atécolecta,períodos/moedas e preparação parcialM20/M22 | Operacional no âmbito demonstrado por decisãoTempo26/10;limitações explícitas;5grupos código+5documentais preservados;sem conclusão integral | Plano financeiro,dados comuns,activos/livros e histórico;retenções/pagamentos/créditos anuaisL8 | Pendências bloqueiam só os casos dependentes;L7/L8 próprios | Estimativa inicial48–80h;saldo não reestimado |
| L7 — IRPC: tratamentos específicos | e07f89da instalado,reconfirmado26/10:main/revisão/delta6QAab2ff2fd coincidem | L7parcial;7grupos código/4documentais preservados. PróximoQA:CBF16 com duodécimos,activo novo suportado,método constante eano civil2026 | Reutilizar qualificação,activos/taxas eperiodizaçãoL6;sem benefício por localização | Provar só novos efeitos eguarda/recuperação/relatório;limites contabilístico/fiscal;sem repetir instalação;L8 separado | Estimativa inicial48–80h;saldo não reestimado |
| L7 — IRPC: tratamentos específicos | 632dc069 instalado,incluindo início12/ba83afe7 e cessação/quotas13;0bd5d495 preservado | L7parcial;cumulações e restantes casos/dependências concretos mantidos | Activos/períodos/saldosL6 reutilizados;75−50=25 adicionais,15 recuperados já nos75;sem consumo oficial | Retomar combinação por norma/parcela/ordem/limites;futuras entregas com capacidade/backup/restauro frescos;L8 conserva saldo final | Estimativa inicial48–80h;saldo não reestimado |
| 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 |
| L10 — IRPS: retenção mensal e líquido | Entrada IRPS, custos salariais e escalões anuais documentais | Tabela mensal própria, remunerações/benefícios, situação pessoal relevante, retenção, salário líquido e contribuição ligada a L9 | Mesmo trabalhador/folha salarial, pagamentos e retenções | Tabela mensal do período, residência e condições familiares necessárias; não dividir escalões anuais por12 | 40–64 h |
@@ -6437,3 +6437,108 @@ Conferência autenticada por leitura em `2026-10-26T13:56:51.412248+02:00` (Afri
**Próximo conjunto delimitado para implementaçãoQA:CBF16 com duodécimos.** Reutilizar activos,tabela/taxa normal máxima,método constante,qualificaçãoCBF e periodizaçãoL6 existentes. Primeiro caso:exercício anual civil2026 com entrada em uso durante o ano;imóvel novo do projecto ou máquina industrial/agro-industrial já suportada;sem quotas anteriores,saída ou cumulação de outros benefícios. Ligar a quota mensalL6 ao incrementoCBF16,limitando ao contabilizado/saldo fiscal e mostrando apenas a diferença adicional. Demonstrar condição satisfeita,negativa,informação em falta e ausência declarada,cálculo→gravação→recuperação→relatório,efeitos no lucro/base/colecta e conservação dos históricos. Este conjunto está apenas delimitado:não é novo cálculo instalado.
Degressivo,reabilitados/usados/reavaliados,quotas anteriores e cumulação cooperativa+CBF16 continuam nos casos próprios. O saldo anterior de sete grupos de código e quatro dependências documentais permanece na mesma matriz,com exemplos/condições de retoma;nenhuma pendência foi apagada. Documento individual em falta limita só o activo/caso dependente. Localização não concede benefício. **L6 operacional delimitado;L7 parcial;retenções,pagamentos,créditos anuais e saldo final emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-server-state-20261026.json`.
## 26/10/2026 — CBF16 com duodécimos demonstrado em QA
**QA preparado, sem instalação.** O portal mantém `e07f89da`, incluindo o primeiro conjuntoL7 `ab2ff2fd`. Este incremento implementa a ligação CBF16–duodécimos delimitada no recibo `irpc-l7-server-state-20261026.json`. L6 permanece operacional no âmbito aceite;L7 continua parcial;L8 conserva retenções,pagamentos,aplicação anual de créditos e saldo final a pagar/recuperar. SGF TEMPO não foi afectado.
**Reutilização e condições:** a opção «Preparar CBF16 com duodécimos» é explícita e conserva os activos,datas,valores e restantes escolhas. O utilizador confirma a reutilização dos meses e da opção mensal do mapaL6. Sem essa opção,os livros/resultados entregues permanecem na fotografia10,com a mesma chave e valores. Com ela,a fotografia11 guarda a preparação,o cálculo e o histórico10 anterior. É possível manter a preparação anual sem alterar automaticamente activos ou apagar resultados anteriores.
Recorte demonstrado:exercício anual civil2026,activo novo já suportado emL6,imóvel novo afecto ao projecto ou máquina industrial/agro-industrial das categorias correspondidas,método constante pela taxa normal máxima,entrada emuso durante2026,sem saída,quotas anteriores ou cumulação de outros benefícios. Mantêm-se prova das condiçõesCBF3/9,reconhecimento10 quando exigido (ou excepção identificada),afectação e período. Localização/sector não activam benefício. Os meses calculados por L6 incluem o mês da entrada emuso;não se introduz cálculo diário nem uma segunda agenda de amortização.
**Cálculo:** usa o motor de amortizaçõesL6 existente,com taxa normal×1,5 e os mesmos duodécimos/12. Mantém base depreciável,terreno/residual,limite contabilístico e saldo fiscal. L7 aplica apenas a diferença entre a dedução fiscal normal e a acelerada;não cria outro activo ou uma segunda depreciação contabilística. Os outros activos do mapa conservam a quota normal. O resultado de referênciaL6 e o resultado apósL7 são apresentados separadamente.
| Caso sintético | Valores demonstrados |
| --- | --- |
| Máquina existente:base1000,taxa normal10%,entrada15/07/2026,6duodécimos,contabilizado60 | Quota normal50;quotaCBF16 75;dedução limitada60;diferença adicional10MZN. Lucro/base de referência6310 e colecta2019,20;apósL7 lucro/base6300 e colecta2016,00MZN. Saldo finalL8indeterminado. |
| Entrada emOutubro,3duodécimos | Quota normal25;quotaCBF16 37,50;diferença12,50 quando o contabilizado a suporta. |
| Entrada emDezembro,1duodécimo | Quota normal25/3,quotaCBF16 25/2;diferença exacta25/6MZN,sem arredondamento fiscal presumido. Aproximação de apresentação e valor exacto permanecem distintos. |
| Imóvel novo já classificado emL6 | Terreno/residual e base são reutilizados;taxa e meses aplicam-se à mesma base. O exemplo confirma quota40→60,limitada50,com diferença10. |
| Falta de suporte da opção/datas/condições | CBF16 fica indeterminado;entradas e referênciaL6 conhecidas conservadas. Não substituir desconhecido por zero. |
| Condição negativa / ausência declarada | Estados distintos e documentados;nenhuma taxaCBF16 aplicada à parcela negativa;ausência produz efeito zero justificado. |
**Demonstração executada:**15testes dirigidos novos,com comparação exacta dos três livros10 aceites (despesa autónoma,cooperativa e amortização anual),sem repetir as suas suites funcionais. API privada:1teste/89asserções,cinco casos mensal/fracção/falta/negativa/ausência,em `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441,guarda de identidade/base e transacção com rollback. Cálculo→gravação→recuperação→HTML e dossier financeiro conferidos a partir dos casos recuperados,com plano/activos/históricos conservados. Recalcular não acumula a diferença adicional. Alterar a data invalida a fotografia corrente sem alterar a anterior.
UI do componente real:opção explícita/cancelamento,alteração das datas e opção mensal no activoL6,informação em falta,6→3duodécimos,limite75→60,diferença10,fracção25/6,gravação/recuperação local e download do relatório;sem erros de página. Esta prova local é distinta da API. Wayfinder`--with-form`,TypeScript e buildQA passaram. Não houve escrita no activo,migração,importação,activação por consulta de fonte ou nova ronda das provas não afectadas deL3/ISPC/câmbio/L5/L6. O motor de amortizaçõesL6 não foi alterado.
**Saldo e condição de retoma:** este recorte cobre duodécimos em exercício anual civil2026;períodos fiscais curtos/autorizados distintos,saídas,anos posteriores,quotas anteriores,quota escolhida inferior à máxima,degressivo,reabilitados/usados/reavaliados e cumulações mantêm correspondência própria. Retomar cada caso quando a respectiva regra/período/contabilização e compatibilidade estiverem ligados ao activo/documentos já existentes,e demonstrar só o seu efeito novo. Uma pendênciaL6 afecta apenas o activo dependente. Os restantes grupos do saldoL7 e os camposM20/M22 ainda sem correspondência mantêm-se;este lote não preenche campos oficiais por aproximação nem conclui o IRPC.
**Entrega agrupada:** os casos compatíveis mensal/fracção/negativa/ausência/informação insuficiente acompanham o mesmo candidato. A capacidade remota de5,52GiB/21448231inodes observada às13:56:51 de26/10 é histórica,não confirmação para nova instalação. Antes da próxima entrega,medir outra vez espaço/inodes na partição de release+backup+temporários,confrontar com o limiar existente5GiB e o backup/carga dessa execução,conferir o main então actual e executar backup/restauro fresco. Manter a versão activa até a nova ficar pronta. Não executar limpeza local ou doSGF para substituir esse controlo remoto.
Fontes e inventário8143 reutilizados dos cotejos aceitesCBF16 eDecreto72/2013art9;originais preservados,sem pesquisa transversal repetida. Recibo:`docs/investmoz/simulations/irpc-l7-months-qa-20261026.json`;provas locais:`outputs/irpc-l7-months/`. Reprodução dirigida: `node --test tests/frontend/irpc-special-months.test.mjs`; `php tools/irpc-special-months-qa.php routes`; `php tools/irpc-special-months-qa.php test`; `tsc --noEmit`; build com `INVESTMOZ_QA_BUILD=1`.
## 26/10/2026 — CBF16 com duodécimos instalado pelo Git
Instalado `0bd5d495505d512088887efd3dc5c61f645b1647`,com `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd` preservado como versão anterior. O main não apresentava divergência;integração por fast-forward sem alterações de código à candidataQA. Backup fresco `2026-10-26T12:34:42Z` e restauro isolado sem rede/55441:174tabelas e369ficheiros/configuração conferidos. Capacidade medida imediatamente antes:5.50GiB e21448052inodes;depois do backup:5.33GiB,acima do limiar existente5GiB,com inodes disponíveis confrontados com a carga observada. Sem limpeza local/remota ou intervençãoSGF.
Conferidos3ficheiros do delta,60ficheiros de execução protegidos e31originais. Schema,roles/grants e permissões iguais;172tabelas de negócio mantêm o backup,cache/sessões reconciliadas com eventos operacionais/acessos públicos. Revisão/manifest,marcadoresCBF16 e suporte10,assets e simuladorHTTP200 conferidos. Sem migrações,importações,recálculo de históricos ou escrita privada sintética no activo. Reutilizadas as provasQA15testes/API89/UI/tipos/build;apenas os controlos automáticos obrigatórios do procedimentoGit e a conferência do delta instalado.
O exemplo mantém quota normal50,quotaCBF16 75 limitada ao contabilizado60:dedução adicional**60−50=10MZN**,não75 nem uma segunda amortização. Lucro/base apósL7 6300 e**colecta simulada2016MZN**;saldo final a pagar/recuperar por determinar emL8. Os tratamentos de despesas autónomas,cooperativas abrangidas e amortizações anuais anteriores permanecem disponíveis,com fotografias/históricos conservados. O estadoQAsem instalação é histórico para este incremento.
**SaldoL7:**CBF16 anual com duodécimos entregue;continuam fora deste recorte períodos curtos/não civis,saídas,anos/quotas anteriores,métodos/categorias não correspondidos,cumulações e restantes famílias/transportesM20M22 já discriminados na mesma matriz. Retoma por regra/período/contabilização e compatibilidade do caso;documentos em falta só limitam o dependente. O próximo conjunto a executar emQA é**CBF16 em período curto por início de actividade de residente em2026**,reutilizando tipo/período e mesesL6,sem anualizar base ou taxa. Cessação,transição e outras extensões conservam âmbito próprio. L6operacional delimitado;L7parcial;localização não concede benefício;L8conserva liquidação final. Recibo:`docs/investmoz/simulations/irpc-l7-months-delivery-20261026.json`.
## 26/10/2026 — CBF16 no início de actividade demonstrado em QA
**QA preparado, sem instalação.** O portal mantém `0bd5d495`, com duodécimos anuais e os tratamentos anteriores preservados. Este incremento cobre apenas CBF16 num período curto por início de actividade de residente em2026,com meses completos até31/12. Reutiliza período,tipo,suporte e activosL6,sem anualizar resultados. Não altera o motor cambial/de amortizaçõesL6 nem volta a pesquisar fontes/provas aceites.
A preparação é explícita dentro dos duodécimosCBF16. Pode reutilizar o suporte já declarado emL6 por acção do utilizador,sem modificar datas,activos ou qualificação. Exige condiçõesCBF3/9,reconhecimento10 quando aplicável ou excepção identificada,afectação do activo e suporte do período. Activo novo já correspondido,entrada emuso no período,método constante pela taxa normal máxima,sem quotas anteriores,saída ou cumulação. A localização não activa benefícios. Sem a nova opção,as fotografias10/11 mantêm chaves e resultados;com ela,a fotografia12 conserva o resultado11 e todo o histórico anterior.
| Caso novo | Efeito demonstrado |
| --- | --- |
| Início1Julho;máquina com entrada15Julho,base1000,taxa10%,contabilizado60 | 6mesesL6;quota normal50,acelerada75,limitada60:dedução adicional10MZN. Lucro/baseL6 3130→L7 3120;colecta simulada1001,60→998,40MZN. Saldo finalL8indeterminado. |
| InícioOutubro / Dezembro | 3 /1meses efectivos;sem anualização. Dedução adicional5 /5/3MZN,com fracção exacta e aproximação de apresentação separadas. |
| Suporte em falta | SóCBF16 fica indeterminado;referênciaL6 conhecida e entradas conservadas. |
| Condição negativa / ausência declarada | Estados distintos e justificados;efeito zero identificado,sem taxa acelerada aplicada à parcela negativa. |
Provas novas dirigidas:9testes;API privada1teste/97asserções emQA isolada127.0.0.1:55441/base `simulator_fiscal_delta_20261021_test`,com guarda e transacção/rollback. Cinco casos passaram cálculo→gravação→recuperação→HTML e dossier financeiro. Comparação exacta do resultado11 aceite e conservação de todo o histórico,plano,activos e outros livros;recalcular não acumula deduções. Interface real demonstrou preparar/cancelar,reutilizar suporteL6,pendência,limites,fracções,guardar/recuperar e exportar,sem erros. Wayfinder`--with-form`,TypeScript e buildQA passaram. Conferidos584ficheiros protegidos e31originais sem alteração;nenhuma migração/importação/escrita privada no activo. SGF TEMPO separado.
**Saldo concretoL7 — código:**(1)outras origens/parcelas de despesas autónomas;(2)cooperativas mistas/retidas e demais entidades9–14;(3)CBF16 cessação/transição/períodos não civis,saídas,quotas/anos anteriores,quota inferior,métodos/categorias e cumulações;(4)mais-valias61-A/operações54–56/41-A;(5)CBF17–19 e direito potencial15;(6)regimes sectoriais/territoriais;(7)transporteL7M20/M22. A extensão de início de actividade sai deste saldo apenas no recorteQA acima;cessação é um próximo candidato compatível,reutilizando o períodoL6,com regra/quotas/saída próprias a demonstrar antes de se declarar suportada.
**Documentos por caso — exemplos/retoma:**despesa36g sem qualificação61(4)→associar natureza/parcela/período;projecto sem reconhecimento10→instrumento ou norma de excepção exigida;cumulação cooperativa+CBF16→disposição aplicável,ordem e limites;efeitoL7 sem campoM20/M22→exemplar/edição/campo e representação das fracções. Não são novos aprovadores ou revalidações genéricas. A dúvida limita o caso/campo dependente;as demais provas permanecem válidas.
Entrega agrupada preparada para os cinco casos compatíveis,sem instalação deste incremento. Na futura entrega:medir novamente espaço/inodes/carga de compilação e backup,conferir o main então actual e executar backup/restauro fresco,mantendo a versão activa até a nova ficar pronta. O controlo de5,50GiB antes/5,33GiB após backup desta entrega0bd5d495 é histórico,não garantia futura. **L6 operacional delimitado;L7 parcial;colecta distinta do saldo final deL8.** Recibo:`docs/investmoz/simulations/irpc-l7-start-period-qa-20261026.json`;provas:`outputs/irpc-l7-start-period/`. Reprodução dirigida:`node --test tests/frontend/irpc-special-start-period.test.mjs`;`php tools/irpc-special-start-period-qa.php routes`;`php tools/irpc-special-start-period-qa.php test`;`tsc --noEmit`;build com `INVESTMOZ_QA_BUILD=1`.
### Porquê investir — fundo azul, 26/10/2026
Pedido expresso da Tempo: ajustar o fundo para azul bebé ou azul IBM. Escolha de apresentação: IBM Blue 20, #D0E2FF, da paleta oficial https://www.carbondesignsystem.com/building-blocks/foundations/color/code. Substitui #BBC0C6 apenas no bloco dos cinco parágrafos; a decisão anterior fica no histórico. Inventário do delta: mantidos texto escuro, geometria compacta, cinco parágrafos editoriais, 12 anteriores, sete cartões, 15 links e a disposição aprovada, sem perda confirmada. Sem alteração de schema, dados, configuração, permissões ou cálculos. Registo em V2-01 na matriz existente. Verificação deste azul concluída: build e diff passaram; prévia isolada em 1440 e 390 px confirmou rgb(208, 226, 255), equivalente a #D0E2FF, sem alteração da geometria, 17 parágrafos ou 15 links e sem transbordo. Captura de computador inspeccionada. Recibo em outputs/why-invest-blue-20261026/layout.json. Sem prova do activo; alteração local sem publicação.
## 26/10/2026 — CBF16 cessação e quotas anteriores: entrega agrupada preparada em QA
**QA, sem instalação.** O conjunto inclui `ba83afe7` (início de actividade) e acrescenta cessação da actividade em2026 e quotas anteriores documentadas de activos que entraram emuso em2025. A versão do portal comunicada permanece `0bd5d495`;não se voltou a instalar ou a conferir remotamente o activo nesta passagem. O main entretanto avançou para `ae0d74bb`;a candidata incorpora a alteração visual de «Porquê investir»,a nota do manual e a linhaV2-01 da matriz,sem perda das notas fiscais. Nenhum ficheiro dessa alteração foi substituído pelo incrementoL7.
**Condições e reutilização.** Preparação opcional13,distinta de início12 e do recorte mensal11,sem alteração das chaves/resultados anteriores. Usa sujeito/período/activos/quotas e saldosL6. CBF3/9/10/16,Decreto72/2013 art3(3),9(1–3) e10 eCIRPC7(4):condições/afectação/reconhecimento ou excepção identificados,ano civil2026 ou cessação de residente desde1Janeiro até ao último mês completo,contabilização/saldos reconciliados,método constante pela taxa normal máxima,duodécimos desde entrada emuso e ausência de cumulação. Localização não concede benefício.
O recorte de implementação admite activos novos a custo histórico com entrada2025/2026. A selecção destes anos é coberturaQA,não um limite legal inventado para os restantes activos. Valores anteriores contabilísticos,fiscais,parcela temporariamente tributada e suporte são reutilizados deL6;não se recalculam taxas/benefícios de exercícios passados. Uma entrada em2026 com quotas anteriores positivas fica por reconciliar. Informação em falta não é zero;condição negativa e ausência declarada permanecem distintas.
**Cessação não é saída do activo.** O termo do período limita os meses efectivos,sem preencher transmissão/inutilização por presunção. Uma saída de activo documentada dentro do período reutiliza a dataL6 e exclui o mês do evento,conformeart9(2);sem ela,reutiliza os meses do período. Este ramo só apura a amortização,não calcula uma mais-valia ou operação de transmissão por aproximação.
| Caso sintético novo | Efeito no cálculo |
| --- | --- |
| Cessação30Junho,activo emuso desdeJaneiro2026,sem quotas anteriores,contabilizado60 | 6meses;quota normal50,acelerada75 limitada60;diferença adicional10MZN. Lucro/base3130→3120;colecta simulada1001,60→998,40MZN. Sem saída do activo presumida. |
| Mesmo período,activo2025;quotas anteriores contabilísticas150,fiscais100,parcela recuperável50 | Dedução normal50;acelerada75,incluindo15 de parcela anterior. Diferença adicional25MZN,sem somar novamente os15. Saldo anterior aritmético50→35;saldo fiscal após dedução850→825. Lucro/base3130→3105;colecta simulada1001,60→993,60MZN. Os saldos declarados150/100/50 permanecem intactos. |
| Ano civil2026,mesmos saldos anteriores,contabilizado120 | Dedução100→150,incluindo30 de parcela anterior;diferença adicional50MZN e saldo anterior aritmético20. Lucro/base6260→6210;colecta simulada2003,20→1987,20MZN. |
| CessaçãoJunho com saída do activo documentada20Junho | 5meses;quota normal125/3 eacelerada125/2;diferença125/6MZN. Fracção exacta preservada,sem arredondamento fiscal presumido. |
| Saldo fiscal remanescente20 ou contabilização/parcela anterior insuficiente | Ambos os cálculos respeitam os mesmos limites;dedução adicional pode ser zero,sem exceder a base nem consumir saldos oficiais. |
| Suporte em falta / condição negativa / ausência declarada | Estados e efeitos separados;uma falta de suporteCBF16 mantém a referênciaL6 conhecida e limita apenas o benefício dependente. Um saldoL6 desconhecido limita também os cálculos que dele dependem. |
**Provas novas:**11testes dirigidos,API privada1teste/123asserções,sete casos cálculo→gravação→recuperação→HTML/dossier financeiro. BaseQA `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441,guarda de identidade e transacção com rollback. Comparação exacta do resultado12 aceite,conservação de todo o histórico,activos,plano e outros livros;recalcular não acumula a dedução nem reduz os saldos declarados. Interface real:preparar/cancelar,preencher apenas os suportes novos,pendência,recuperação15/saldo35,saída5meses/fracção,gravação/recuperação/exportação e ausência/negativa,sem erros. Wayfinder`--with-form`,TypeScript ebuildQA passaram;build/tipos conferidos também após incorporar o main. Reutilizadas,sem repetir,as provas aceites de `ba83afe7` e dos restantes percursos. MotoresL6 de amortizações/periodização/câmbio,schema,configuração,permissões,originais e provas anteriores preservados. SGF TEMPO separado;nenhuma escrita no activo,migração ou importação.
**Saldo concreto — código:**(1)outras origens/segregações de despesas autónomas;(2)cooperativas mistas/retidas e demais entidades9–14;(3)CBF16 com activos anteriores a2025,períodos parciais/não civis/transição,saídas fora do recorte,quota inferior,métodos/categorias e cumulações;(4)mais-valias61-A/operações54–56/41-A;(5)CBF17–19 e direito potencial15;(6)regimes sectoriais/territoriais;(7)transporteL7M20/M22. O recorte agora demonstrado deixa de figurar como integralmente por implementar,mas permanece apenas emQA. Retomar extensõesCBF16 com a regra temporal/método/base ligada aos activos e demonstrar o efeito novo;retomar mistos/cumulações com segregação,ordem e limites,sem pesquisar novamente o que já está aceite.
**Dependências documentais por caso:**natureza/parcela/período da operação→associar os factos e o exercício;reconhecimentoCBF10→instrumento ou excepção exigida;quotas anteriores150/100/50 sem suporte→reconciliar a parcela temporariamente tributada,sem incluir exclusões permanentes;cumulação→disposição/ordem/limites aplicáveis;campoM20/M22→exemplar/edição/campo e representação exacta. A falta limita só o caso/campo dependente,não exige aprovadores ou revalidação genérica de fontes.
**Entrega agrupada preparada:**início12 de `ba83afe7` mais cessação/quotas anteriores13,com as provas aceites e novas separadas no mesmo pacote. Antes de instalar,voltar a conferir main,espaço/inodes/carga de compilação ebackup,executar backup/restauro fresco e manter a versão activa até a nova ficar pronta. **L6 operacional delimitado;L7 parcial;colecta simulada não é saldo final:retenções,pagamentos,créditos anuais e saldo a pagar/recuperar permanecem emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-cessation-prior-qa-20261026.json`;provas:`outputs/irpc-l7-cessation-prior/`. Reprodução só do delta:`node --test tests/frontend/irpc-special-cessation-prior.test.mjs`;`php tools/irpc-special-cessation-prior-qa.php routes`;`php tools/irpc-special-cessation-prior-qa.php test`;`tsc --noEmit`;build com `INVESTMOZ_QA_BUILD=1`.
## 26/10/2026 — CBF16 início, cessação e quotas anteriores instalado pelo Git
**Instalado `632dc06930d6b4f1b012feb3b4daa3b1cfc53f39`,incluindo `ba83afe7`.** Entrega única do início de actividade,cessação e quotas anteriores no âmbitoQA demonstrado. `0bd5d495` permanece como release anterior;históricos e provas aceites conservados. O main `ae0d74bb` e a alteração visual de «Porquê investir» foram incorporados,preservando texto/cor/geometria e a linhaV2-01 da matriz. Sem instalação separada dos dois incrementos.
**Capacidade e recuperação:**a primeira medição confirmou 4.32GiB,abaixo do mínimo existente5GiB,e a falha anteriorae0d74bb por falta de espaço;versão activa preservada. Conferidas ausência de instalaçõesnpm e de ficheiros abertos,só a cache regenerável `/root/.npm/_cacache` foi limpa pelo comando npm próprio. Recuperados 2.82GiB;32logs npm anteriores e `_npx` preservados. Sem apagar releases,backups,dependências dos projectos,provas únicas ou ficheirosSGF. Nova medição:7.15GiB e21431150inodes;após backup:6.99GiB,acima do limiar5GiB,com capacidade de backup/compilação e escala de inodes conferidas. O limiar do instalador não foi reduzido.
Backup fresco `2026-10-26T13:29:24Z`:174tabelas e369ficheiros/configuração conferidos;restauro isolado sem rede/porta55441 com174checksums iguais. Schema,roles/grants e permissões mantidos. Só depois destas guardas,integraçãoGit por fast-forward sem forçar o histórico. A release anterior ficou activa até a nova estar pronta. Revisão/manifest servidos,marcadores12/13 e restantes leitores,assets e simuladorHTTP200 conferidos após instalação. Três ficheiros do delta fiscal,60ficheiros protegidos/enquadrados no main e31originais correspondem ao destino preparado. Dados de negócio comparados com o backup;cache/sessões reconciliadas com eventos operacionais/acessos públicos. Sem migrações,importações ou escrita privada sintética no activo.
**Resultado demonstrado preservado:**dedução normal50MZN→acelerada75MZN;**75−50=25MZN adicionais**. Os15MZN recuperados de quotas anteriores **já estão incluídos nos75**,não são somados novamente. Saldo anterior aritmético35MZN;valores declarados150/100/50 e históricos mantidos,sem consumo de saldos oficiais. Lucro/base3105MZN e**colecta simulada993,60MZN**;saldo final a pagar/recuperar permanece indeterminado emL8. Cessação da actividade não presume transmissão/inutilização dos activos;saída só quando documentada no mapa existente.
Reutilizadas as provas aceites:início12 (9testes/API97) e cessação/quotas13 (11testes/API123),UI real,gravação/recuperação/relatórios,tipos/build. Não se repetiram as respectivas suites por iniciativa desta entrega;apenas os controlos automáticos obrigatórios do procedimentoGit e a conferência do delta instalado. Os motoresL6 de amortizações,periodização e câmbio mantêm-se;L3,ISPC,L5 e demais provas aceites não foram reabertos. Recibo:`docs/investmoz/simulations/irpc-l7-grouped-delivery-20261026.json`;provas locais:`outputs/irpc-l7-grouped-delivery-20261026/`.
**SaldoL7 e próxima retoma:**continuam próprios as cumulações (por exemplo cooperativa+CBF16:identificar disposição,parcela elegível,ordem e limites antes de combinar),outras origens/segregações de despesas autónomas,cooperativas mistas/retidas e demais entidades,extensõesCBF16fora dos anos/períodos/métodos/categorias demonstrados,mais-valias61-A/operações54–56/41-A,CBF17–19/direito potencial15,regimes sectoriais/territoriais e transporteM20/M22. Mantém-se a separação entre código por implementar e documentos por caso:natureza/parcela/período,reconhecimento ou excepção exigida,saldos anteriores temporariamente tributados,norma/ordem/limites de cumulação e edição/campo/fracção. Uma falta limita só o caso/campo dependente;sem pesquisa transversal repetida ou aprovador genérico. **L6 operacional delimitado;L7 parcial;L8 conserva retenções,pagamentos,créditos anuais e saldo final.** Cada futura entrega volta a medir capacidade e executar backup/restauro fresco.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -1,4 +1,4 @@
import {irpcSpecialVersion,validateSpecial,calculateSpecial,specialReportRows,specialDependency,type SpecialInput,type SpecialModel} from './irpc-special.ts';
import {irpcSpecialVersion,irpcSpecialMonthlyVersion,irpcSpecialStartPeriodVersion,irpcSpecialCessationPriorVersion,specialCalculationVersion,validateSpecial,calculateSpecial,specialReportRows,specialDependency,type SpecialInput,type SpecialModel} from './irpc-special.ts';
import {normalFormPreparationVersion,validateNormalFormPreparation,prepareNormalForms,normalFormPreparationReport,type NormalFormPreparationInput,type NormalFormPreparationModel} from './irpc-normal-form-preparation.ts';
import {normalPeriodFxVersion,validateNormalPeriodFx,mapNormalPeriodFx,normalPeriodFxDependency,normalPeriodFxReport,type NormalPeriodFxInput,type NormalPeriodFxModel} from './irpc-normal-period-fx.ts';
import {normalDepreciationVersion,validateNormalDepreciation,calculateNormalDepreciation,normalDepreciationReport,type NormalDepreciationInput,type NormalDepreciationModel} from './irpc-normal-depreciation.ts';
@@ -41,13 +41,13 @@ export function validateNormal(b:NormalBook){
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||![irpcSpecialVersion,irpcNormalVersion,normalProfitVersion,normalBaseVersion,normalAssessmentVersion,normalSchedulesVersion,normalCostsVersion,normalDepreciationVersion,normalPeriodFxVersion,normalFormPreparationVersion].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.');
for(const r of [b.result,...(b.history??[])])if(r&&(!r.model||![irpcSpecialStartPeriodVersion,irpcSpecialCessationPriorVersion,irpcSpecialMonthlyVersion,irpcSpecialVersion,irpcNormalVersion,normalProfitVersion,normalBaseVersion,normalAssessmentVersion,normalSchedulesVersion,normalCostsVersion,normalDepreciationVersion,normalPeriodFxVersion,normalFormPreparationVersion].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.special?irpcSpecialVersion:b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion: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]:[]),...(b.costs?[b.costs]:[]),...(b.depreciation?[b.depreciation]:[]),...(b.periodsFx?[b.periodsFx,normalPeriodFxDependency(d,b.periodsFx)]:[]),...(b.forms?[b.forms]:[]),...(b.special?[b.special,specialDependency(d)]:[])]);}
function key(d:Record<string,unknown>,b:NormalBook){return JSON.stringify([b.special?specialCalculationVersion(b.special):b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion: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]:[]),...(b.costs?[b.costs]:[]),...(b.depreciation?[b.depreciation]:[]),...(b.periodsFx?[b.periodsFx,normalPeriodFxDependency(d,b.periodsFx)]:[]),...(b.forms?[b.forms]:[]),...(b.special?[b.special,specialDependency(d)]:[])]);}
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;};
@@ -96,7 +96,7 @@ export function calculateNormal(d:Record<string,unknown>,b:NormalBook):NormalMod
const assessment=b.assessment?calculateNormalAssessment(b.assessment,base?.taxableBase??null,{year:b.year,scope:b.scope,extended:!!b.schedules||!!periodsFx,short:!!periodsFx?.short,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;
const model:NormalModel={...(periodsFx?{periodsFx}:{}),...(depreciation?{depreciation}:{}),...(costs?{costs}:{}),...(schedules?{schedules,currentLoss,fiscalPeriod}:{}),...(assessment?{assessment,colecta:assessment.colecta}:{}),...(base?{base}:{}),...(profit?{profit}:{}),version:b.special?irpcSpecialVersion:b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion: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+(periodsFx?' '+periodsFx.rule: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.':'')};
const model:NormalModel={...(periodsFx?{periodsFx}:{}),...(depreciation?{depreciation}:{}),...(costs?{costs}:{}),...(schedules?{schedules,currentLoss,fiscalPeriod}:{}),...(assessment?{assessment,colecta:assessment.colecta}:{}),...(base?{base}:{}),...(profit?{profit}:{}),version:b.special?specialCalculationVersion(b.special):b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion: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+(periodsFx?' '+periodsFx.rule: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.':'')};
if(b.special)model.special=calculateSpecial(d,b,model,source);
if(b.forms){model.formPreparation=prepareNormalForms(b.forms,model,source);model.pending.push(...model.formPreparation.pending.map(p=>'Preparação M20/M22: '+p));}
return model;
+42 -4
View File
@@ -5,18 +5,31 @@ import {calculateNormalDepreciation,type NormalDepreciationModel} from './irpc-n
import {addFractions,subtractFractions,decimalFraction,fraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
export const irpcSpecialVersion='IRPC-normal-adjustments/10';
export const irpcSpecialMonthlyVersion='IRPC-normal-adjustments/11';
export const irpcSpecialStartPeriodVersion='IRPC-normal-adjustments/12';
export const irpcSpecialCessationPriorVersion='IRPC-normal-adjustments/13';
export const specialCessationPriorSource='CBF3/9/10/16;CIRPC7(4);Decreto72/2013 art3(3),9(1–3) e10:residente,ano civil2026 ou período curto de cessação com meses completosL6. Activo novo a custo histórico,entrada2025/2026,método constante/taxa normal máxima e duodécimos desde a entrada. Taxa ×1,5,limites contabilizado elegível e saldo fiscal;quotas anteriores e parcela temporariamente tributada documentadas emL6,sem recalcular o passado nem consumir saldos oficiais. Saída do activo só quando declarada,excluindo o mês do evento;cessação não presume transmissão. Sem cumulação.';
export const specialStartPeriodSource='CBF3/9/10/16;CIRPC7(4);Decreto72/2013 art3(3)/9(3):período curto por início de actividade de residente em2026. Taxa normal máxima ×1,5 ×meses efectivos/12 reutilizados de L6,sem anualização;activo novo emuso no período,método constante,sem saída/quotas anteriores/cumulação. Limites contabilizado elegível e saldo fiscal;apenas diferença adicional.';
export const specialMonthlySource='CBF16 com Decreto72/2013 art9:taxa normal máxima ×1,5 ×duodécimos/12,meses reutilizados do mapaL6. Exercício anual civil2026,entrada emuso no ano,método constante,sem saída/quotas anteriores/cumulação. Dedução limitada ao contabilizado elegível e saldo fiscal;apenas diferença adicional,não nova amortização contabilística.';
export const specialSources={expenses:'CIRPC,Lei34/2007,art61(4),PDF17/p768(71):35% sobre encargos não devidamente documentados e despesas confidenciais/ilícitas,sem prejuízo do36(1)g. Exercício2026;sem regra inferida da falta de anexo.',cooperative:'CIRPC,Lei34/2007,art12/14,PDF5/p768(59),e61(1):cooperativas agrárias,de artesanato e culturais;redução de50% da taxa geral32%=16%;rendimentos sujeitos a retenção excluídos deste benefício. Recorte2026,residente,parcela ordinária integralmente elegível.',acceleration:'CBF,Lei4/2009,art3/4/9/10/16;compilação oficial APIEX pp66–68/72:incremento50% das taxas normais nos imóveis novos do projecto e,nas mesmas condições,imóveis reabilitados/máquinas e equipamentos industriais ou agro-industriais. Decreto72/2013 art3(3):limite contabilizado e saldo fiscal. Recorte constante pela taxa normal máxima da tabela,primeiro exercício anual2026,sem cumulação presumida.'}as const;
export type Qualification={state:''|'known'|'absent'|'not_applicable';eligible:''|'yes'|'no';from:string;to:string;reference:string;periodReference:string};
export const newQualification=():Qualification=>({state:'',eligible:'',from:'',to:'',reference:'',periodReference:''});
export type SpecialExpense={id:string;scheduleId:string;nature:''|'undocumented'|'confidential'|'illicit'|'other';eligible:''|'yes'|'no';reference:string};
export type AcceleratedAsset={id:string;assetId:string;kind:''|'new_project_building'|'rehabilitated_project_building'|'industrial_equipment'|'agroindustrial_equipment'|'other';eligible:''|'yes'|'no';reference:string};
export type SpecialInput={version:1;expenses:{qualification:Qualification;rows:SpecialExpense[]};cooperative:{qualification:Qualification;kind:''|'agrarian'|'craft'|'cultural'|'other';allIncomeEligible:''|'yes'|'no';withheldIncome:''|'absent'|'known'};acceleration:{qualification:Qualification;cbfRequirements:''|'yes'|'no';recognition:''|'documented'|'not_required';recognitionReference:string;noOtherBenefits:''|'yes'|'no';rows:AcceleratedAsset[]}};
export type SpecialContinuationInput={version:1;period:''|'annual'|'cessation';reference:string;historyReference:string;monthlyFromStart:''|'yes'|'no'};
export type SpecialMonthlyInput={version:1;reference:string;startPeriod?:{version:1;reference:string};continuation?:SpecialContinuationInput};
export type SpecialInput={version:1;expenses:{qualification:Qualification;rows:SpecialExpense[]};cooperative:{qualification:Qualification;kind:''|'agrarian'|'craft'|'cultural'|'other';allIncomeEligible:''|'yes'|'no';withheldIncome:''|'absent'|'known'};acceleration:{qualification:Qualification;cbfRequirements:''|'yes'|'no';recognition:''|'documented'|'not_required';recognitionReference:string;noOtherBenefits:''|'yes'|'no';rows:AcceleratedAsset[];monthly?:SpecialMonthlyInput}};
export const specialCalculationVersion=(i:SpecialInput)=>i.acceleration.monthly?.continuation?irpcSpecialCessationPriorVersion:i.acceleration.monthly?.startPeriod?irpcSpecialStartPeriodVersion:i.acceleration.monthly?irpcSpecialMonthlyVersion:irpcSpecialVersion;
export const newSpecialInput=():SpecialInput=>({version:1,expenses:{qualification:newQualification(),rows:[]},cooperative:{qualification:newQualification(),kind:'',allIncomeEligible:'',withheldIncome:''},acceleration:{qualification:newQualification(),cbfRequirements:'',recognition:'',recognitionReference:'',noOtherBenefits:'',rows:[]}});
export const newSpecialExpense=(id:string):SpecialExpense=>({id,scheduleId:'',nature:'',eligible:'',reference:''});
export const newAcceleratedAsset=(id:string):AcceleratedAsset=>({id,assetId:'',kind:'',eligible:'',reference:''});
const choices=(v:unknown,allowed:string[])=>typeof v==='string'&&allowed.includes(v);
export function validateSpecial(i:SpecialInput){
if(!i||i.version!==1||!i.expenses||!i.cooperative||!i.acceleration)throw Error('Qualificação L7 não recuperável;originais conservados.');
if(i.acceleration.monthly!==undefined&&(!i.acceleration.monthly||i.acceleration.monthly.version!==1||typeof i.acceleration.monthly.reference!=='string'))throw Error('Preparação CBF16 por duodécimos não recuperável;históricos conservados.');
if(i.acceleration.monthly?.startPeriod!==undefined&&(!i.acceleration.monthly.startPeriod||i.acceleration.monthly.startPeriod.version!==1||typeof i.acceleration.monthly.startPeriod.reference!=='string'))throw Error('Preparação CBF16 para início de actividade não recuperável;históricos conservados.');
const continuation=i.acceleration.monthly?.continuation;
if(continuation!==undefined&&(!continuation||continuation.version!==1||!choices(continuation.period,['','annual','cessation'])||typeof continuation.reference!=='string'||typeof continuation.historyReference!=='string'||!choices(continuation.monthlyFromStart,['','yes','no'])||i.acceleration.monthly?.startPeriod!==undefined))throw Error('Preparação CBF16 de cessação/quotas anteriores não recuperável ou incompatível com início de actividade;históricos conservados.');
for(const q of[i.expenses.qualification,i.cooperative.qualification,i.acceleration.qualification])if(!q||!choices(q.state,['','known','absent','not_applicable'])||!choices(q.eligible,['','yes','no'])||['from','to','reference','periodReference'].some(k=>typeof q[k as 'from']!=='string'))throw Error('Condição/período L7 não recuperável.');
for(const [rows,keys]of [[i.expenses.rows,Object.keys(newSpecialExpense(''))],[i.acceleration.rows,Object.keys(newAcceleratedAsset(''))]]as const){if(!Array.isArray(rows)||new Set(rows.map(r=>r.id)).size!==rows.length||rows.some(r=>!r||keys.some(k=>typeof(r as unknown as Record<string,unknown>)[k]!=='string')||!choices(r.eligible,['','yes','no'])))throw Error('Parcela L7 não recuperável ou identificador repetido.');}
if(i.expenses.rows.some(r=>!choices(r.nature,['','undocumented','confidential','illicit','other']))||i.acceleration.rows.some(r=>!choices(r.kind,['','new_project_building','rehabilitated_project_building','industrial_equipment','agroindustrial_equipment','other'])))throw Error('Natureza L7 desconhecida.');
@@ -71,6 +84,11 @@ export function calculateSpecial(draft:Record<string,unknown>,b:NormalBook,m:Nor
if(accDecision.status==='absent'&&i.acceleration.rows.length)fail(accDecision,'Ausência de amortização acelerada contradiz activos seleccionados.');
if(accDecision.status!=='calculated'&&i.acceleration.rows.length&&accDecision.status!=='indeterminate')fail(accDecision,'Não aplicação global com activos seleccionados:reconcilie o estado e as parcelas.');
if(accDecision.status==='calculated'){
if(i.acceleration.monthly&&!i.acceleration.monthly.reference.trim())fail(accDecision,'Falta suporte da reutilização dos meses e da opção por duodécimosCBF16 no mapaL6.');
if(i.acceleration.monthly?.startPeriod&&!i.acceleration.monthly.startPeriod.reference.trim())fail(accDecision,'Falta suporte do período curto por início de actividadeCBF16;período e activosL6 conservados.');
const continuation=i.acceleration.monthly?.continuation;
if(continuation?.monthlyFromStart==='no')fail(accDecision,'Duodécimos desde a entrada emuso não aplicados:esta combinação de quotas/saída exige correspondência própria;L6 e os saldos declarados ficam preservados.');
if(continuation&&(!continuation.period||!continuation.reference.trim()||!continuation.historyReference.trim()||!continuation.monthlyFromStart))fail(accDecision,'CBF16 cessação/quotas anteriores:identifique período,suporte da vigência/condições e das quotas anteriores ou ausência;duodécimos desde a entrada emuso por documentar. Sem recalcular ou presumir saldos anteriores.');
if(i.acceleration.cbfRequirements!=='yes'||!i.acceleration.recognition||!i.acceleration.recognitionReference.trim())fail(accDecision,'Falta enquadramentoCBF3/9 e reconhecimento10 quando exigido;excepção deve ter norma/suporte,não localização.');
if(i.acceleration.noOtherBenefits!=='yes')fail(accDecision,'CumulaçãoCBF4 por corresponder;este recorte não combina outros benefícios positivos.');
if(coopDecision.status==='calculated')fail(accDecision,'Combinação de redução cooperativa comCBF16 ainda não correspondida;cada caso independente continua demonstrável.');
@@ -87,7 +105,15 @@ export function calculateSpecial(draft:Record<string,unknown>,b:NormalBook,m:Nor
const building=r.kind==='new_project_building'&&base?.catalog?.kind==='building',equipment=['industrial_equipment','agroindustrial_equipment'].includes(r.kind)&&['machine','laundry_machine'].includes(a.category);
if(!building&&!equipment)issues.push('Categoria/afectação fora do recorte:imóvel novo ou máquina industrial/agro-industrial correspondida;reabilitados e outras categorias/métodos exigem regra própria.');
if(base?.catalog&&cmp(decimalFraction(a.rate),decimalFraction(base.catalog.rate))!==0n)issues.push('RecorteCBF16 usa a taxa normal máxima da tabela;opção por quota inferior exige correspondência própria,sem a acelerar por aproximação.');
if(a.method!=='constant'||a.timing!=='annual'||a.start!=='2026-01-01'||a.exitState!=='absent'||a.previousAccounting!=='0'||a.previousFiscal!=='0'||a.priorAvailable!=='0'||m.fiscalPeriod?.from!=='2026-01-01'||m.fiscalPeriod?.to!=='2026-12-31')issues.push('CBF16 inicial:primeiro exercício anual civil2026,método constante,sem quotas anteriores ou saída;duodécimos e recuperação anterior continuam separados.');
if(i.acceleration.monthly){
const p=specialPeriod(b,m),priorZero=[a.previousAccounting,a.previousFiscal,a.priorAvailable].every(v=>cmp(decimalFraction(v),z())===0n);
if(i.acceleration.monthly.continuation){
const c=i.acceleration.monthly.continuation,annual=c.period==='annual'&&p.from==='2026-01-01'&&p.to==='2026-12-31'&&!m.periodsFx?.short,cessation=c.period==='cessation'&&b.periodsFx?.kind==='cessation'&&m.periodsFx?.short&&p.from==='2026-01-01'&&iso(p.to)&&p.to<'2026-12-01';
if(b.scope!=='resident_general'||p.pending.length||!annual&&!cessation||a.method!=='constant'||a.timing!=='months'||!iso(a.start)||a.start<'2025-01-01'||a.start>p.to||a.start>='2026-01-01'&&!priorZero||a.exitState!=='absent'&&!(a.exitState==='known'&&iso(a.exitDate)&&a.exitDate>=p.from&&a.exitDate<=p.to)||base?.months===null||base?.months===undefined)issues.push('CBF16 cessação/quotas anteriores:residente,ano civil2026 ou cessaçãoL6 de meses completos desde1Janeiro,activo novo com entrada2025/2026 e saldosL6 reconciliados,método constante e duodécimos. Quotas anteriores positivas exigem entrada2025;saída só por evento documentado dentro do período. Outros anos/períodos/métodos mantêm correspondência própria.');
}else if(i.acceleration.monthly.startPeriod){
if(b.scope!=='resident_general'||b.periodsFx?.kind!=='start'||!m.periodsFx?.short||p.pending.length||!iso(p.from)||p.from<'2026-02-01'||p.from>'2026-12-01'||p.from.slice(-2)!=='01'||p.to!=='2026-12-31'||a.method!=='constant'||a.timing!=='months'||!iso(a.start)||a.start<p.from||a.start>p.to||a.exitState!=='absent'||!priorZero||base?.months===null||base?.months===undefined)issues.push('CBF16 início de actividade:residente,período curtoL6 de meses completos em2026 até31/12,activo novo emuso dentro do período,método constante,opção mensal e ausência documentada de saída/quotas anteriores;cessação/transição e demais situações permanecem separadas.');
}else if(a.method!=='constant'||a.timing!=='months'||!iso(a.start)||a.start<'2026-01-01'||a.start>'2026-12-31'||a.exitState!=='absent'||!priorZero||p.from!=='2026-01-01'||p.to!=='2026-12-31'||base?.months===null||base?.months===undefined)issues.push('CBF16 por duodécimos:exercício anual civil2026,método constante,entrada no ano,opção mensalL6 e ausência documentada de saída/quotas anteriores;outros períodos/casos permanecem separados.');
}else if(a.method!=='constant'||a.timing!=='annual'||a.start!=='2026-01-01'||a.exitState!=='absent'||a.previousAccounting!=='0'||a.previousFiscal!=='0'||a.priorAvailable!=='0'||m.fiscalPeriod?.from!=='2026-01-01'||m.fiscalPeriod?.to!=='2026-12-31')issues.push('CBF16 inicial:primeiro exercício anual civil2026,método constante,sem quotas anteriores ou saída;duodécimos e recuperação anterior continuam separados.');
if(!issues.length)status='calculated';
}
return{...structuredClone(r),assetKey:a?.assetKey??'',description:a?.description??'',status,reason:issues.join(' ')||(status==='calculated'?'Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal.':'Condição negativa documentada;quota normal mantida.')};
@@ -96,7 +122,9 @@ export function calculateSpecial(draft:Record<string,unknown>,b:NormalBook,m:Nor
if(accDecision.status==='calculated'){
for(const r of accelerations)if(r.status==='indeterminate')fail(accDecision,(r.description||r.id)+': '+r.reason);
if(accDecision.status==='calculated'&&b.depreciation&&m.depreciation?.adjustment){
acceleratedDepreciation=calculateNormalDepreciation(b.depreciation,source,{from:'2026-01-01',to:'2026-12-31'},[...b.rows,...(b.schedules?.rows??[]),...(b.costs?.rows??[])],false,new Set(accelerations.filter(r=>r.status==='calculated').map(r=>r.assetId)));
const startPeriod=!!i.acceleration.monthly?.startPeriod,continuation=i.acceleration.monthly?.continuation;
acceleratedDepreciation=calculateNormalDepreciation(b.depreciation,source,startPeriod||continuation?specialPeriod(b,m):{from:'2026-01-01',to:'2026-12-31'},[...b.rows,...(b.schedules?.rows??[]),...(b.costs?.rows??[])],startPeriod||continuation?.period==='cessation',new Set(accelerations.filter(r=>r.status==='calculated').map(r=>r.assetId)));
if(startPeriod||continuation)acceleratedDepreciation={...acceleratedDepreciation,source:continuation?specialCessationPriorSource:specialStartPeriodSource};
if(acceleratedDepreciation.adjustment===null)fail(accDecision,acceleratedDepreciation.pending.join(' '));
else additionalDeduction=subtractFractions(m.depreciation.adjustment,acceleratedDepreciation.adjustment);
}else if(accDecision.status==='calculated')fail(accDecision,'Reconciliação da amortização normal em falta.');
@@ -108,7 +136,12 @@ export function calculateSpecial(draft:Record<string,unknown>,b:NormalBook,m:Nor
const assessment=assessmentInput?calculateNormalAssessment(assessmentInput,base?.taxableBase??null,{year:b.year,scope:b.scope,currency:m.currency,extended:!!b.schedules||!!b.periodsFx,short:!!m.periodsFx?.short,period:specialPeriod(b,m)}):null;
const normalColecta=assessment?.colecta??null,colecta=coopDecision.status==='indeterminate'?null:normalColecta?(coopDecision.status==='calculated'?mul(normalColecta,1n,2n):normalColecta):null;
const combinedColecta=colecta&&autonomousTax?addFractions([colecta,autonomousTax]):null;
return{input:structuredClone(i),context:structuredClone(specialContext(draft)),subjectNuit:b.base?.subjectNuit??'',period:specialPeriod(b,m),expenses:{...expenseDecision,rows:expenses,knownAutonomous,autonomousTax,source:specialSources.expenses},cooperative:{...coopDecision,rate:coopDecision.status==='calculated'?fraction(16n):null,source:specialSources.cooperative},acceleration:{...accDecision,rows:accelerations,additionalDeduction,normal:m.depreciation??null,accelerated:acceleratedDepreciation,source:specialSources.acceleration},reference:{taxableProfit:m.taxableProfit,taxableBase:m.taxableBase,colecta:m.colecta??null},taxableProfit,taxableBase:base?.taxableBase??null,colecta,combinedColecta,pending:[...expenseDecision.pending,...coopDecision.pending,...accDecision.pending,...(base?.pending??[]),...(assessment?.pending??[])],limitations:['L7 parcial:apenas61(4),cooperativa integralmente elegível12 eCBF16 no recorte documentado.','Localização/sector só contextualizam;não activam benefícios.','Parcelas mistas,cumulação,mais-valias e demais famílias têm correspondência própria.','M20/M22 permanecem preparaçãoL6 de referência;efeitosL7 sem campo oficial presumido.','Colecta combinada não é saldo final a pagar/recuperar;retenções,pagamentos e créditos anuais emL8.'],finalBalance:{scope:'L8',payable:null,recoverable:null}};
const monthlySource=i.acceleration.monthly?.continuation?specialCessationPriorSource:i.acceleration.monthly?.startPeriod?specialStartPeriodSource:specialMonthlySource;
const monthlyModel=i.acceleration.monthly?{input:structuredClone(i.acceleration.monthly),period:specialPeriod(b,m),source:monthlySource,assets:accelerations.map(r=>{
const input=b.depreciation?.assets.find(a=>a.id===r.assetId),normal=m.depreciation?.assets.find(a=>a.id===r.assetId),accelerated=acceleratedDepreciation?.assets.find(a=>a.id===r.assetId),applied=accDecision.status==='calculated'&&r.status==='calculated'&&accelerated?.status==='calculated',rate=normal?.status==='calculated'&&input?decimalFraction(input.rate):null;
return{...(i.acceleration.monthly?.continuation?{prior:{previousAccounting:input?.previousAccounting??'',previousFiscal:input?.previousFiscal??'',available:input?.priorAvailable??'',reference:input?.previousReference??'',normalUsed:normal?.priorUsed??null,normalRemaining:normal?.priorRemaining??null,acceleratedUsed:applied?accelerated.priorUsed:null,acceleratedRemaining:applied?accelerated.priorRemaining:null,normalFiscalRemaining:normal?.remainingFiscal??null,acceleratedFiscalRemaining:applied?accelerated.remainingFiscal:null},exit:{state:input?.exitState??'',date:input?.exitDate??''}}:{}),id:r.id,assetId:r.assetId,assetKey:r.assetKey,description:r.description,start:input?.start??'',months:normal?.months??null,taxBasis:normal?.taxBasis??null,normalRate:rate,acceleratedRate:applied&&rate?mul(rate,3n,2n):null,normalQuota:normal?.quota??null,acceleratedQuota:applied?accelerated.quota:null,normalDeduction:normal?.deduction??null,acceleratedDeduction:applied?accelerated.deduction:null,additionalDeduction:applied&&normal?.deduction&&accelerated.deduction?subtractFractions(accelerated.deduction,normal.deduction):r.status==='not_applicable'?z():null,applied,reason:r.reason};
})}:undefined;
return{input:structuredClone(i),context:structuredClone(specialContext(draft)),subjectNuit:b.base?.subjectNuit??'',period:specialPeriod(b,m),expenses:{...expenseDecision,rows:expenses,knownAutonomous,autonomousTax,source:specialSources.expenses},cooperative:{...coopDecision,rate:coopDecision.status==='calculated'?fraction(16n):null,source:specialSources.cooperative},acceleration:{...accDecision,rows:accelerations,additionalDeduction,normal:m.depreciation??null,accelerated:acceleratedDepreciation,...(monthlyModel?{monthly:monthlyModel}:{}),source:i.acceleration.monthly?.continuation?specialCessationPriorSource:i.acceleration.monthly?.startPeriod?specialStartPeriodSource:i.acceleration.monthly?specialSources.acceleration+' '+specialMonthlySource:specialSources.acceleration},reference:{taxableProfit:m.taxableProfit,taxableBase:m.taxableBase,colecta:m.colecta??null},taxableProfit,taxableBase:base?.taxableBase??null,colecta,combinedColecta,pending:[...expenseDecision.pending,...coopDecision.pending,...accDecision.pending,...(base?.pending??[]),...(assessment?.pending??[])],limitations:['L7 parcial:apenas61(4),cooperativa integralmente elegível12 eCBF16 no recorte documentado.','Localização/sector só contextualizam;não activam benefícios.','Parcelas mistas,cumulação,mais-valias e demais famílias têm correspondência própria.','M20/M22 permanecem preparaçãoL6 de referência;efeitosL7 sem campo oficial presumido.','Colecta combinada não é saldo final a pagar/recuperar;retenções,pagamentos e créditos anuais emL8.'],finalBalance:{scope:'L8',payable:null,recoverable:null}};
}
export type SpecialModel=ReturnType<typeof calculateSpecial>;
const money=(v:FiscalFraction|null)=>{if(!v)return'Indeterminado';const p=fractionPresentation(v);return(p.approximate?'≈':'')+p.decimal+' MZN (exacto '+v.numerator+'/'+v.denominator+')';};
@@ -122,4 +155,9 @@ export function specialReportRows(m:SpecialModel):Array<[string,string,string,st
['IRPC — L7','Amortizações aceleradas',`${status(m.acceleration.status)};dedução adicional conciliada:${money(m.acceleration.additionalDeduction)};${m.acceleration.reason}`,`${m.input.acceleration.qualification.reference};${m.input.acceleration.qualification.periodReference};${m.input.acceleration.recognitionReference};${m.acceleration.source}`],
...m.acceleration.rows.map(r=>{const a=m.acceleration.accelerated?.assets.find(a=>a.id===r.assetId),n=m.acceleration.normal?.assets.find(a=>a.id===r.assetId);return['IRPC — L7',r.description||r.assetId,`${status(r.status)};quota normal:${money(n?.quota??null)};quota acelerada:${money(a?.quota??null)};dedução normal:${money(n?.deduction??null)};dedução acelerada:${money(a?.deduction??null)};${r.reason}`,r.reference]as[string,string,string,string];}),
['IRPC — L7','Efeitos nos totais',`ReferênciaL6:lucro:${money(m.reference.taxableProfit)};base:${money(m.reference.taxableBase)};colecta:${money(m.reference.colecta)}. Após tratamentosL7:lucro:${money(m.taxableProfit)};base:${money(m.taxableBase)};colecta sobre a base:${money(m.colecta)};imposto autónomo:${money(m.expenses.autonomousTax)};colecta combinada:${money(m.combinedColecta)}. Saldo final a pagar/recuperar:Indeterminado (L8).`,m.pending.join(' | ')||'Regras/parcelas reconciliadas neste recorte;simulação,não liquidação final.'],
...(m.acceleration.monthly?specialMonthlyReport(m.acceleration.monthly,m.acceleration.additionalDeduction):[]),
];}
function specialMonthlyReport(m:NonNullable<SpecialModel['acceleration']['monthly']>,deduction:FiscalFraction|null):Array<[string,string,string,string]>{
return[['IRPC — L7','CBF16 — duodécimos reutilizados de L6','Período:'+m.period.from+'–'+m.period.to+';dedução adicional conciliada:'+money(deduction)+';sem nova dedução do activo de origem.',m.input.reference+(m.input.startPeriod?';início de actividade:'+m.input.startPeriod.reference:'')+(m.input.continuation?';período:'+(m.input.continuation.period==='cessation'?'Cessação da actividade':m.input.continuation.period==='annual'?'Ano civil2026':'Informação em falta')+';suporte:'+m.input.continuation.reference+';histórico:'+m.input.continuation.historyReference:'')+';'+m.source],...m.assets.map(a=>['IRPC — L7','CBF16 por duodécimos — '+a.description,'Entrada emuso:'+(a.start||'Informação em falta')+';duodécimosL6:'+(a.months??'Indeterminados')+';base fiscal:'+money(a.taxBasis)+';taxa normal:'+(a.normalRate?fractionPresentation(a.normalRate).decimal+'%':'Indeterminada')+';taxa CBF16:'+(a.acceleratedRate?fractionPresentation(a.acceleratedRate).decimal+'%':'Não aplicada')+';quota normal:'+money(a.normalQuota)+';quota CBF16:'+money(a.acceleratedQuota)+';dedução normal:'+money(a.normalDeduction)+';dedução CBF16:'+money(a.acceleratedDeduction)+';diferença adicional:'+money(a.additionalDeduction)+(a.prior?';quotas contabilísticas anteriores:'+a.prior.previousAccounting+';quotas fiscais anteriores:'+a.prior.previousFiscal+';parcela anterior recuperável declarada:'+a.prior.available+';recuperada normal:'+money(a.prior.normalUsed)+';recuperada CBF16:'+money(a.prior.acceleratedUsed)+';saldo anterior aritmético normal:'+money(a.prior.normalRemaining)+';saldo anterior aritmético CBF16:'+money(a.prior.acceleratedRemaining)+';saldo fiscal normal:'+money(a.prior.normalFiscalRemaining)+';saldo fiscal CBF16:'+money(a.prior.acceleratedFiscalRemaining)+';saída:'+(a.exit?.state==='absent'?'Ausência declarada':a.exit?.state==='known'?'Evento documentado':'Informação em falta')+' '+(a.exit?.date??'')+';sem consumo de saldos oficiais':'')+';'+a.reason,m.source+(a.prior?';suporte das quotas anteriores:'+a.prior.reference:'')]as[string,string,string,string])];
}
+1 -1
View File
@@ -15,7 +15,7 @@ export default function WhyInvest() {
<div className="-mx-2 flow-root">
<article
aria-label="Investir em Moçambique"
className="p-2 lg:float-left lg:w-2/3"
className="rounded-lg bg-[#D0E2FF] p-2 lg:float-left lg:w-2/3"
>
<div className="space-y-3 text-base leading-6 text-slate-700">
<p>
@@ -0,0 +1,54 @@
<?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 IrpcSpecialCessationPriorDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_cbf16_cessation_and_prior_quotas_recover_without_consuming_declared_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(['cessation','prior','annual','exit','missing','negative','absent']as$case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l7-cessation-prior/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$personal,'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'];$a=$m['special']['acceleration'];
$this->assertSame('IRPC-normal-adjustments/13',$m['version']);$this->assertSame($b['special']['acceleration']['monthly'],$a['monthly']['input']);
$this->assertContains('IRPC-normal-adjustments/12',array_column(array_column($b['history'],'model'),'version'));
$this->assertContains('IRPC-normal-adjustments/11',array_column(array_column($b['history'],'model'),'version'));
$this->assertSame($b['depreciation'],$a['normal']['input']);$this->assertSame(['scope'=>'L8','payable'=>null,'recoverable'=>null],$m['special']['finalBalance']);
$this->assertNull($m['tax']);$this->assertArrayHasKey('irpcWithholdings',$s);
if($case==='cessation'){
$v=$a['monthly']['assets'][0];$this->assertSame(6,$v['months']);$this->assertSame('absent',$v['exit']['state']);$this->assertSame('10',$a['additionalDeduction']['numerator']);
$this->assertSame('3120',$m['special']['taxableProfit']['numerator']);$this->assertSame(['numerator'=>'4992','denominator'=>'5'],$m['special']['colecta']);
}elseif($case==='prior'||$case==='annual'){
$v=$a['monthly']['assets'][0];$this->assertSame('150',$b['depreciation']['assets'][0]['previousAccounting']);$this->assertSame('100',$b['depreciation']['assets'][0]['previousFiscal']);$this->assertSame('50',$b['depreciation']['assets'][0]['priorAvailable']);
$this->assertSame($case==='prior'?'15':'30',$v['prior']['acceleratedUsed']['numerator']);$this->assertSame($case==='prior'?'35':'20',$v['prior']['acceleratedRemaining']['numerator']);
$this->assertSame($case==='prior'?'25':'50',$a['additionalDeduction']['numerator']);$this->assertSame($case==='prior'?'3105':'6210',$m['special']['taxableProfit']['numerator']);
$this->assertSame(['numerator'=>$case==='prior'?'4968':'9936','denominator'=>'5'],$m['special']['colecta']);$this->assertSame($b['depreciation'],$a['accelerated']['input']);
}elseif($case==='exit'){
$v=$a['monthly']['assets'][0];$this->assertSame(5,$v['months']);$this->assertSame('2026-06-20',$v['exit']['date']);
$this->assertSame(['numerator'=>'125','denominator'=>'3'],$v['normalQuota']);$this->assertSame(['numerator'=>'125','denominator'=>'6'],$a['additionalDeduction']);
}elseif($case==='missing'){
$this->assertSame('indeterminate',$a['status']);$this->assertNull($a['additionalDeduction']);$this->assertSame('3130',$m['taxableProfit']['numerator']);$this->assertNull($m['special']['colecta']);
}elseif($case==='negative'){
$this->assertSame('not_applicable',$a['rows'][0]['status']);$this->assertFalse($a['monthly']['assets'][0]['applied']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}else{
$this->assertSame('absent',$a['status']);$this->assertSame([],$a['monthly']['assets']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}
file_put_contents(base_path('outputs/irpc-l7-cessation-prior/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
@@ -0,0 +1,49 @@
<?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 IrpcSpecialMonthlyDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_monthly_cbf16_recovers_new_results_missing_cases_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()]));$id=null;$etag=null;
foreach(['monthly','fraction','missing','negative','absent']as$case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l7-months/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$personal,'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'];$a=$m['special']['acceleration'];
$this->assertSame('IRPC-normal-adjustments/11',$m['version']);$this->assertSame($b['special']['acceleration']['monthly'],$a['monthly']['input']);
$this->assertContains('IRPC-normal-adjustments/10',array_column(array_column($b['history'],'model'),'version'));
$this->assertSame($b['depreciation'],$a['normal']['input']);$this->assertSame('L8',$m['special']['finalBalance']['scope']);$this->assertNull($m['special']['finalBalance']['payable']);
$this->assertNull($m['special']['finalBalance']['recoverable']);$this->assertNull($m['tax']);$this->assertArrayHasKey('irpcWithholdings',$s);
if($case==='monthly'){
$v=$a['monthly']['assets'][0];$this->assertSame(6,$v['months']);$this->assertSame('50',$v['normalQuota']['numerator']);$this->assertSame('75',$v['acceleratedQuota']['numerator']);
$this->assertSame('60',$v['acceleratedDeduction']['numerator']);$this->assertSame('10',$a['additionalDeduction']['numerator']);
$this->assertSame('6310',$m['taxableProfit']['numerator']);$this->assertSame('6300',$m['special']['taxableProfit']['numerator']);$this->assertSame('2016',$m['special']['colecta']['numerator']);
$this->assertSame($b['depreciation'],$a['accelerated']['input']);
}elseif($case==='fraction'){
$v=$a['monthly']['assets'][0];$this->assertSame(1,$v['months']);$this->assertSame(['numerator'=>'25','denominator'=>'3'],$v['normalQuota']);$this->assertSame(['numerator'=>'25','denominator'=>'6'],$a['additionalDeduction']);
}elseif($case==='missing'){
$this->assertSame('indeterminate',$a['status']);$this->assertNull($a['additionalDeduction']);$this->assertSame('6310',$m['taxableProfit']['numerator']);$this->assertNull($m['special']['colecta']);
}elseif($case==='negative'){
$this->assertSame('not_applicable',$a['rows'][0]['status']);$this->assertFalse($a['monthly']['assets'][0]['applied']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}else{
$this->assertSame('absent',$a['status']);$this->assertSame([],$a['monthly']['assets']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}
file_put_contents(base_path('outputs/irpc-l7-months/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
}
}
}
@@ -0,0 +1,49 @@
<?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 IrpcSpecialStartPeriodDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_start_period_cbf16_recovers_new_results_missing_cases_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()]));$id=null;$etag=null;
foreach(['start','fraction','missing','negative','absent']as$case){
$d=json_decode(file_get_contents(base_path('outputs/irpc-l7-start-period/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);
$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$personal,'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'];$a=$m['special']['acceleration'];
$this->assertSame('IRPC-normal-adjustments/12',$m['version']);$this->assertSame($b['special']['acceleration']['monthly'],$a['monthly']['input']);
$this->assertContains('IRPC-normal-adjustments/11',array_column(array_column($b['history'],'model'),'version'));$this->assertContains('IRPC-normal-adjustments/10',array_column(array_column($b['history'],'model'),'version'));
$this->assertSame($b['depreciation'],$a['normal']['input']);$this->assertSame('L8',$m['special']['finalBalance']['scope']);$this->assertNull($m['special']['finalBalance']['payable']);
$this->assertNull($m['special']['finalBalance']['recoverable']);$this->assertNull($m['tax']);$this->assertArrayHasKey('irpcWithholdings',$s);
if($case==='start'){
$v=$a['monthly']['assets'][0];$this->assertSame(6,$v['months']);$this->assertSame('50',$v['normalQuota']['numerator']);$this->assertSame('75',$v['acceleratedQuota']['numerator']);
$this->assertSame('60',$v['acceleratedDeduction']['numerator']);$this->assertSame('10',$a['additionalDeduction']['numerator']);
$this->assertSame('3130',$m['taxableProfit']['numerator']);$this->assertSame('3120',$m['special']['taxableProfit']['numerator']);$this->assertSame(['numerator'=>'4992','denominator'=>'5'],$m['special']['colecta']);$this->assertTrue($m['periodsFx']['short']);$this->assertSame('2026-07-01',$a['monthly']['period']['from']);$this->assertStringContainsString('início de actividade',$a['source']);
$this->assertSame($b['depreciation'],$a['accelerated']['input']);
}elseif($case==='fraction'){
$v=$a['monthly']['assets'][0];$this->assertSame(1,$v['months']);$this->assertSame(['numerator'=>'25','denominator'=>'3'],$v['normalQuota']);$this->assertSame(['numerator'=>'5','denominator'=>'3'],$a['additionalDeduction']);
}elseif($case==='missing'){
$this->assertSame('indeterminate',$a['status']);$this->assertNull($a['additionalDeduction']);$this->assertSame('3130',$m['taxableProfit']['numerator']);$this->assertNull($m['special']['colecta']);
}elseif($case==='negative'){
$this->assertSame('not_applicable',$a['rows'][0]['status']);$this->assertFalse($a['monthly']['assets'][0]['applied']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}else{
$this->assertSame('absent',$a['status']);$this->assertSame([],$a['monthly']['assets']);$this->assertSame('0',$a['additionalDeduction']['numerator']);
}
file_put_contents(base_path('outputs/irpc-l7-start-period/recovered-'.$case.'.json'),json_encode($back,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
@@ -0,0 +1,41 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {normalBook,normalCurrent,calculateNormal,recordNormal,saveNormalBook,normalHtml} from '../../resources/js/lib/irpc-normal.ts';
import {validateSpecial} from '../../resources/js/lib/irpc-special.ts';
import {fraction} from '../../resources/js/lib/fiscal-rational.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const read=name=>JSON.parse(fs.readFileSync(new URL('./fixtures/'+name,import.meta.url),'utf8'));
const val=v=>v?Number(v.numerator)/Number(v.denominator):null;
function accepted(){const d=read('irpc-l7-preserved.json').acceleration,f=read('irpc-l7-start-preserved.json');d.business_plan_snapshot=f.plan;d.modelo_a_snapshot=saveNormalBook(d,f.book);return{d,b:normalBook(d)};}
function setup(period='cessation',prior=true){
const{d,b}=accepted(),months=period==='annual'?12:6,p=JSON.parse(d.business_plan_snapshot);p.plan.assetDepreciation='120';d.business_plan_snapshot=JSON.stringify(p);
if(period==='annual')delete b.periodsFx;else Object.assign(b.periodsFx,{kind:'cessation',from:'2026-01-01',to:'2026-06-30',reference:'QA cessação documentada30Junho2026;meses completos sem transmissão presumida'});
b.schedules.interest.amount=String(months*20);
Object.assign(b.depreciation.assets[0],{start:prior?'2025-01-01':'2026-01-15',timing:'months',accounting:String(months*10),previousAccounting:prior?'150':'0',previousFiscal:prior?'100':'0',priorAvailable:prior?'50':'0',previousReference:prior?'QA quotas contabilísticas150,fiscais100,parcela50 temporariamente tributada;sem encargos permanentemente excluídos':'QA ausência declarada de quotas anteriores;activo entrou em2026',exitState:'absent',exitDate:''});
for(const part of[b.special.expenses,b.special.cooperative,b.special.acceleration])Object.assign(part.qualification,{from:'2026-01-01',to:period==='annual'?'2026-12-31':'2026-06-30',periodReference:period==='annual'?'QA ano civil2026':b.periodsFx.reference});
delete b.special.acceleration.monthly.startPeriod;
b.special.acceleration.monthly.continuation={version:1,period,reference:'QA CBF16 vigente no sujeito/projecto e período2026 declarado;sem cumulação',historyReference:'QA activo novo2025/2026,método constante e duodécimos desde entrada;quotas anteriores reconciliadas no mapaL6,não recalculadas',monthlyFromStart:'yes'};return{d,b};
}
test('accepted12 result,key and fullhistory remain exact without continuation',()=>{const{d,b}=accepted();assert.equal(normalCurrent(d,b),true);assert.deepEqual(calculateNormal(d,b),b.result.model);assert.deepEqual(normalBook(d).history,b.history);});
test('cessation reuses6 months without assuming assetexit;50 normal,75 accelerated capped60,additional10',()=>{const{d,b}=setup('cessation',false),asset=JSON.stringify(b.depreciation),period=JSON.stringify(b.periodsFx),m=calculateNormal(d,b),s=m.special,a=s.acceleration.monthly.assets[0];assert.equal(m.version,'IRPC-normal-adjustments/13');assert.equal(a.months,6);assert.equal(a.exit.state,'absent');assert.equal(val(a.normalQuota),50);assert.equal(val(a.acceleratedQuota),75);assert.equal(val(a.acceleratedDeduction),60);assert.equal(val(a.additionalDeduction),10);assert.equal(val(m.taxableProfit),3130);assert.equal(val(m.colecta),1001.6);assert.equal(val(s.taxableProfit),3120);assert.equal(val(s.taxableBase),3120);assert.equal(val(s.colecta),998.4);assert.equal(JSON.stringify(b.depreciation),asset);assert.equal(JSON.stringify(b.periodsFx),period);assert.equal(s.finalBalance.payable,null);});
test('cessation with priorbook150,fiscal100,available50 recovers15 once and adds only25 to normaldeduction',()=>{const{d,b}=setup(),m=calculateNormal(d,b),s=m.special,a=s.acceleration.monthly.assets[0];assert.equal(a.months,6);assert.equal(val(a.normalDeduction),50);assert.equal(val(a.acceleratedDeduction),75);assert.equal(val(a.prior.normalUsed),0);assert.equal(val(a.prior.acceleratedUsed),15);assert.equal(val(a.prior.normalRemaining),50);assert.equal(val(a.prior.acceleratedRemaining),35);assert.equal(val(a.prior.normalFiscalRemaining),850);assert.equal(val(a.prior.acceleratedFiscalRemaining),825);assert.equal(val(s.acceleration.additionalDeduction),25);assert.equal(val(s.taxableProfit),3105);assert.equal(val(s.taxableBase),3105);assert.equal(val(s.colecta),993.6);assert.equal(b.depreciation.assets[0].priorAvailable,'50');assert.equal(b.depreciation.assets[0].previousFiscal,'100');});
test('annual2026 continuation preserves2025 actualbalances and records30priorused within150 deduction,additional50',()=>{const{d,b}=setup('annual'),m=calculateNormal(d,b),s=m.special,a=s.acceleration.monthly.assets[0];assert.equal(a.months,12);assert.equal(val(a.normalQuota),100);assert.equal(val(a.acceleratedQuota),150);assert.equal(val(a.prior.acceleratedUsed),30);assert.equal(val(a.prior.acceleratedRemaining),20);assert.equal(val(s.acceleration.additionalDeduction),50);assert.equal(val(m.taxableProfit),6260);assert.equal(val(s.taxableProfit),6210);assert.equal(val(s.colecta),1987.2);assert.deepEqual(s.acceleration.normal.input,s.acceleration.accelerated.input);});
test('documented assetexit excludes eventmonth and keeps exact fractional quotas;cessation date does not edit exit',()=>{const{d,b}=setup();Object.assign(b.depreciation.assets[0],{exitState:'known',exitDate:'2026-06-20'});const a=calculateNormal(d,b).special.acceleration.monthly.assets[0];assert.equal(a.months,5);assert.deepEqual(a.normalQuota,fraction(125n,3n));assert.deepEqual(a.acceleratedQuota,fraction(125n,2n));assert.deepEqual(a.additionalDeduction,fraction(125n,6n));assert.deepEqual(a.prior.acceleratedUsed,fraction(5n,2n));assert.deepEqual(a.prior.acceleratedRemaining,fraction(95n,2n));});
test('remaining fiscalbalance and accounted/priorcaps bind both calculations;available amount is never a second deduction',()=>{const{d,b}=setup();Object.assign(b.depreciation.assets[0],{previousAccounting:'1000',previousFiscal:'980',priorAvailable:'20'});let a=calculateNormal(d,b).special.acceleration.monthly.assets[0];assert.equal(val(a.normalDeduction),20);assert.equal(val(a.acceleratedDeduction),20);assert.equal(val(a.additionalDeduction),0);assert.equal(val(a.prior.acceleratedFiscalRemaining),0);const second=setup(),p=JSON.parse(second.d.business_plan_snapshot);p.plan.assetDepreciation='0';second.d.business_plan_snapshot=JSON.stringify(p);second.b.depreciation.assets[0].accounting='0';a=calculateNormal(second.d,second.b).special.acceleration.monthly.assets[0];assert.equal(val(a.normalDeduction),50);assert.equal(val(a.acceleratedDeduction),50);assert.equal(val(a.additionalDeduction),0);assert.equal(val(a.prior.acceleratedRemaining),0);});
test('missing support or missing priorbalance blocks only dependent CBF16;absence and negative remain explicit',()=>{for(const key of['reference','historyReference','monthlyFromStart']){const{d,b}=setup();b.special.acceleration.monthly.continuation[key]='';const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.notEqual(m.colecta,null);}const missing=setup();missing.b.depreciation.assets[0].previousFiscal='';const pending=calculateNormal(missing.d,missing.b);assert.equal(pending.special.acceleration.additionalDeduction,null);assert.match(pending.depreciation.pending.join(' '),/em falta/);assert.equal(missing.b.depreciation.assets[0].previousFiscal,'');for(const state of['negative','absent']){const{d,b}=setup();if(state==='negative')b.special.acceleration.rows[0].eligible='no';else{b.special.acceleration.rows=[];Object.assign(b.special.acceleration.qualification,{state:'absent',eligible:''});}const s=calculateNormal(d,b).special;assert.equal(val(s.acceleration.additionalDeduction),0);assert.equal(s.acceleration.status,state==='absent'?'absent':'calculated');if(state==='negative')assert.equal(s.acceleration.rows[0].status,'not_applicable');}});
test('otherstartyears,nonmonthlyhistory,transition,cumulation and prioramounts for currentyearentry stay out of scope',()=>{for(const mutate of[b=>b.depreciation.assets[0].start='2024-01-01',b=>b.special.acceleration.monthly.continuation.monthlyFromStart='no',b=>b.periodsFx.kind='transition',b=>b.special.acceleration.noOtherBenefits='no',b=>b.depreciation.assets[0].start='2026-01-01']){const{d,b}=setup();mutate(b);const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.notEqual(m.colecta,null);}});
test('save-recover13 preserves12result and allhistorical balances;recalc idempotent and reports reconciliation without officialconsumption',()=>{const{d,b}=setup(),history=structuredClone(b.history),old=structuredClone(b.result),asset=JSON.stringify(b.depreciation),plan=d.business_plan_snapshot,others=JSON.parse(d.modelo_a_snapshot).irpcWithholdings;d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));let back=normalBook(JSON.parse(JSON.stringify(d)));assert.equal(normalCurrent(d,back),true);assert.deepEqual(back.history,[...history,old]);assert.equal(old.model.version,'IRPC-normal-adjustments/12');assert.equal(JSON.stringify(back.depreciation),asset);assert.equal(d.business_plan_snapshot,plan);assert.deepEqual(JSON.parse(d.modelo_a_snapshot).irpcWithholdings,others);const html=normalHtml(d);assert.match(html,/2026-01-01–2026-06-30/);assert.match(html,/recuperada CBF16:15.00/);assert.match(html,/saldo anterior aritmético CBF16:35.00/);assert.match(html,/sem consumo de saldos oficiais/);assert.match(html,/colecta sobre a base:993.60/);assert.match(html,/Saldo final a pagar\/recuperar:Indeterminado/);assert.match(JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance'])})),/quotas contabilísticas anteriores/);d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,back));back=normalBook(d);assert.equal(val(back.result.model.special.acceleration.additionalDeduction),25);assert.equal(back.depreciation.assets[0].priorAvailable,'50');back.depreciation.assets[0].previousFiscal='110';assert.equal(normalCurrent(d,back),false);});
test('invalid or overlapping optionalpreparation cannot replace preservedbooks',()=>{for(const c of[null,{version:2,period:'annual',reference:'QA',historyReference:'QA',monthlyFromStart:'yes'},{version:1,period:'other',reference:'QA',historyReference:'QA',monthlyFromStart:'yes'}]){const{b}=setup();b.special.acceleration.monthly.continuation=c;assert.throws(()=>validateSpecial(b.special),/não recuperável/);}const{b}=setup();b.special.acceleration.monthly.startPeriod={version:1,reference:'QA'};assert.throws(()=>validateSpecial(b.special),/incompatível/);});
test('prepare only compatible new guardedAPI cases with missing,negative and absence variants',()=>{const cases={cessation:setup('cessation',false),prior:setup(),annual:setup('annual'),exit:setup(),missing:setup(),negative:setup(),absent:setup()};Object.assign(cases.exit.b.depreciation.assets[0],{exitState:'known',exitDate:'2026-06-20'});cases.missing.b.special.acceleration.monthly.continuation.historyReference='';cases.negative.b.special.acceleration.rows[0].eligible='no';cases.absent.b.special.acceleration.rows=[];Object.assign(cases.absent.b.special.acceleration.qualification,{state:'absent',eligible:''});fs.mkdirSync('outputs/irpc-l7-cessation-prior',{recursive:true});for(const[name,{d,b}]of Object.entries(cases)){d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b,'2026-10-26T18:00:00+02:00'));fs.writeFileSync('outputs/irpc-l7-cessation-prior/'+name+'.json',JSON.stringify(d));fs.writeFileSync('outputs/irpc-l7-cessation-prior/'+name+'.html',normalHtml(d));}});
@@ -0,0 +1,30 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {normalBook,normalCurrent,calculateNormal,recordNormal,saveNormalBook,normalHtml} from '../../resources/js/lib/irpc-normal.ts';
import {newSpecialInput,validateSpecial} from '../../resources/js/lib/irpc-special.ts';
import {fraction} from '../../resources/js/lib/fiscal-rational.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const frozen=()=>JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-l7-preserved.json',import.meta.url),'utf8'));
const val=v=>v?Number(v.numerator)/Number(v.denominator):null;
const q=state=>({state,eligible:state==='known'?'yes':'',from:'2026-01-01',to:'2026-12-31',reference:'QA condições/ausência documentadas no sujeito/projecto',periodReference:'QA ano civil2026,CBF16 e Decreto72/2013art9'});
function setup(account='60',start='2026-07-15'){
const d=frozen().acceleration,b=normalBook(d),p=JSON.parse(d.business_plan_snapshot);p.plan.assetDepreciation=account;d.business_plan_snapshot=JSON.stringify(p);
Object.assign(b.depreciation.assets[0],{accounting:account,start,timing:'months'});
b.special.acceleration.monthly={version:1,reference:'QA opção de duodécimos desde a entrada emuso,datas/meses do mesmo activoL6'};return{d,b};
}
test('accepted10 books remain current and reproduce exact original expense,cooperative and annualasset models;history is read unchanged',()=>{for(const[name,d]of Object.entries(frozen())){const b=normalBook(d),original=structuredClone(b.result);assert.equal(normalCurrent(d,b),true,name);assert.deepEqual(calculateNormal(d,b),original.model,name);assert.deepEqual(normalBook(d).result,original,name);}});
test('explicit monthly11 reuses6 L6months and limits75quota to60accounted,adding only10deduction',()=>{const{d,b}=setup(),original=JSON.stringify(b.depreciation),m=calculateNormal(d,b),s=m.special,a=s.acceleration.monthly.assets[0];assert.equal(m.version,'IRPC-normal-adjustments/11');assert.equal(a.months,6);assert.equal(val(a.normalRate),10);assert.equal(val(a.acceleratedRate),15);assert.equal(val(a.normalQuota),50);assert.equal(val(a.acceleratedQuota),75);assert.equal(val(a.normalDeduction),50);assert.equal(val(a.acceleratedDeduction),60);assert.equal(val(a.additionalDeduction),10);assert.equal(val(m.taxableProfit),6310);assert.equal(val(m.colecta),2019.2);assert.equal(val(s.taxableProfit),6300);assert.equal(val(s.taxableBase),6300);assert.equal(val(s.colecta),2016);assert.equal(s.finalBalance.payable,null);assert.equal(JSON.stringify(b.depreciation),original);});
test('month timing comes from L6 including midmonth entry,January,October and December;never dailyproration',()=>{for(const[start,account,months,normal,accelerated]of[['2026-01-01','120',12,100,150],['2026-07-31','60',6,50,75],['2026-10-20','60',3,25,37.5],['2026-12-31','20',1,100/12,12.5]]){const{d,b}=setup(account,start),m=calculateNormal(d,b),a=m.special.acceleration.monthly.assets[0];assert.equal(a.months,months);assert.equal(val(a.normalQuota),normal);assert.equal(val(a.acceleratedQuota),accelerated);assert.equal(a.months,m.depreciation.assets[0].months);}});
test('December retains exact fractional difference and report never rounds fiscal amount',()=>{const{d,b}=setup('20','2026-12-15'),m=calculateNormal(d,b),a=m.special.acceleration.monthly.assets[0];assert.deepEqual(a.normalQuota,fraction(25n,3n));assert.deepEqual(a.acceleratedQuota,fraction(25n,2n));assert.deepEqual(a.additionalDeduction,fraction(25n,6n));d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));assert.match(normalHtml(d),/25\/6/);assert.match(normalHtml(d),/≈/);});
test('accounted caps of0,40,60,100 remain binding and no additional quota is invented',()=>{for(const[account,normal,accelerated,diff]of[['0',0,0,0],['40',40,40,0],['60',50,60,10],['100',50,75,25]]){const{d,b}=setup(account),s=calculateNormal(d,b).special,a=s.acceleration.monthly.assets[0];assert.equal(val(a.normalDeduction),normal);assert.equal(val(a.acceleratedDeduction),accelerated);assert.equal(val(s.acceleration.additionalDeduction),diff);}});
test('new project building reuses land/residual basis and existing2percent table rate with monthlycap',()=>{const{d,b}=setup('50');Object.assign(b.depreciation.assets[0],{category:'commercial_building',cost:'5000',land:'1000',rate:'2'});b.special.acceleration.rows[0].kind='new_project_building';const a=calculateNormal(d,b).special.acceleration.monthly.assets[0];assert.equal(val(a.taxBasis),4000);assert.equal(val(a.normalQuota),40);assert.equal(val(a.acceleratedQuota),60);assert.equal(val(a.acceleratedDeduction),50);assert.equal(val(a.additionalDeduction),10);});
test('other existing assets stay on their normal quota;selected asset is neither copied nor deducted twice',()=>{const{d,b}=setup('80'),other=structuredClone(b.depreciation.assets[0]);b.depreciation.assets[0].accounting='60';Object.assign(other,{id:'other',assetKey:'other',document:'QA-other',description:'Mobiliário foraCBF16',category:'furniture',cost:'200',rate:'10',start:'2026-01-01',timing:'annual',accounting:'20'});b.depreciation.assets.push(other);const s=calculateNormal(d,b).special;assert.equal(s.acceleration.normal.assets.length,2);assert.equal(s.acceleration.accelerated.assets.length,2);assert.deepEqual(s.acceleration.normal.assets[1],s.acceleration.accelerated.assets[1]);assert.equal(val(s.acceleration.additionalDeduction),10);});
test('missingmonthlysupport blocks only CBF16 totals;normalreference and storedinput are retained',()=>{const{d,b}=setup();b.special.acceleration.monthly.reference='';const m=calculateNormal(d,b);assert.equal(m.special.acceleration.status,'indeterminate');assert.equal(m.special.acceleration.additionalDeduction,null);assert.equal(val(m.colecta),2019.2);assert.equal(m.special.acceleration.monthly.assets[0].acceleratedQuota,null);assert.match(m.special.acceleration.reason,/Falta suporte/);});
test('negative condition,declaredabsence and missingqualification have distinct monthly outcomes',()=>{const negative=setup();negative.b.special.acceleration.rows[0].eligible='no';let s=calculateNormal(negative.d,negative.b).special;assert.equal(s.acceleration.rows[0].status,'not_applicable');assert.equal(val(s.acceleration.additionalDeduction),0);assert.equal(s.acceleration.monthly.assets[0].applied,false);assert.equal(s.acceleration.monthly.assets[0].acceleratedRate,null);for(const state of['absent','']){const{d,b}=setup();b.special.acceleration.rows=[];b.special.acceleration.qualification=q(state);b.special.acceleration.monthly.reference='';s=calculateNormal(d,b).special;assert.equal(s.acceleration.status,state==='absent'?'absent':'indeterminate');assert.equal(val(s.acceleration.additionalDeduction),state==='absent'?0:null);}});
test('newmonthlyscope excludes priorquotas,annualoption,exits and earlier/laterentry while retaining L6 reference',()=>{for(const mutate of[a=>a.previousAccounting='1',a=>a.timing='annual',a=>{a.exitState='known';a.exitDate='2026-12-01';},a=>a.start='2025-07-01',a=>a.start='2027-01-01']){const{d,b}=setup();mutate(b.depreciation.assets[0]);const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.notEqual(m.taxableProfit,null);assert.equal(m.special.acceleration.status,'indeterminate');}});
test('short fiscalperiod already supported in L6 is not silently included in this annual CBF16 increment',()=>{const d=JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-l6-values-preserved.json',import.meta.url),'utf8')),b=normalBook(d),model=setup().b.special;b.special=structuredClone(model);for(const part of[b.special.expenses,b.special.cooperative,b.special.acceleration])part.qualification={...part.qualification,from:'2026-07-01'};Object.assign(b.depreciation.assets[0],{category:'machine',cost:'1000',rate:'10',accounting:'60',timing:'months',start:'2026-07-01'});const m=calculateNormal(d,b);assert.notEqual(m.colecta,null);assert.equal(m.special.acceleration.additionalDeduction,null);assert.match(m.special.acceleration.reason,/exercício anual civil2026/);});
test('monthlyexplicitoption never selects CBF from location;missingeligibility evidence remains pending',()=>{const{d,b}=setup();d.province_id='QA-ZEE-candidate';b.special.acceleration.recognitionReference='';const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.notEqual(m.colecta,null);assert.match(m.special.acceleration.reason,/reconhecimento10/);});
test('version11 save-recover preserves10history,originalasset,plan and otherbooks;recalculate stays idempotent',()=>{const{d,b}=setup(),old=structuredClone(b.result),asset=JSON.stringify(b.depreciation),plan=d.business_plan_snapshot;d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));let back=normalBook(JSON.parse(JSON.stringify(d)));assert.equal(normalCurrent(d,back),true);assert.deepEqual(back.history.at(-1),old);assert.equal(back.history.at(-1).model.version,'IRPC-normal-adjustments/10');assert.equal(JSON.stringify(back.depreciation),asset);assert.equal(d.business_plan_snapshot,plan);assert.ok(JSON.parse(d.modelo_a_snapshot).irpcWithholdings);const html=normalHtml(d);assert.match(html,/duodécimosL6:6/);assert.match(html,/diferença adicional:10.00/);assert.match(html,/Saldo final a pagar\/recuperar:Indeterminado/);assert.match(JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance'])})),/CBF16 por duodécimos/);d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,back));back=normalBook(d);assert.equal(val(back.result.model.special.acceleration.additionalDeduction),10);assert.equal(val(back.result.model.special.colecta),2016);back.depreciation.assets[0].start='2026-10-01';assert.equal(normalCurrent(d,back),false);});
test('malformed optionalmonthly schema cannot overwrite oldbooks',()=>{for(const value of[null,{version:2,reference:'QA'},{version:1,reference:12}]){const{b}=setup();b.special.acceleration.monthly=value;assert.throws(()=>validateSpecial(b.special),/não recuperável/);}});
test('newmonthlycases only prepare guardedprivateAPI inputs and reports',()=>{const cases={monthly:setup(),fraction:setup('20','2026-12-15'),missing:setup(),negative:setup(),absent:setup()};cases.missing.b.special.acceleration.monthly.reference='';cases.negative.b.special.acceleration.rows[0].eligible='no';cases.absent.b.special.acceleration.qualification=q('absent');cases.absent.b.special.acceleration.rows=[];fs.mkdirSync('outputs/irpc-l7-months',{recursive:true});for(const[name,{d,b}]of Object.entries(cases)){d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b,'2026-10-26T16:00:00+02:00'));fs.writeFileSync('outputs/irpc-l7-months/'+name+'.json',JSON.stringify(d));fs.writeFileSync('outputs/irpc-l7-months/'+name+'.html',normalHtml(d));}});
@@ -0,0 +1,37 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {normalBook,normalCurrent,calculateNormal,recordNormal,saveNormalBook,normalHtml} from '../../resources/js/lib/irpc-normal.ts';
import {validateSpecial} from '../../resources/js/lib/irpc-special.ts';
import {fraction} from '../../resources/js/lib/fiscal-rational.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const read=name=>JSON.parse(fs.readFileSync(new URL('./fixtures/'+name,import.meta.url),'utf8'));
const val=v=>v?Number(v.numerator)/Number(v.denominator):null;
function accepted(){const d=read('irpc-l7-preserved.json').acceleration,f=read('irpc-l7-monthly-preserved.json');d.business_plan_snapshot=f.plan;d.modelo_a_snapshot=saveNormalBook(d,f.book);return{d,b:normalBook(d)};}
function setup(month=7){
const{d,b}=accepted(),p=JSON.parse(d.business_plan_snapshot);p.plan.assetDepreciation='120';d.business_plan_snapshot=JSON.stringify(p);
const old=normalBook(read('irpc-l6-values-preserved.json'));b.periodsFx=structuredClone(old.periodsFx);b.periodsFx.from='2026-'+String(month).padStart(2,'0')+'-01';
b.periodsFx.reference='QA início documentado em'+b.periodsFx.from+';meses completos até31/12';
delete b.forms;const months=13-month;b.schedules.interest.amount=String(months*20);
Object.assign(b.depreciation.assets[0],{accounting:String(months*10),start:b.periodsFx.from.slice(0,8)+'15',timing:'months'});
for(const part of[b.special.expenses,b.special.cooperative,b.special.acceleration])Object.assign(part.qualification,{from:b.periodsFx.from,periodReference:b.periodsFx.reference});
b.special.acceleration.monthly.startPeriod={version:1,reference:'QA início de actividade residente2026,CBF16 e períodoL6 reconciliados'};return{d,b};
}
test('accepted11 result and currentkey remain exact without startPeriod;10 histories still readable',()=>{const{d,b}=accepted();assert.equal(normalCurrent(d,b),true);assert.deepEqual(calculateNormal(d,b),b.result.model);const old=read('irpc-l7-preserved.json').acceleration;assert.equal(normalCurrent(old,normalBook(old)),true);});
test('resident July start reuses6 actualmonths,50 normalquota,75 accelerated capped60;only10 additional',()=>{const{d,b}=setup(),asset=JSON.stringify(b.depreciation),plan=d.business_plan_snapshot,m=calculateNormal(d,b),s=m.special,a=s.acceleration.monthly.assets[0];assert.equal(m.version,'IRPC-normal-adjustments/12');assert.equal(m.periodsFx.short,true);assert.equal(a.months,6);assert.equal(val(a.normalQuota),50);assert.equal(val(a.acceleratedQuota),75);assert.equal(val(a.acceleratedDeduction),60);assert.equal(val(s.acceleration.additionalDeduction),10);assert.equal(val(m.taxableProfit),3130);assert.equal(val(m.taxableBase),3130);assert.equal(val(m.colecta),1001.6);assert.equal(val(s.taxableProfit),3120);assert.equal(val(s.taxableBase),3120);assert.equal(val(s.colecta),998.4);assert.equal(s.finalBalance.payable,null);assert.equal(s.acceleration.accelerated.assets.length,b.depreciation.assets.length);assert.equal(JSON.stringify(b.depreciation),asset);assert.equal(d.business_plan_snapshot,plan);assert.match(s.acceleration.source,/início de actividade/);assert.doesNotMatch(s.acceleration.source,/primeiro exercício anual/);});
test('October and December use3 and1 months without annualisation and retain exact fiscalfraction',()=>{for(const[month,months,diff]of[[10,3,fraction(5n)],[12,1,fraction(5n,3n)]]){const{d,b}=setup(month),m=calculateNormal(d,b),a=m.special.acceleration.monthly.assets[0];assert.equal(m.periodsFx.months,months);assert.equal(a.months,months);assert.deepEqual(a.additionalDeduction,diff);assert.deepEqual(a.normalQuota,fraction(BigInt(months)*25n,3n));d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));assert.match(normalHtml(d),new RegExp('duodécimosL6:'+months));if(month===12)assert.match(normalHtml(d),/5\/3/);}});
test('missing start evidence blocks only L7;absent and negative remain distinct withnormal totals',()=>{const missing=setup();missing.b.special.acceleration.monthly.startPeriod.reference='';let m=calculateNormal(missing.d,missing.b);assert.equal(m.special.acceleration.status,'indeterminate');assert.equal(m.special.acceleration.additionalDeduction,null);assert.equal(val(m.colecta),1001.6);assert.match(m.special.acceleration.reason,/Falta suporte do período curto/);for(const state of['negative','absent']){const{d,b}=setup();if(state==='negative')b.special.acceleration.rows[0].eligible='no';else{b.special.acceleration.rows=[];Object.assign(b.special.acceleration.qualification,{state:'absent',eligible:''});}m=calculateNormal(d,b);assert.equal(val(m.special.acceleration.additionalDeduction),0);assert.equal(m.special.acceleration.status,state==='absent'?'absent':'calculated');assert.equal(val(m.special.colecta),1001.6);if(state==='negative')assert.equal(m.special.acceleration.rows[0].status,'not_applicable');}});
test('cessation,otherperiodkind,nonresident,previousyearentry,priorquotas and exits remain outside newrecorte',()=>{for(const mutate of[b=>b.periodsFx.kind='same_year',b=>{b.periodsFx.kind='cessation';b.periodsFx.from='2026-01-01';b.periodsFx.to='2026-06-30';},b=>b.scope='ep_general',b=>b.depreciation.assets[0].start='2026-06-01',b=>b.depreciation.assets[0].previousAccounting='1',b=>{b.depreciation.assets[0].exitState='known';b.depreciation.assets[0].exitDate='2026-12-01';}]){const{d,b}=setup();mutate(b);const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.equal(m.special.acceleration.status,'indeterminate');assert.notEqual(m.taxableProfit,null);}});
test('short fiscalperiod remains unsupported in11 unless explicitly prepared;cancel returns same11 decision',()=>{const{d,b}=setup(),period=JSON.stringify(b.periodsFx),asset=JSON.stringify(b.depreciation);delete b.special.acceleration.monthly.startPeriod;const m=calculateNormal(d,b);assert.equal(m.version,'IRPC-normal-adjustments/11');assert.equal(m.special.acceleration.additionalDeduction,null);assert.match(m.special.acceleration.reason,/exercício anual civil2026/);assert.equal(JSON.stringify(b.periodsFx),period);assert.equal(JSON.stringify(b.depreciation),asset);});
test('save-recover12 keeps11result verbatim,originalassets,otherbooks and fractional report;recalc is idempotent',()=>{const{d,b}=setup(),old=structuredClone(b.result),history=structuredClone(b.history),asset=JSON.stringify(b.depreciation),plan=d.business_plan_snapshot,others=JSON.parse(d.modelo_a_snapshot);d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));let back=normalBook(JSON.parse(JSON.stringify(d)));assert.equal(normalCurrent(d,back),true);assert.deepEqual(back.history,[...history,old]);assert.deepEqual(back.history.at(-1),old);assert.equal(back.history.at(-1).model.version,'IRPC-normal-adjustments/11');assert.equal(JSON.stringify(back.depreciation),asset);assert.equal(d.business_plan_snapshot,plan);assert.deepEqual(JSON.parse(d.modelo_a_snapshot).irpcWithholdings,others.irpcWithholdings);const html=normalHtml(d);assert.match(html,/2026-07-01–2026-12-31/);assert.match(html,/dedução adicional conciliada:10.00/);assert.match(html,/colecta sobre a base:998.40/);assert.match(html,/Saldo final a pagar\/recuperar:Indeterminado/);assert.match(JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance'])})),/início de actividade/);d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,back));back=normalBook(d);assert.equal(val(back.result.model.special.acceleration.additionalDeduction),10);assert.equal(val(back.result.model.special.colecta),998.4);back.periodsFx.from='2026-10-01';assert.equal(normalCurrent(d,back),false);});
test('invalid startPeriod child cannot replace originalbooks',()=>{for(const child of[null,{version:2,reference:'QA'},{version:1,reference:3}]){const{b}=setup();b.special.acceleration.monthly.startPeriod=child;assert.throws(()=>validateSpecial(b.special),/não recuperável/);}});
test('prepare only new guardedAPI cases and reports',()=>{const cases={start:setup(),fraction:setup(12),missing:setup(),negative:setup(),absent:setup()};cases.missing.b.special.acceleration.monthly.startPeriod.reference='';cases.negative.b.special.acceleration.rows[0].eligible='no';cases.absent.b.special.acceleration.rows=[];Object.assign(cases.absent.b.special.acceleration.qualification,{state:'absent',eligible:''});fs.mkdirSync('outputs/irpc-l7-start-period',{recursive:true});for(const[name,{d,b}]of Object.entries(cases)){d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b,'2026-10-26T17:00:00+02:00'));fs.writeFileSync('outputs/irpc-l7-start-period/'+name+'.json',JSON.stringify(d));fs.writeFileSync('outputs/irpc-l7-start-period/'+name+'.html',normalHtml(d));}});
+21
View File
@@ -0,0 +1,21 @@
<?php
$root=dirname(__DIR__);
$operation=$argv[1]??'';
if(!in_array($operation,['routes','test'],true)||basename($root)!=='portal-investidor-irpc-l7-common-qa-20261026')throw new RuntimeException('Explicit L7 QA workspace and routes/test operation required.');
foreach(['storage/framework/views','storage/framework/cache','storage/framework/sessions','bootstrap/cache','storage/logs','outputs/irpc-l7-cessation-prior']as$dir)if(!is_dir($root.'/'.$dir))mkdir($root.'/'.$dir,0700,true);
foreach(['APP_BASE_PATH'=>$root,'APP_ENV'=>'testing','APP_KEY'=>'base64:'.base64_encode(str_repeat('Q',32)),'DB_CONNECTION'=>'pgsql','DB_HOST'=>'127.0.0.1','DB_PORT'=>'55441','DB_DATABASE'=>'simulator_fiscal_delta_20261021_test','DB_USERNAME'=>'postgres','DB_PASSWORD'=>'','DB_URL'=>'','CACHE_STORE'=>'array','SESSION_DRIVER'=>'array','QUEUE_CONNECTION'=>'sync','MAIL_MAILER'=>'array'] as $k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
$loader=require $root.'/vendor/autoload.php';
spl_autoload_register(function($class)use($root){foreach(['App\\'=>'app/','Tests\\'=>'tests/','Database\\Factories\\'=>'database/factories/']as$prefix=>$dir){if(str_starts_with($class,$prefix)){$file=$root.'/'.$dir.str_replace('\\','/',substr($class,strlen($prefix))).'.php';if(is_file($file)){require $file;return;}}}},true,true);
$app=require $root.'/bootstrap/app.php';
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.pgsql');
if($app->configurationIsCached()||$c['host']!=='127.0.0.1'||(int)$c['port']!==55441||$c['database']!=='simulator_fiscal_delta_20261021_test'||!empty($c['url']))throw new RuntimeException('QA guard');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$c['database'],$c['username'],$c['password']);
if($pdo->query('select current_database()')->fetchColumn()!==$c['database'])throw new RuntimeException('QA identity');
if($operation==='routes'){
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$status=Illuminate\Support\Facades\Artisan::call('wayfinder:generate',['--with-form'=>true]);
echo Illuminate\Support\Facades\Artisan::output();exit($status);
}
$argv=['phpunit','-c','phpunit.investmoz.xml','tests/Feature/IrpcSpecialCessationPriorDraftTest.php'];$argc=count($argv);$_SERVER['argv']=$argv;$_SERVER['argc']=$argc;require $root.'/vendor/phpunit/phpunit/phpunit';
+21
View File
@@ -0,0 +1,21 @@
<?php
$root=dirname(__DIR__);
$operation=$argv[1]??'';
if(!in_array($operation,['routes','test'],true)||basename($root)!=='portal-investidor-irpc-l7-common-qa-20261026')throw new RuntimeException('Explicit L7 QA workspace and routes/test operation required.');
foreach(['storage/framework/views','storage/framework/cache','storage/framework/sessions','bootstrap/cache','storage/logs','outputs/irpc-l7-months']as$dir)if(!is_dir($root.'/'.$dir))mkdir($root.'/'.$dir,0700,true);
foreach(['APP_BASE_PATH'=>$root,'APP_ENV'=>'testing','APP_KEY'=>'base64:'.base64_encode(str_repeat('Q',32)),'DB_CONNECTION'=>'pgsql','DB_HOST'=>'127.0.0.1','DB_PORT'=>'55441','DB_DATABASE'=>'simulator_fiscal_delta_20261021_test','DB_USERNAME'=>'postgres','DB_PASSWORD'=>'','DB_URL'=>'','CACHE_STORE'=>'array','SESSION_DRIVER'=>'array','QUEUE_CONNECTION'=>'sync','MAIL_MAILER'=>'array'] as $k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
$loader=require $root.'/vendor/autoload.php';
spl_autoload_register(function($class)use($root){foreach(['App\\'=>'app/','Tests\\'=>'tests/','Database\\Factories\\'=>'database/factories/']as$prefix=>$dir){if(str_starts_with($class,$prefix)){$file=$root.'/'.$dir.str_replace('\\','/',substr($class,strlen($prefix))).'.php';if(is_file($file)){require $file;return;}}}},true,true);
$app=require $root.'/bootstrap/app.php';
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.pgsql');
if($app->configurationIsCached()||$c['host']!=='127.0.0.1'||(int)$c['port']!==55441||$c['database']!=='simulator_fiscal_delta_20261021_test'||!empty($c['url']))throw new RuntimeException('QA guard');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$c['database'],$c['username'],$c['password']);
if($pdo->query('select current_database()')->fetchColumn()!==$c['database'])throw new RuntimeException('QA identity');
if($operation==='routes'){
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$status=Illuminate\Support\Facades\Artisan::call('wayfinder:generate',['--with-form'=>true]);
echo Illuminate\Support\Facades\Artisan::output();exit($status);
}
$argv=['phpunit','-c','phpunit.investmoz.xml','tests/Feature/IrpcSpecialMonthlyDraftTest.php'];$argc=count($argv);$_SERVER['argv']=$argv;$_SERVER['argc']=$argc;require $root.'/vendor/phpunit/phpunit/phpunit';
+21
View File
@@ -0,0 +1,21 @@
<?php
$root=dirname(__DIR__);
$operation=$argv[1]??'';
if(!in_array($operation,['routes','test'],true)||basename($root)!=='portal-investidor-irpc-l7-common-qa-20261026')throw new RuntimeException('Explicit L7 QA workspace and routes/test operation required.');
foreach(['storage/framework/views','storage/framework/cache','storage/framework/sessions','bootstrap/cache','storage/logs','outputs/irpc-l7-start-period']as$dir)if(!is_dir($root.'/'.$dir))mkdir($root.'/'.$dir,0700,true);
foreach(['APP_BASE_PATH'=>$root,'APP_ENV'=>'testing','APP_KEY'=>'base64:'.base64_encode(str_repeat('Q',32)),'DB_CONNECTION'=>'pgsql','DB_HOST'=>'127.0.0.1','DB_PORT'=>'55441','DB_DATABASE'=>'simulator_fiscal_delta_20261021_test','DB_USERNAME'=>'postgres','DB_PASSWORD'=>'','DB_URL'=>'','CACHE_STORE'=>'array','SESSION_DRIVER'=>'array','QUEUE_CONNECTION'=>'sync','MAIL_MAILER'=>'array'] as $k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
$loader=require $root.'/vendor/autoload.php';
spl_autoload_register(function($class)use($root){foreach(['App\\'=>'app/','Tests\\'=>'tests/','Database\\Factories\\'=>'database/factories/']as$prefix=>$dir){if(str_starts_with($class,$prefix)){$file=$root.'/'.$dir.str_replace('\\','/',substr($class,strlen($prefix))).'.php';if(is_file($file)){require $file;return;}}}},true,true);
$app=require $root.'/bootstrap/app.php';
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.pgsql');
if($app->configurationIsCached()||$c['host']!=='127.0.0.1'||(int)$c['port']!==55441||$c['database']!=='simulator_fiscal_delta_20261021_test'||!empty($c['url']))throw new RuntimeException('QA guard');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$c['database'],$c['username'],$c['password']);
if($pdo->query('select current_database()')->fetchColumn()!==$c['database'])throw new RuntimeException('QA identity');
if($operation==='routes'){
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$status=Illuminate\Support\Facades\Artisan::call('wayfinder:generate',['--with-form'=>true]);
echo Illuminate\Support\Facades\Artisan::output();exit($status);
}
$argv=['phpunit','-c','phpunit.investmoz.xml','tests/Feature/IrpcSpecialStartPeriodDraftTest.php'];$argc=count($argv);$_SERVER['argv']=$argv;$_SERVER['argc']=$argc;require $root.'/vendor/phpunit/phpunit/phpunit';