50 lines
8.9 KiB
Python
50 lines
8.9 KiB
Python
"""Prepare only cell patches in the existing audit and readable scope/restoration records."""
|
||
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;d=root/'docs/investmoz/v2/auditoria-portal';p=root/'storage/app/private/investmoz-v2/portal-audit'
|
||
read=lambda n:json.loads((p/n).read_text(encoding='utf8'))
|
||
tag='[Delimitação/ACL QA 11-10-2026] '
|
||
folder=p/'functional-scope-finalize-20261011';folder.mkdir(exist_ok=True)
|
||
scope=read('functional-delivery-scope-code-20261011.json');backup=read('functional-scope-backup-restoration-qa-20261011.json');target=read('functional-scope-target-backup-20261011.json')
|
||
assert scope['code_revision']==backup['code_revision']==target['candidate_code_revision']
|
||
evidence='functional-document-alias-before/after-20261011.json; functional-document-boundary-chromium-20261011.json; functional-document-images-chromium-20261011.json; functional-delivery-scope-chromium-20261011.json; functional-scope-dependencies-chromium-20261011.json; functional-scope-persistence-qa-20261011.json. C126: alias geral200 enquanto rota própria403; corrigido para403 nas duas rotas, originais/derivadas permitidos por perfil recuperados pelos hashes. Revogação sintética32/auditoria elimina acesso pelo URL anterior na sessão aberta e nova. Documento aceite29 preservado. Disponibilidade imobiliária422 conserva também os erros semânticos anteriores; rascunho55planeado recuperável. Casos30–35/54 e renda4500/monthly preservados.'
|
||
common='Seis categorias base e variantes delimitadas na interface QA; módulos separados não oferecidos com flagOFF, sem alterar concessões/contratos/taxonomia. Serviço VerifiedDocumentBinary aplica a autorização atual da oportunidade também na rota genérica e nas derivadas. Nenhuma tabela/ACL paralela; partilha individual continua indisponível e explicada. Publicar anúncio não publica anexos.'
|
||
gap='ACL individual de anexos ainda não implementada: destinatário externo selecionado, subconjunto de membros, concessão/revogação por ficheiro. Não incluir documentos que exigem essa confidencialidade individual. Response normativo§27 integral, variantes por categoria não ensaiadas, restauração da oportunidade e leitores/dispositivos reais permanecem fora da entrega. R-ARCHIVE/R-DRAFT aguardam decisão; não confundir com restauro de anexo.'
|
||
deps='030000 →040000 confirmado em prévias QA com schema/ledger/dependências consistentes;190000 apenas quando disponibilizado o percurso integrado. Alvoativo288tabelas/020000+050000/COUNTRY02ON:030000+040000 ausentes. Backup/restauro REAL do alvo em'+target['verified_at']+':288tabelas,31seq,799ficheiros,2MFA,restauro somente55441; ligado ao código'+scope['code_revision'][:12]+'. Readiness/prévias autenticadas correspondentes, ensaio de atualização do clone do alvo, ClamD3310fresh/scan/worker supervisionado e titulares/âmbitos legítimos ainda necessários. Zero geometrias no alvo; importação separada. Não ativar agora.'
|
||
active='Ativo consultado READONLY investemoz:5432; COUNTRY02ON, demaisflagsOFF,288tabelas,13contas,0org/representações/geo_geometries. Nenhuma escrita ou troca de código/configuração/serviço ativo. Codefix apenas cloneQA55441. A/B eC37 preservados.'
|
||
ids={'AUD-OP-01','AUD-OP-02','AUD-OP-03','AUD-OP-04','AUD-PROFILE-07','AUD-PROFILE-29','AUD-PROFILE-31','AUD-PROFILE-32','AUD-OPS-01','AUD-UI-01'}
|
||
packet={'proof_filename':'csv-authoring-proof.json','files':[]}
|
||
for name in ['matriz-requisitos.csv','backlog-priorizado.csv']:
|
||
file=d/name;raw=file.read_bytes()
|
||
with file.open(encoding='utf-8-sig',newline='')as s:rows=list(csv.reader(s))
|
||
h=rows[0];patches=[]
|
||
for number,row in enumerate(rows[1:],1):
|
||
rid=row[h.index('ID')]
|
||
if rid not in ids:continue
|
||
def append(k,v):
|
||
old=row[h.index(k)];assert tag not in old,(rid,k)
|
||
return old+'\n'+tag+v
|
||
if name=='matriz-requisitos.csv':
|
||
values={'Implementação encontrada':append('Implementação encontrada',common),'Disponibilidade ativa':active,
|
||
'Evidência funcional':append('Evidência funcional',evidence),'Lacuna':append('Lacuna',gap),'Dependência':append('Dependência',deps),
|
||
'Interface':append('Interface','Âmbito/variantes/privacidade visíveis a390px; erro422adjacente, rascunho55e renda54recuperados. Não repetirA/B/C37.'),
|
||
'API':append('API','403 nas rotas próprias/genéricas/derivadas sem perfil;401 após revogação da sessão,403no novo login; biblioteca aceita29continua200/hash. Submissão variante excluída422, sem apagar erros semânticos.'),
|
||
'Gravação':append('Gravação','SomenteQA: rascunho55 e conta sintética32/MFA normal, concessão/revogação pelos serviços existentes com auditoria. Perfis existentes não revogados;0escritasativas.'),
|
||
'Recuperação':append('Recuperação',evidence),'Resultado apresentado':append('Resultado apresentado',common),
|
||
'Versões divergentes':append('Versões divergentes','Candidata8af63e2fe657 preservada como referência;C126 impede a sua disponibilização. Novo código'+scope['code_revision'][:12]+' inclui seis ficheiros alterados face àquela, total14no delta e bundle recompilado. Propostas de restauração não são decisões implementadas.')}
|
||
else:
|
||
values={'Pendência':append('Pendência',gap),'Correção/componentes':append('Correção/componentes',common+' '+evidence),
|
||
'Dependência/pergunta':append('Dependência/pergunta',deps+' Decisões separadas: aprovar R-ARCHIVE(Publicador independente→needs_information/não público) e R-DRAFT(autor/coeditor autorizado→draft, nunca submetido/publicado)? Nenhuma republicação automática.'),
|
||
'Ordem do próximo lote':append('Ordem do próximo lote','RevisãoQA delimitada comC126corrigido; preparar ensaio de atualização do clone real, readiness por instalação e serviços do destino. ACLindividual fora do pacote; não oferecer divulgação seletiva. COUNTRY02ativo preservado; nenhuma ativação autorizada.')}
|
||
patches.append({'row':number,'values':values})
|
||
assert len(patches)==len(ids)
|
||
packet['files'].append({'filename':name,'input_sha256':hashlib.sha256(raw).hexdigest(),'rows':rows,'patches':patches,'allowed_columns':sorted({k for patch in patches for k in patch['values']}),'source_hash_updates':[]})
|
||
if name=='matriz-requisitos.csv':counts={'requirements':len(rows)-1,'rows':len(rows)-1,'source_occurrences':sum(int(r[h.index('Quantidade de linhas de origem')])for r in rows[1:]),'states':dict(collections.Counter(r[h.index('Estado')]for r in rows[1:])),'updated_IDs':sorted(ids),'new_IDs':0}
|
||
(folder/'csv-edits.json').write_text(json.dumps(packet,ensure_ascii=False),encoding='utf8');(folder/'counts.json').write_text(json.dumps(counts,ensure_ascii=False,indent=2),encoding='utf8')
|
||
cases=d/'casos-reproducao.md';text=cases.read_text(encoding='utf8');assert '## C126' not in text
|
||
text+='''\n\n## C126 — contorno da autorização de anexos pela rota geral da biblioteca\n\n- **Prioridade/estado:** P0 de confidencialidade; corrigido e demonstrado apenas em QA. Impede disponibilizar a candidata8af63e2fe657 sem esta correção. Não existe030000/040000 no ativo; não se extrapola a exploração para documentos de outro consumidor.\n- **Operação/perfil:** gestão geral17, sem perfil/âmbito da oportunidade54; descarregar um original, imagem ou derivada por UUID.\n- **Reprodução:** autenticar17 emQAHTTPS18445; GET`/minhas-oportunidades/54/resources/documents/a61f9a47-82a7-49cc-958e-edd115729333/download` devolve403; GET`/management/documents/8dd5731f-80dc-48a1-a307-a51e27769d0b/download` devolvia200/PDF para os mesmos bytes.\n- **Esperado/observado:** ambas as rotas devem exigir a autorização vigente da oportunidade; só a primeira a exigia. Causa: rota geral aceitava manage-portal e VerifiedDocumentBinary conferia apenas scan/integridade/cifra.\n- **Correção:** serviço comum resolve a relação existente com oportunidade e exige perfil/âmbito atual, recurso ativo e oportunidade não arquivada; originais/derivadas órfãos dessa origem falham fechados. URLs assinados conservam autenticação e autorização. Sem tabelas ou cadastros paralelos; classificação não é ACL.\n- **Provas:** functional-document-alias-before/after-20261011.json; functional-document-boundary-chromium-20261011.json; functional-document-images-chromium-20261011.json. Ambos os URLs403 para17; Promotor21/Validador24/Publicador25 recuperam os três PDFs54pelos hashes; derivadas33protegidas e biblioteca29preservada. Concessão sintética32 e revogação por Superutilizador27: URL anterior recusado na sessão e após novo login, com auditoria. A retirada global anterior não foi usada como substituto desta revogação.\n- **Limite:** não implementa conceder/revogar acesso a um destinatário individual por anexo. Partilha externa seletiva e restrição entre membros autorizados continuam indisponíveis e anunciadas na interface.\n'''
|
||
cases.write_text(text,encoding='utf8')
|
||
print(json.dumps(counts,ensure_ascii=False))
|