"""Prepare targeted edits for the existing CSV registry; Artifact Tool authors them.""" from pathlib import Path from datetime import datetime,timezone import csv,json,hashlib,collections csv.field_size_limit(20000000) root=Path(__file__).resolve().parent.parent doc=root/'docs/investmoz/v2/auditoria-portal' private=root/'storage/app/private/investmoz-v2/portal-audit' packet_dir=private/'functional-finalize-20261011';packet_dir.mkdir(exist_ok=True) tag='[Workflow QA 11/10/2026 — critérios de saída] ' common='QA HTTPS18445, stability_consumers_20261011_084534_test:55441, guarda e produção. Seis categorias30–35: alteração material→submissão→só gates afetados→condição bloqueante422/foco→resolução com documento→aprovação24 independente→publicação25→recuperação/ResponseGET sem gravação. Fundiário32: primeiro422 externo, depois ramo positivo SIMULAÇÃO QA identificada, sem efeito jurídico, restrito e recuperado noutra sessão. Coedição HTTP15/QA22 de10/10 reutilizada; nova UI de recursos/país/hierarquia/mapa/nova sessão, QA23 leitura/escrita403. Original15 scaneado por ClamD real; exclusão bloqueou URL anterior em2sessões, restauro mesmoSHA, outraorg403/anónimo semPDF. Filtro deleted0/1 corrigido,6consultas e cartões; origem unknown/PT+paísMZ+texto, coleções separadas;9rotas com teclado/atalho/axe0/320/390px. Não repetirA/B/C37.' evidence='docs/investmoz/v2/auditoria-portal/workflow-criterios-saida-20261011.md; recibos privados functional-workflow/land-publication/coedit-resources/documents/filters/accessibility/joint-chromium-20261011.json e functional-final-persistence/category-semantics/materiality-semantic/conditions-qa-20261011.json. Semântica negativa/materialidade de referências em memória distinguidas da interface.' gap='Restauro de oportunidade proposta R-ARCHIVE/R-DRAFT, sem implementação antecipada. Variantes por modalidade e contratos §25 ainda por critério, conforme tabela por categoria; Response§27 de compatibilidade com normative_response_complete=false (IDs/história/estados preservados). Interesse no anúncio público de negócio existente e outras variantes de país/estatística/mapa/documento têm consumidores separados.173correspondências eMandie/Guro; partilha individual de documentos de oportunidade não criada. Leitor de ecrã, PDF etiquetado e dispositivos reais pendentes. Sem fecho global por contagem de testes.' deps='030000+040000 já instaladosQA, prévias autenticadas e dependências consistentes, sem reinstalar. ClamDQA13310 real/fresco+fila+GDWebP usados conjuntamente. Destino3310 assinaturas09/10 com>51h, signatures_stale pelo limite48h: novos scans bloqueados; verificar worker supervisionado. Prévias antigas ready=false não habilitam aplicação. Para futura instalação, renovar backup/restauro do alvo ativo/fingerprint, prévia030→040 e habilitações legítimas separadas.190000 somente percurso integrado, OFF nestaQA; não bloqueia workflow isolado. Legado/modulares/ofertas/SLA separados.' active='COUNTRY02 ativo485ee04c40b2 preservado, somente050000; ativo288tabelas/13contas/0org/representações,030/040/190 ausentes e flags restantesOFF conforme prova ativa anterior. Incremento somente cópiaQA, nenhuma escrita/configuração/aplicação ativa. Hashes críticos ativos e todos os assets conservados.' ids={'AUD-OP-01','AUD-OP-02','AUD-OP-03','AUD-OP-04','AUD-PROFILE-06','AUD-PROFILE-07','AUD-PROFILE-08','AUD-PROFILE-09','AUD-PROFILE-10','AUD-PROFILE-11','AUD-PROFILE-12','AUD-PROFILE-19','AUD-PROFILE-21','AUD-PROFILE-23','AUD-PROFILE-25','AUD-PROFILE-28','AUD-PROFILE-30','AUD-PROFILE-31','AUD-GEO-03','AUD-STATS-01','AUD-UI-01','AUD-LIB-02','AUD-SCAN-01','AUD-OPS-01'} packet={'proof_filename':'csv-authoring-proof.json','files':[]};counts={} for name in ['matriz-requisitos.csv','backlog-priorizado.csv']: file=doc/name;raw=file.read_bytes() with file.open(encoding='utf-8-sig',newline='') as stream:rows=list(csv.reader(stream)) headers=rows[0];patches=[] for number,row in enumerate(rows[1:],1): rid=row[headers.index('ID')] if rid not in ids:continue def append(field,text): old=row[headers.index(field)];assert tag not in old return old+'\n'+tag+text specific=gap if rid=='AUD-PROFILE-06':specific='Coedição de rascunho HTTP já demonstrada e UI de recursos/país/mapa demonstrada agora. Falta variante visual de correção após submissão e revogação do coeditor nessa ação. Não repetir a coedição de rascunho15. '+gap if rid=='AUD-STATS-01':specific='Unknown/todas/conhecida e combinação país/origem/texto recuperadas; coleções separadas. Manter variantes por consumidor: interesse de anúncio público de negócio existente, outros apoios/transições/cancelamento; reutilizar4formulários públicos já submetidos/repetidos. Não somar investidores únicos.' if rid=='AUD-UI-01':specific='9rotas do workflow/recursos/lista:axe0, teclado/atalho e320/390px. Foco de erro de condição demonstrado. Leitor de ecrã real, estados/variantes adicionais, documentosPDF etiquetados e dispositivos reais pendentes; A/B/C37 fechados.' if name=='matriz-requisitos.csv': history=json.dumps({k:row[headers.index(k)] for k in ['Lacuna','Dependência']},ensure_ascii=False) values={'Implementação encontrada':append('Implementação encontrada','Materialidadev3 preserva v2/assinaturas; condições internas noJSON/auditoria existentes, sem tabelas; erros de arrendamento junto a renda/periodicidade; filtrobooleano0/1; indicadores e nomes/títulos cartográficos corrigidos. '+common), 'Disponibilidade ativa':active,'Evidência funcional':append('Evidência funcional',common+' '+evidence),'Lacuna':specific,'Dependência':deps, 'Versões divergentes':append('Versões divergentes','Pendências históricas substituídas apenas nos subcritérios demonstrados, conservadas: '+history), 'Interface':append('Interface','ChromiumHTTPS/produção: critérios específicos nos recibos; coedição préviaHTTPnão repetida. Não extrapolar para todo§25/27/portal.'), 'API':append('API','200/201,422controlado por condição/dependência,403por organização,404após retirada; ResponseGETmantémversion. Filtrodeleted=false rejeitava;0/1recupera.'), 'Gravação':append('Gravação','QAopportunities/workflow_context/tasks/audit_events e recursos existentes; condições/assinaturas/originais preservados,0escritasativas.'), 'Recuperação':append('Recuperação','F5/Response e novas sessões de recursos/ramo fundiário; país/descendentes/hashdocumental correspondem ao persistido.'), 'Resultado apresentado':append('Resultado apresentado',common)} else: values={'Pendência':specific,'Correção/componentes':append('Correção/componentes',common+' '+evidence),'Dependência/pergunta':deps,'Ordem do próximo lote':'RevisãoQA delimitada; decisõesR-ARCHIVE/R-DRAFT, variantes por categoria/consumidor e dependências reais do destino. Sem autorização de ativação deste pacote; COUNTRY02ONpreservado.'} patches.append({'row':number,'values':values}) assert len(patches)==len(ids),(name,len(patches)) packet['files'].append({'filename':name,'input_sha256':hashlib.sha256(raw).hexdigest(),'rows':rows,'patches':patches,'allowed_columns':sorted({k for p in patches for k in p['values']})}) if name=='matriz-requisitos.csv': counts={'at':datetime.now(timezone.utc).isoformat(),'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(collections.Counter(r[headers.index('Estado')] for r in rows[1:])),'changed_IDs':sorted(ids),'no_global_closures_by_extrapolation':True} (packet_dir/'csv-edits.json').write_text(json.dumps(packet,ensure_ascii=False),encoding='utf-8') (packet_dir/'counts.json').write_text(json.dumps(counts,ensure_ascii=False,indent=2),encoding='utf-8') print(json.dumps({'matrix':counts['requirements'],'source_occurrences':counts['source_occurrences'],'states':counts['states'],'updated_requirements':len(ids),'active_writes':0},ensure_ascii=False))