"""Reconcile current QA evidence into existing reports; no database or new matrix.""" import json import xml.etree.ElementTree as ET from pathlib import Path from datetime import datetime, timezone root = Path(__file__).resolve().parent.parent private = root / 'storage/app/private/investmoz-v2/portal-audit' docs = root / 'docs/investmoz/v2/auditoria-portal' runtime = json.loads((private / 'investor-path-qa-runtime.json').read_text(encoding='utf-8-sig')) http = json.loads((private / 'investor-path-http-qa.json').read_text(encoding='utf-8-sig')) assert http['target'] == runtime['target'] and http['api_persistence_passed'] assert not http['integrated_ui_ab_passed'] and http['active_writes'] == 0 proof_file = private / 'investor-path-evidence.json' proof = json.loads(proof_file.read_text(encoding='utf-8-sig')) calculation = json.loads((private / 'investor-path-recovered-calculations.json').read_text(encoding='utf-8-sig')) assert calculation['passed'] and calculation['target'] == runtime['target'] and not calculation['interface_observed'] old = private / 'investor-path-evidence-before-continuation.json' if not old.exists(): old.write_text(json.dumps(proof, indent=2), encoding='utf-8') proof['previous_full_suite'] = proof.get('previous_full_suite', {**proof['full_suite'], 'code_hash': proof['code_hash'], 'scope': 'Previous full regression; no per-requirement or current UI acceptance'}) proof.update(runtime) selected = [] for name in ['continuation-consumer-qa.xml', 'continuation-profile-qa.xml', 'continuation-install-qa.xml', 'continuation-business-journey-qa.xml']: tree = ET.parse(private / name) cases = list(tree.iter('testcase')) assert cases and all(not list(case) for case in cases), f'Failure/skip in {name}' selected.append({'junit': name, 'tests': len(cases), 'assertions': sum(int(c.get('assertions', 0)) for c in cases), 'result': 'passed', 'cases': [{'class': c.get('class'), 'method': c.get('name'), 'assertions': int(c.get('assertions', 0))} for c in cases]}) proof.update({'current_selected_suites': selected, 'real_http_ab_evidence': 'investor-path-http-qa.json', 'new_authenticated_http_session_recovered': True, 'integrated_ui_ab_passed': False, 'cartography_current_qa_evidence': 'geometry-consumers-path-qa.json', 'current_frontend_directed_tests': 7, 'manual_script': 'roteiro-manual-qa-i0-i3.md', 'activation_ready': False, 'actual_recovered_calculations': 'investor-path-recovered-calculations.json', 'qa_demonstrated': 'Real authenticated HTTP/new cookie sessions A/B plus API/persistence/profile criteria; UI pending', 'remaining': ['A/B browser interface and new browser session', 'Visual country/origin/statistics per form', 'Each selector/map consumer rendering, including C27', 'Workflow and specialized contracts', 'Visual authenticated cartography import/reversal', 'Final backup/restore/compatibility renewal after visual demonstration'], 'browser': {'apps': [], 'browsers': [], 'reset_rechecked': True, 'failed_providers': ['iab', 'chrome', 'edge'], 'qa_login_http': 200, 'cause': 'No browser provider exposed; connection/registration root cause not established', 'visual_verified': False}}) proof_file.write_text(json.dumps(proof, ensure_ascii=False, indent=2), encoding='utf-8') def insert(filename, heading, body): file = docs / filename text = file.read_text(encoding='utf-8-sig') block = heading + '\n\n' + body.strip() + '\n\n' start = text.find(heading + '\n') if start >= 0: end = text.find('\n## ', start + len(heading)) text = text[:start] + block + (text[end + 1:] if end >= 0 else '') else: first = text.find('\n') text = text[:first + 1] + '\n' + block + text[first + 1:].lstrip('\n') file.write_text(text, encoding='utf-8') insert('relatorio-executivo.md', '## Continuação atual — prova HTTP, cobertura por formulário e interface pendente', ''' **I0–I3 continuam parciais; nenhuma escrita ativa.** A/B passaram no servidor QA real18097: login → criação/gravação → logout → nova sessão/cookies/login → recuperação → aplicabilidade → ferramenta/entradas congeladas → resultado no dossier → rascunho Balcão → acompanhamento interno. Outra conta403/404; troca de contexto403; gestor não lê draft/resultado financeiro privado. Tarefa de mercado concluída enquanto terra aguarda. QA web{runtime['qa_path_journeys']} instâncias/{runtime['qa_path_steps']} etapas; inclui os dossiers sintéticos preservados e a continuação com MFA quando demonstrada. Não importar fixtures no ativo. País/origem/filtros/estatísticas: provas específicas dos quatro tipos de apoio e três serviços Balcão reforçadas; wizard, fundiário, perfil/empresa/submissão e CRM conservam provas próprias. Complemento continuation-business-journey-qa.xml demonstra interesse em negócio público PT/ZA, recibo/replay, recuperação/filtro/estatística e jornada PT=1/MZ=0, sem inferir país como origem. Ver [cobertura por formulário/consumidor](cobertura-percursos-i0-i3.md), ligada aos IDs da matriz. Apresentação visual continua pendente. C27 preparou a ligação do território principal ao preview na ficha da oportunidade e do filtro aplicado ao mapa da Bolsa; TypeScript/build passaram.361/361 limites reais recuperados READ ONLY na mesma QA A/B; perfis HTTP gestor/público/conta comum ensaiados em província/distrito/posto. Públicos0, internos361; faltam2/39/179 correspondências e polígonos de localidades. **Nenhum mapa ou seletor foi visualmente aceite.** C29: a fixture HTTP inicial tinha listas orçamentais vazias incompatíveis. Corrigida por nova versão, mantendo os resultados congelados anteriores e o erro explícito. A função efetiva do dossier verifica agora os snapshots realmente recuperados: A20unidades/0.00 e B20/70000.00; é cálculo demonstrado, sem observação visual. Browser: inventário vazio antes/depois de reset, IAB/Chrome/Edge indisponíveis; login QA HTTP200. Causa observada é fornecedor não exposto nesta sessão; causa de conexão/registo não determinada. [Roteiro manual executável](roteiro-manual-qa-i0-i3.md) com URLs, contas QA, ações/esperados e negativas preparado. HTML/props/HTTP não substituem essa execução. Matriz única mantém3.354 requisitos/linhas canónicas e5.830 ocorrências;5 concluídos anteriores,3.198 parciais,146 não implementados,1 implementado mas não ativado,4 decisões concretas. **Nenhum novo requisito encerrado.** Evidências complementares por método nos JUnit continuation-consumer/profile/install, sessão real em investor-path-http-qa.json e mapa de cobertura acima. Regressão global384/5215 é anterior a C27; não serve como prova atual de interface. C28 remove número381 fixo no preparador de evidências, sem eliminar guardas/hashes/autenticação. Backup/restauro final não renovado antes da demonstração visual. Fingerprints mudaram; ready=true histórico não vale para a versão atual. Instalação de recursos, extensão do percurso, disponibilização por configuração e importação/divulgação cartográfica são ações separadas, fora da autorização ativa. Workflow e contratos especializados permanecem no backlog; nenhuma jornada educativa nova. ''') insert('backlog.md', '## Próximo lote atual — critérios abertos após as provas HTTP', ''' 1. **P0/P1 AUD-UI-01, DASH-01, SIM-01, DESK-02, GUIDE-01, CRM-01:** executar [roteiro A/B](roteiro-manual-qa-i0-i3.md), criar projetos novos pela interface, recuperar em outra sessão do navegador, alternar sem mistura, ferramenta/resultado, rascunho de apoio e tarefa paralela. Provas HTTP já passaram; navegador continua sem fornecedor. Fecho exige capturas/resultados/rede/persistência por passo. 2. **P1 AUD-COUNTRY-01–04/06–07 e STATS-01:** ensaiar visualmente cada formulário da [cobertura](cobertura-percursos-i0-i3.md), filtros/URL/tabela e agregados separados. Interesse em negócio público e estatística específica da jornada agora têm provas API/persistência próprias; a apresentação e variações condicionais continuam abertas. Perfil/empresa e residência fiscal/fundos preservam significados próprios. 3. **P1 AUD-GEO-02/03:** observar cada seletor/mapa, incluindo C27 já preparado; guardar/reabrir campo, limpar descendentes, respeitar acesso e edição.361 disponíveis na QA não são361 públicos nem cobertura visual. Correspondências2/39/179 e localidades permanecem; reutilizar cadastro/originais sem aproximação ou dados inventados. Edição de zonas exige conta QA com MFA; não desativar a permissão. 4. **P1 AUD-OPS-01:** após demonstração, renovar backup/restauro/hashes/compatibilidade da versão final; repetir somente ensaios pertinentes e gerar provas verdadeiras. Recursos030000 e percurso190000 são instalações distintas; flag habilita navegação separadamente. Mecanismo cartográfico C30 preparado e demonstrado em QA; verificar interface e preparar prova específica da revisão/alvo após backup final. Importador CLI QA não pode ser apontado ao ativo. C28 preparador corrigido para não exigir contagem381 fixa. 5. **Workflow e contratos especializados:** continuam pendentes; sem novas jornadas educativas enquanto falhas prioritárias abertas. ClamD real e GD/scan das três derivadas de oportunidades têm provas QA atuais; arranque permanente/manutenção/PHP ativo e operações ainda não ensaiadas são pendências específicas, sem bloquear países/preparação. Todas as linhas permanecem na matriz existente; não reabrir aceitação de fontes oficiais nem recriar estados/dados paralelos. Nenhuma instalação ativa autorizada. ''') insert('execucao-percurso-i1-i3.md', '## Continuação atual — sessões reais e evidência por consumidor', ''' Prova posterior ao lote inicial abaixo: investor-path-http-qa.json executa login/logout e novo cookie jar/login no servidor QA18097, recupera A/B por ID, aplicabilidade, draft próprio, resultado congelado, pedido e tarefa concluída. Outra conta403/draft404 e contexto cruzado403. A mostra necessidade esperada0; B70000; ambas20unidades nas fórmulas. Na QA web existem4instâncias/76etapas, incluindo2fixtures de setup e2HTTP; os38steps dos testes abaixo pertencem a outra base isolada. País/origem/filtros/estatísticas foram reforçados por formulário; interesse em negócio público e jornada têm agora provas específicas. C27 liga consumidores de mapas; build/TypeScript passaram. C28 corrige a contagem fixa no preparador. Ver cobertura-percursos-i0-i3.md e roteiro-manual-qa-i0-i3.md. Interface ainda não observada; I0–I3 permanecem parciais. Provas anteriores de backup e hashes são históricas; renovar depois da demonstração visual. Nenhuma escrita/ativação ativa autorizada; instalação de schema, flag e importação/divulgação cartográfica são atos separados. ''') insert('plano-ativacao.md', '## Sequência atual — após demonstração e sem autorização ativa', f''' Plano preparado, **não executado**. A/B HTTP/nova sessão real passaram; interface ainda pendente. Por isso não renovar o backup final como se a demonstração visual estivesse concluída nem considerar pronta a ativação. A revisão atual alterou fingerprints: percurso `{runtime['code_hash']}`; recursos `{runtime['resource_code_hash']}`. Provas anteriores preservadas e insuficientes para esses hashes. `activation_ready=false`. | Ordem | Ação exata futura | Dependência/efeito esperado | Verificação e reversão | | --- | --- | --- | --- | | 0 | Concluir roteiro QA A/B e consumidores; fixar revisão/assets/hashes | Interface com nova sessão/perfis/resultados; nenhuma mistura. Não usar contagem global como substituto. | Registar cada critério na mesma matriz; se mudar código relevante, repetir respetiva demonstração. | | 1 | Renovar dump + ficheiros privados e restaurar numa nova base loopback*_test:55441; ensaiar compatibilidade/reversão sobre essa cópia | Origem ativa apenas READ ONLY; destino QA com guarda. Usar mecanismos de backup existentes, incluindo tools/desk-activation-backup.php; preservar prova antiga antes de substituir. Comparar schema, contagens, hashes por tabela, ficheiros/chave privada, órfãos/relações/RLS.288tabelas/5ficheiros são baseline histórico, não contagem a forçar. | Repetir ensaio vazio e recusa depois de uso; gerar provas para ambos os fingerprints sem fabricar true nem copiar flags visuais de outra versão. Não renovar/aplicar no ativo agora. | | 2 | Disponibilizar correções/assets desta revisão, mantendo INVESTOR_PATH_ENABLED=false | Países/origem/filtros/maturidade/C27; sem reclassificar valores legados, sem novo dado por deploy. | Confirmar assets servidos; rollback de código compatível preserva novos payloads/histórico. | | 3 | Conta ativa autorizada: GET `/management/opportunity-resources-install`, confirmar prévia atual, depois POST nessa rota **somente se030000 estiver ausente** | `2026_10_09_030000_extend_opportunity_resources`:3tabelas de associação existentes no desenho,1coluna em documents,1função/3triggers,1migration/evento;0recursos/documentos/localizações novos automaticamente. Backup/restauro/compatibilidade/hash/permissões. | Ler ledger/evento/autor/hash e comparar dados/classificações/relações/originais. Não repetir instalação como ensaio. Down só sem recursos/originais cifrados; após uso preservação/exportação antes de recuperação. | | 4 | GET `/management/balcao-install`, conferir apenas migration190000 pendente; POST autenticado pela mesma rota |2colunas nas entidades atuais +1definição publicada imutável +ledger/evento.0conversões de journeys antigos,0dossiers/etapas/tarefas criados. `pathQaVerified` exige API e A/B visual dessa revisão. Não repetir migrations básicas do Balcão/Bolsa/gestão já instaladas. | Schema/definição/ledger/evento/hash; instalação não habilita percurso. Down recusa após uso; preservar definição/história/RLS. | | 5 | Em ação de configuração/deploy separada, habilitar INVESTOR_PATH_ENABLED e atualizar configuração servida | Só depois de schema instalado e QA visual da versão. Mostra `/investimentos`/painel; instancia19etapas apenas ao criar novo dossier, sem renumerar roteiros. | Confirmar rotas/layout/perfis/recuperação. Reversão imediata: desligar flag preservando dossiers, drafts, resultados, documentos, consentimentos, tarefas e eventos; ferramentas diretas mantidas. | | 6 | Prévia/aplicação **cartográfica autenticada**, lote oficial privado, em geo_geometries existentes | C30: GET/POST `/management/territory-geometry-import`, POST `/{{batch}}/reverse`; mecanismo preparado e demonstrado em QA. **Não existe prova ativa válida desta revisão agora**. Depende de prévia/hash/original/scan/dedup/conflitos. Se base continuar0 e todas as correspondências permanecerem inequívocas:361=9+120+232novos;0geo_locations/pontos/perímetros de investimento.2/39/179ficam de fora. | Guardar lote/origem/edição/IDs/autor/eventos; replay0novos. Não apontar portal-audit-geometry-qa.php ao ativo. Reverter acesso/arquivar apenas lote novo sem uso; preservar originais/relações/história. | | 7 | Disponibilizar camadas por consumidor/âmbito autorizado, ato separado de importar | Fonte aceite não é divulgação automática; edição2019/atualidade jurídica/administrativo vs implantação explícitos. Limites internos não podem aparecer publicamente para tornar o teste verde. | Conferir cada mapa/selector/perfil. Retirar camada/autorização sem apagar geometria ou histórico. | ClamD é requisito de scan/reabertura/download/publicação dos binários afetados; arranque/assinaturas e cada derivada têm provas próprias. GD/WebP depende do PHP web. Não bloquear metadados, países, estatísticas ou preparação independente por estes itens. Nenhum cálculo fiscal ativado por importação/publicação. Restauro integral ativo continua fora da autorização; antes dele reconciliar todas as escritas posteriores ao backup. A renovação após interface pode envolver leitura ativa/restoreQA, mas nenhuma instalação, importação, publicação ou sobrescrita ativa está autorizada. ''') with (docs / 'casos-reproducao.md').open('a', encoding='utf-8') as f: if '## C27 —' not in (docs / 'casos-reproducao.md').read_text(encoding='utf-8'): f.write('''\n## C27 — consumidores sem contexto cartográfico\n\nRequisitos AUD-GEO-02/03. Reprodução de código: ficha de oportunidade chama InvestmentMapPanel apenas com opportunity_id; preview procura IDs territoriais exclusivamente nos filtros e recebe vazio. Bolsa desenha pontos e omite consulta de limites do território aplicado. Esperado: contexto administrativo do território conhecido, respeitando classificação, sem mudar resultado económico nem inventar implantação. Observado: chamada ao preview ausente nestes consumidores. Causa identificada: ligação de props/componente incompleta. Corrigido em código QA: territoryId separado a partir do primary_territory_path, e TerritoryGeometryPreview da Bolsa a partir de p.filters. TypeScript/build passam; GET real/serviço QA verificam acessos. Reprodução/renderização no navegador ainda pendentes; não confundir causa de código com prova visual.\n\n## C28 — preparador de prova preso à contagem381\n\nRequisito AUD-OPS-01. Fonte tools/portal-audit-prepare-activation.php exigia tests=passed=381 e emitia381 fixo; a regressão posterior384/5215, apesar de passar, seria rejeitada por esta condição. Esperado: total positivo, todos passados, sem skips, mantendo hash/backup/restauro/compatibilidade/autenticação independentes. Corrigida condição/serialização para usar total efetivo; a contagem continua apenas inventário de regressão, sem provar critérios ou UI. Sintaxe/Pint verificados. Preparador não executado contra ativo nem prova de ativação emitida; demais dependências continuam obrigatórias.\n''') if '## C29 —' not in (docs / 'casos-reproducao.md').read_text(encoding='utf-8'): f.write('''\n## C29 — fixture HTTP com orçamento incompatível\n\nRequisito AUD-SIM-02; falha na preparação da fixture, não demonstrada como regressão do portal. Reprodução QA: snapshot financeirov1 com incomes=[]/expenses=[], gravar draft e devolver evidência; executar recoverPathResult sobre o snapshot recuperado. Esperado para demonstração:20unidades/gap0(A) ou70000(B). Observado: Entradas incompatíveis. Causa: fixture criada pelo ensaio HTTP não respeitava o contrato de pelo menos uma linha orçamental. Correção no ensaio: novas linhas sintéticas explicitamente identificadas, PUT com ETag/contexto gera draftv2 e novo resultado; originais congeladosv1 preservados. Não relaxada a validação nem atribuído zero ao erro. investor-path-recovered-calculations.json demonstra novos cálculos e recusa dos resultados históricos incompatíveis; HTTP recupera ambos sem sobrescrita. Roteiro visual cria projetos novos e informa o histórico das fixtures de inspeção. Interface permanece pendente.\n''') historical = { 'relatorio-executivo.md': {'## Estado atual — lote I0/I1–I3 executado exclusivamente em QA': '## Histórico do lote inicial I0/I1–I3 — antes da continuação HTTP/C27'}, 'backlog.md': {'## Próximo lote — após execução QA aprovada de I1–I3': '## Histórico do próximo lote então definido — antes da continuação HTTP/C27'}, 'plano-ativacao.md': {'## Ordem final — execução aprovada QA, ativo não autorizado': '## Histórico da ordem anterior — fingerprints substituídos por C27', '## Versão atual — separar preparação, instalação e disponibilização': '## Histórico da versão anterior — separar preparação, instalação e disponibilização'}, 'execucao-percurso-i1-i3.md': {'## Lote executado e limites da evidência': '## Histórico do lote inicial — limites da evidência então obtida'}, } for filename, replacements in historical.items(): file = docs / filename content = file.read_text(encoding='utf-8') for old_heading, new_heading in replacements.items(): content = content.replace(old_heading, new_heading) file.write_text(content, encoding='utf-8') print(json.dumps({'evidence_updated': True, 'requirements_closed': 0, 'active_writes': 0, 'qa_instances': runtime['qa_path_journeys'], 'qa_steps': runtime['qa_path_steps'], 'visual': False}))