54 lines
9.0 KiB
Python
54 lines
9.0 KiB
Python
from pathlib import Path
|
||
from datetime import datetime, timezone
|
||
import csv, hashlib, json, collections
|
||
|
||
csv.field_size_limit(20000000)
|
||
ROOT=Path(__file__).resolve().parent.parent
|
||
DOC=ROOT/'docs/investmoz/v2/auditoria-portal'
|
||
OUT=ROOT/'outputs/investmoz-portal-stability-20261011'
|
||
PRIVATE=ROOT/'storage/app/private/investmoz-v2/portal-audit/portal-stability-finalize-20261011'
|
||
PRIVATE.mkdir(exist_ok=True)
|
||
manifest=json.loads((OUT/'manifesto-candidata.json').read_text(encoding='utf-8'))
|
||
revision=manifest['delivery_revision'][:12]
|
||
tag='[Estabilização integrada QA 11/10/2026 — '+revision+']'
|
||
country='COUNTRY02: Chromium no hostname portal-investidor.test, Apache2.4.54/PHP8.5.11TS/mod_php/128M e HTTPS reconhecido. Estado anterior→login/MFA→prévia→somente050000→replay mesma operação→perfil→PT/F5→MZ/v3→Back/Forward cifrados→logout/API401/Back sem master→nova sessão/MFA/MZ e fonte→OFF/ON sem perda. SQL:288 tabelas,2colunas nullable,1auditoria de instalação,2snapshots cifrados recuperáveis,0outras instalações. Produção250ae618d716c; fingerprint050000162daff6ce08 inalterado. Fixtures somenteQA fora da instalação. Backup original real288tabelas/31sequências/379ficheiros/2MFA restaurado duas vezes emQA; backup pós-utilizaçãoQA restaurado conserva dados novos. Ativo READ ONLY09:40:51:13contas/0org/0memberships/79migrations/126audits,sem050000/COUNTRYfalse, código/config/bundle/chave/dados intactos.'
|
||
ops='Frente única C110–C112 e casos adicionais C113–C117: utilitárioCSPRNG comum remove25chamadas diretas em14componentes, chaves distintas por operação e estáveis nas tentativas; cURL corrigido exclusivamente na cópiaApacheQA com nghttp2.dll1.70; OPcache com namespace/fallbackQA; GeoJSON por feature/38MiB/581features exatas (11/159/411); MFA normalFortify aceite no bootstrap sem recifrar envelopes; campos de mensagem bloqueados durante envio evitam perda do segundo texto. Provas individuais: rascunhos/dossier/Balcão/mensagens/comunicação/pedido dePromotor/scan real-download byte a byte/autogravação pública, cinco403; 040000 a frio com erro de transporte antescommit/retry mesma chave/replay/1install+1bootstrap e recuperação noutra sessão. Prévia cartográfica3níveis;L1criou0/reutilizou11/reverteu0/preservou11;408geometrias existentes hash integral inalterado. Nenhuma publicação ou perfil real atribuído. Recebido inicial com falha de mensagem preservado e complementado por prova final específica.'
|
||
active='Estado atual: ativação suspensa por instrução do responsável; COUNTRY02 desabilitado e050000 ausente no ativo. Somente código/bundle/runtime em cópia privadaQA; não reiniciado Apache ativo, não modificada base/config/código ativo. Autorização anterior13644ed74a48/162daff6ce08 preservada no âmbito original, sem extensão automática à nova revisão.'
|
||
country_gap='Disponibilização ativa suspensa. Gravação real do país mestre depende de cadastro legítimo e representação autorizada (atualmente0/0), que podem ser preenchidos posteriormente pelo fluxo autorizado; não são pré-requisito para instalar duas colunas. A revisão nova acrescenta18ficheiros manuais+58artefactosWayfinder eDLL de runtime em relação à anterior; apreciar delta antes de levantar suspensão. Sem afirmação de ensaio ativo.'
|
||
ops_gap='Aceitação global por consumidores ainda parcial: contratos/workflow/documentos derivados/correspondências ambíguas/acessibilidade integral/dispositivos reais mantêm critérios próprios. A frente técnica corrigida foi demonstrada apenas nas ações enumeradas; não fecha todos os requisitos dos14módulos. Ofertas/competências modulares/SLA continuam decisões separadas. Ativação suspensa e nenhum outro pacote previsto na sequênciaCOUNTRY02.'
|
||
dependencies='Revisão fixa485ee04c40b2; inputs98dbb2952e5c; produção250ae618d716; fingerprint050000162daff6ce08. Dependência nova de runtime: DLLnghttp2PHP1.70 exige apreciação explícita; OPcache isolado é diferençaQA, não mudança automática ativa. Antes de qualquer disponibilização autorizada, renovar backup/restauro real correspondente<=24h, conferir certificado/contexto/cookies/recursos e prévia autenticada real. Intervenções futuras agrupadas: controlo normalLaragon para DLL carregada e login/MFA do gestor real. Nenhuma intervenção solicitada agora. Fila eClamD necessários a uploads, não aCOUNTRY02;030/040/190 não são dependênciasDDL050000.'
|
||
accept='DemonstradoQA: resultado visível/persistido/recuperado COUNTRY02 e ações técnicas listadas, transporteHTTPS reconhecido/produção final, MFA normal/sessão regenerada/logout privado, replay único, originals e envelopes intactos, restauros anterior e pósuso. Futuro ativo: revisão exata, certificado reconhecido, backup/restauro correspondente vigente, prévia investemoz5432/hash/fingerprint/dependências/ready correspondentes, POST autenticado somente050000,2colunas/0tabelas/contas/org/representações e1auditoria. Reversão preferidaCOUNTRYfalse mantendoTLS/colunas/histórico; não down/drop/keygenerate/MFAoff. Não repetirA/B/C37 integrais.'
|
||
evidence='outputs/investmoz-portal-stability-20261011/relatorio-estabilizacao.md; casos-reproducao.md; cobertura-consumidores.md; country02-interface.json; country02-persistencia.json; consumidores-interface.json; consumidores-persistencia.json; runtime-qa.json; restauro-original.json; backup-pos-utilizacao-qa.json; ativo-preservado.json; manifesto-candidata.json; procedimento-unico.md.'
|
||
packet={'proof_filename':'csv-authoring-proof.json','files':[]}
|
||
for filename in ['matriz-requisitos.csv','backlog-priorizado.csv']:
|
||
file=DOC/filename
|
||
raw=file.read_bytes()
|
||
with file.open(encoding='utf-8-sig',newline='') as f:rows=list(csv.reader(f))
|
||
headers=rows[0]; patches=[]
|
||
for index,row in enumerate(rows[1:],1):
|
||
rid=row[headers.index('ID')]
|
||
if rid not in ['AUD-COUNTRY-02','AUD-OPS-01']:continue
|
||
assert tag not in row[headers.index('Evidência funcional')] if filename=='matriz-requisitos.csv' else tag not in row[headers.index('Correção/componentes')]
|
||
summary=country if rid=='AUD-COUNTRY-02' else ops
|
||
gap=country_gap if rid=='AUD-COUNTRY-02' else ops_gap
|
||
append=lambda field,value:row[headers.index(field)]+'\n'+tag+' '+value
|
||
if filename=='matriz-requisitos.csv':
|
||
history='\n[Histórico de pendências anterior à suspensão, preservado sem vigência atual] '+json.dumps({k:row[headers.index(k)] for k in ['Disponibilidade ativa','Lacuna','Dependência']},ensure_ascii=False)
|
||
values={'Implementação encontrada':append('Implementação encontrada',summary),'Disponibilidade ativa':active,'Evidência funcional':append('Evidência funcional',summary+' '+evidence),'Lacuna':gap,'Dependência':dependencies,'Critério de aceitação':append('Critério de aceitação',accept),'Versões divergentes':append('Versões divergentes','136/162 original imutável/suspenso; revisão '+revision+' com delta explícito, sem nova ativação.')+history,
|
||
'Interface':append('Interface','Critérios individuais Chromium HTTPS e CSPRNG semrandomUUID: ver '+evidence),
|
||
'API':append('API','Prévia/POST/replay autorizadosQA; cinco403 e logout401; nenhuma chamada de instalação ativa.'),
|
||
'Gravação':append('Gravação','PersistênciaSQL comprovada por recibos específicos; instalações e fixtures exclusivamenteQA.'),
|
||
'Recuperação':append('Recuperação','F5/nova sessão e snapshots cifrados; original e pósuso realmente restaurados em clonesQA.'),
|
||
'Resultado apresentado':append('Resultado apresentado',summary)}
|
||
else:
|
||
values={'Pendência':gap,'Correção/componentes':append('Correção/componentes',summary+' '+evidence),'Dependência/pergunta':dependencies,'Aceitação':append('Aceitação',accept),'Ordem do próximo lote':'Ativação suspensa. Apreciar delta da revisão'+revision+' e limitações; continuar critérios funcionais independentesQA. Não voltar a solicitar testes básicos de ambientes incompletos; futuras intervençõesLaragon/MFA agrupadas no procedimento único.'}
|
||
patches.append({'row':index,'values':values})
|
||
assert len(patches)==2
|
||
packet['files'].append({'filename':filename,'input_sha256':hashlib.sha256(raw).hexdigest(),'rows':rows,'patches':patches,'allowed_columns':sorted({k for p in patches for k in p['values']})})
|
||
if filename=='matriz-requisitos.csv':
|
||
states=collections.Counter(r[headers.index('Estado')] for r in rows[1:])
|
||
counts={'requirements':len(rows)-1,'rows':len(rows)-1,'source_occurrences':sum(int(r[headers.index('Quantidade de linhas de origem')]) for r in rows[1:]),'states':dict(states),'closed_AB_C37_preserved':True,'changed_requirement_IDs':['AUD-COUNTRY-02','AUD-OPS-01']}
|
||
(PRIVATE/'csv-edits.json').write_text(json.dumps(packet,ensure_ascii=False),encoding='utf-8')
|
||
(PRIVATE/'counts-before.json').write_text(json.dumps(counts,ensure_ascii=False,indent=2),encoding='utf-8')
|
||
print(json.dumps({'packet':PRIVATE.name,'counts':counts,'database_writes':0},ensure_ascii=False))
|