162 lines
28 KiB
Python
162 lines
28 KiB
Python
"""Seal the bounded QA candidate; explicitly keep destination activation blocked."""
|
||
from pathlib import Path
|
||
from datetime import datetime,timezone
|
||
import json,hashlib,zipfile,shutil,csv,collections,xml.etree.ElementTree as ET
|
||
csv.field_size_limit(20000000)
|
||
root=Path(__file__).resolve().parent.parent;p=root/'storage/app/private/investmoz-v2/portal-audit';source=Path(json.loads((p/'portal-stability-latest.json').read_text())['source'])
|
||
read=lambda n:json.loads((p/n).read_text(encoding='utf8'))
|
||
sha=lambda x:hashlib.sha256(x.read_bytes()).hexdigest()
|
||
scope=read('functional-delivery-scope-code-20261011.json');code=scope['code_files'];build=read('functional-scope-production-build-20261011.json')
|
||
backup=read('functional-scope-backup-restoration-qa-20261011.json');target=read('functional-scope-target-backup-20261011.json');deps=read('functional-scope-dependencies-chromium-20261011.json')
|
||
assert scope['code_revision']==backup['code_revision']==target['candidate_code_revision']
|
||
assert build['manifest_sha256']==backup['build_manifest_sha256']==scope['production_manifest_sha256']
|
||
assert deps['profiles_preview']['code_hash']==backup['profile_fingerprint']
|
||
for rec in [backup,target]:
|
||
assert rec['result']=='passed'
|
||
for file,h in [('dump_path','dump_sha256'),('files_path','files_sha256')]:assert sha(Path(rec[file]))==rec[h]
|
||
names=['functional-document-alias-before-20261011.json','functional-document-alias-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','functional-scope-country-compatibility-qa-20261011.json','functional-scope-production-build-20261011.json','functional-scope-backup-restoration-qa-20261011.json','functional-scope-target-backup-20261011.json']
|
||
for n in names:assert read(n)['result']=='passed',n
|
||
names+=['functional-scope-target-readonly-20261011.json','functional-scope-destination-services-readonly-20261011.json','functional-scope-finalize-20261011/csv-authoring-proof.json']
|
||
previous=root/'outputs/investmoz-opportunity-workflow-consolidated-final-20261011';prior=json.loads((previous/'manifesto.json').read_text())
|
||
assert sha(previous/'manifesto.json')=='410bc74e6befde6e51a6e8afe8d55a699d600c1a857f1fc7d395baba30cd49ca'
|
||
assert sha(previous/'investmoz-workflow-8af63e2fe657.zip')=='feb7f4e8ae2608f08ef90d3a0acfbe71ba118480c967e784fa5037b645cc3403'
|
||
for n,h in prior['QA_evidence'].items():assert sha(p/n)==h,('Historical evidence changed',n)
|
||
for n,h in code.items():assert sha(source/n)==h
|
||
for n,h in build['assets'].items():assert sha(source/'public/build'/n)==h
|
||
for n,h in read('functional-active-files-before-20261011.json').items():assert sha(root/n)==h
|
||
for n,h in prior['unchanged_dependencies'].items():assert sha(root/n)==h and sha(source/n)==h
|
||
with (root/'docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv').open(encoding='utf-8-sig',newline='')as f:rows=list(csv.DictReader(f))
|
||
counts=read('functional-scope-finalize-20261011/counts.json')
|
||
assert len(rows)==counts['requirements']==3401
|
||
assert dict(collections.Counter(r['Estado']for r in rows))==counts['states']
|
||
out=root/'outputs/investmoz-opportunity-workflow-scope-20261011';out.mkdir(exist_ok=True)
|
||
assert not(out/'manifesto.json').exists(),'Never overwrite a sealed candidate'
|
||
payload=out/'payload';payload.mkdir()
|
||
for n in code:
|
||
to=payload/n;to.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(source/n,to)
|
||
for n in build['assets']:
|
||
to=payload/'public/build'/n;to.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(source/'public/build'/n,to)
|
||
payload_hashes={f.relative_to(payload).as_posix():sha(f)for f in payload.rglob('*')if f.is_file()}
|
||
assert len(payload_hashes)==172
|
||
failure=ET.parse(source/'storage/functional-scope-regression-20261011.xml').getroot().find('testsuite')
|
||
repair=ET.parse(source/'storage/functional-scope-error-regression-20261011.xml').getroot().find('testsuite')
|
||
assert int(failure.attrib['tests'])==26 and int(failure.attrib['failures'])==1
|
||
assert int(repair.attrib['tests'])==1 and int(repair.attrib['failures'])==0 and int(repair.attrib['errors'])==0
|
||
quality={'existing_regression':'25 unaffected passes reused; one failure of semantic error preservation corrected and its test rerun successfully (50 assertions)','production_build':build['manifest_sha256'],'typescript_exit':0,'XML_before_fix_sha256':sha(source/'storage/functional-scope-regression-20261011.xml'),'XML_affected_after_fix_sha256':sha(source/'storage/functional-scope-error-regression-20261011.xml'),'acceptance_is_criterion_based':True}
|
||
core={'format':'investmoz-opportunity-workflow-scope-1','base_revision':prior['base_revision'],'previous_candidate':{'revision':prior['revision'],'manifest_sha256':sha(previous/'manifesto.json'),'archive_sha256':'feb7f4e8ae2608f08ef90d3a0acfbe71ba118480c967e784fa5037b645cc3403','preserved':True,'availability_blocked_by':'C126'},
|
||
'code_revision':scope['code_revision'],'payload':payload_hashes,'base_hashes':scope['active_base_hashes'],'unchanged_dependencies':prior['unchanged_dependencies'],'additional_changes':scope['changed_from_previous'],
|
||
'production_manifest_sha256':build['manifest_sha256'],'recompilation_required':True,'profile_fingerprint':backup['profile_fingerprint'],'resources_fingerprint':deps['resources_preview']['code_hash'],
|
||
'included_categories':prior['included_categories'],'included_cases':[30,31,32,33,34,35,54],'included_scope':'Existing base-category internal workflow, compatible Response, scoped group-private resources, materiality/conditions, filters and scoped accessibility; sale/lease completed vacant unencumbered preparation branch',
|
||
'unavailable':['Individual per-file recipients/sharing/NDA/revocation','Opportunity restoration pending R-ARCHIVE/R-DRAFT decision','Full normative Response/27 export','Real estate planned/under-construction/occupied/renovation/encumbered/urban-limit submission','Experimental modular categories/offers/SLA','Legacy integration and integrated journey/190000','Geometry imports/publication','Real devices/full accessibility and external legal decisions'],
|
||
'effects':{'code_files':14,'new_service_files':1,'assets':158,'new_routes':0,'new_configuration_files':0,'prospective_installations':['030000','040000'],'prospective_new_tables':7,'prospective_new_columns':5,'automatic_accounts':0,'automatic_organizations':0,'automatic_representations':0,'automatic_publications':0,'active_writes':0},
|
||
'privacy_policy':'Existing opportunity organization/type/role authorization; authenticated manager alone cannot bypass it. Classifications remain metadata, not individual grants. Publication of teaser does not publish files. Original/image derivatives require current authorization through every binary route.',
|
||
'QA_evidence':{n:sha(p/n)for n in names},'reused_evidence':prior['QA_evidence'],'quality':quality,
|
||
'QA_backup':{k:backup[k]for k in ['at','source','restored','tables','sequences','files','dump_sha256','files_sha256','MFA_envelopes_readable','code_revision','acervo']},
|
||
'destination_backup':{'at':target['verified_at'],'target':target['target'],'restored_only_in_QA':target['restored_target'],'tables':len(target['tables']),'sequences':len(target['sequences']),'files':target['file_count'],'originals':target['active_originals_backed_up'],'MFA_envelopes_readable':target['MFA_envelopes_readable'],'dump_sha256':target['dump_sha256'],'files_sha256':target['files_sha256'],'candidate_code_revision':target['candidate_code_revision'],'read_only_active':True,'installer_readiness':False},
|
||
'COUNTRY02_compatibility':read('functional-scope-country-compatibility-qa-20261011.json'),'destination_inventory':read('functional-scope-target-readonly-20261011.json'),
|
||
'activation_ready':False,'activation_authorized':False,'activation_blocks':['ClamD destination signatures_stale; fresh real scan needed','Destination supervised document/image worker/GD operation not demonstrated','Final upgrade rehearsal of restored active target and scoped installer readiness/preview proofs needed','Legitimate bootstrap holders and functional scopes not designated','Administrative map geometry absent; separate authorization/import required if that display is included'],
|
||
'restoration_decisions_pending':{'R-ARCHIVE':'Independent scoped Publisher with MFA/reason/audit -> needs_information nonpublic; explicit new submission/review/publication, no automatic republication','R-DRAFT':'Author or authorized organization coeditor -> private draft only never submitted/published; reason/audit and original ID/history preserved'},
|
||
'preserved':['COUNTRY02 active/050000','A/B and C37 closures','five phases/19 existing stage numbering','IDs/URLs/contracts/classifications/relations/originals/cipher/audit','active TLS/session/services/code/database'],'audit_counts':counts}
|
||
revision=hashlib.sha256(json.dumps(core,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest();manifest={**core,'revision':revision,'sealed_at':datetime.now(timezone.utc).isoformat()}
|
||
(out/'manifesto.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n',encoding='utf8')
|
||
report=f'''# Gestão de Oportunidades — candidata delimitada {revision[:12]}
|
||
|
||
**Preparada e demonstrada nos critérios indicados em QA; disponibilização ativa bloqueada.** Código `{scope['code_revision']}`. Substitui para apreciação a referência `8af63e2fe657`, conservada intacta: C126 impede disponibilizá-la sem a correção documental. COUNTRY02 ativo, A/B e C37 mantêm os fechos. Nenhuma alteração no código, configuração, serviços ou base ativa.
|
||
|
||
## Funcionalidades incluídas e limites
|
||
|
||
| Categoria/consumidor | Incluído e evidência reutilizada | Limite concreto |
|
||
| --- | --- | --- |
|
||
| Projeto, 30/52 | Rascunho incompleto; correção, condição, revisão técnica material, aprovação24/publicação25 e recuperação. | Cenários/licenças dependem do caso; análise interna não certifica viabilidade. |
|
||
| Imobiliário, venda31/arrendamento54 | Concluído/desocupado/sem encargos; documentos próprios; submissão→correção→três revisões24→aprovação→publicação restrita25. Renda4500 MZN/mês preservada. | Outros negócios imobiliários, construção planeada/em curso, ocupação/renovação, encargos e limites urbanísticos não avançam neste pacote; podem guardar preparação. |
|
||
| Fundiário, 32 | Revisão territorial, bloqueio externo, aprovação/publicação restrita sintética explicitamente identificada e recuperação. | Não atribui terra/DUAT nem comprova conflitos/consulta reais.173 correspondências/Mandie–Guro mantidos fora. |
|
||
| Venda de negócio, 33 | Revisão societária, aprovação independente e teaser público. Documentos/imagens/derivadas privados. | Interesse em anúncio legado, modalidades financeiras/histórico/projeções e destinatários de due diligence não encerrados por esse caso. |
|
||
| Parceria, 34 | Governação, materialidade apenas nos gates afetados, correção/aprovação/publicação restrita; recurso já ensaiado reutilizado. | Variantes de contribuições/documentação e partilha individual externa pendentes. A ACL da sala de parceria não é ACL dos anexos da oportunidade. |
|
||
| Franquia, 35 | Registo societário/materialidade, licenças, aprovação/publicação restrita e recuperação. | Exclusividade, royalties, titularidade e territórios por variante ainda exigem provas próprias; não são modalidades certificadas por35. |
|
||
| Recursos15/33/54; lista `/minhas-oportunidades`; estatísticas `/management/interests` | País/hierarquia/mapa, filtros e estatísticas já ensaiados reutilizados; retirada/restauro de anexo conservam originais. C126 e revogação acrescentam proteção em todas as rotas binárias. | Estes resultados não encerram consumidores públicos restantes, todas as estatísticas, toda cartografia ou todo o portal. |
|
||
|
||
O Promotor continua a guardar rascunhos incompletos. A interface mostra «Âmbito desta entrega» e «Privacidade dos anexos»; apenas seis categorias base são oferecidas no contexto autorizado com módulos OFF. API422 explica a variante excluída sem apagar os erros semânticos originais. O rascunho55planeado recupera noutra sessão; o54 conserva4500/monthly. Taxonomia, contratos e valores antigos não foram convertidos. A administração legada preserva a política existente; não conta como cobertura do novo workflow por perfil.
|
||
|
||
**Indisponíveis nesta candidata:** partilha individual de anexos; restauração de oportunidade; exportação normativa§27 integral (Response compatível conserva `normative_response_complete=false`); concessão, financiamento, fornecimento, outros e ofertas; SLA; legado/percurso integrado190000; importação/divulgação cartográfica; atos externos; dispositivos físicos, leitores reais e acessibilidade integral.
|
||
|
||
## ACL documental: alcance e correção
|
||
|
||
| Documentos/perfil | Operações incluídas | Operações indisponíveis |
|
||
| --- | --- | --- |
|
||
| Contratos, títulos, licenças, avaliação, finanças, beneficiário efetivo e restantes anexos próprios da oportunidade; imagens originais e WebP derivados | Metadados e download pelos Promotores autorizados da organização; Validadores/Publicadores conforme âmbito/tipo; Auditor/Superutilizador com acesso previsto. Coedição/edição só no estado autorizado; revisões/publicação independentes. | Conceder ou revogar por ficheiro a um destinatário escolhido; restringir o ficheiro a alguns membros autorizados; NDA/partilha com comprador externo. |
|
||
| Gestão geral sem perfil funcional, outra organização sem âmbito, visitante | Recusa da entrega privada, inclusive pela rota geral UUID e URL assinado. Publicação do teaser não torna os binários públicos. | Nenhum acesso por ser gestor da biblioteca, por conhecer o UUID, por estar autenticado ou por classificar metadados como public/authenticated. |
|
||
| Perfil revogado | Sessão anterior invalidada; novo login não recupera a autorização revogada. | Não é possível retirar cópias já descarregadas. Revogação de perfil não é ACL por ficheiro. |
|
||
| Biblioteca e sala de parceria | Reutilizam os seus controlos próprios. O original aceite29 mantém bytes/hash e consulta autorizada. | Não converter a prova de revogação da sala ou de retirada global de anexo em prova de ACL individual da oportunidade. |
|
||
|
||
C126 era **bloqueante**: gestor17 recebia403 na rota própria54 e200/PDF na rota geral. `VerifiedDocumentBinary` agora resolve a ligação existente, verifica a autorização vigente e a situação do recurso/oportunidade, antes de entregar os bytes. Sem nova tabela ou sistema de permissões. Originais/derivadas dessa origem sem vínculo válido falham fechados. Ambas as rotas passam a403; três PDFs recuperados por21/24/25 com hashes; imagem33 e derivadas autorizadas recuperadas, gestor/visitante recusados. Conta sintética32 recebeu/revogou um grant através do serviço autenticado:200→401 na sessão anterior→403 após novo login, com auditoria; nenhum grant das contas anteriores foi retirado.
|
||
|
||
**Condição de inclusão documental:** estes fluxos internos usam a política de grupo acima. Um documento que exija restrição a uma pessoa/subconjunto não pode integrar este pacote: a interface avisa e a operação de partilha individual não é oferecida. A correção fecha o contorno C126 em QA; não declara implementada a ACL individual.
|
||
|
||
## Restauração — propostas separadas, ainda por decidir
|
||
|
||
| Decisão | Quem | Destino e condições |
|
||
| --- | --- | --- |
|
||
| R-ARCHIVE | Publicador autorizado por âmbito/tipo, independente do Promotor e da aprovação, MFA recente | Oportunidade arquivada→`needs_information`, **não pública**, com motivo/auditoria. Conservar publicação anterior como história; nova submissão/revisões/decisões/publicação explícitas. Nunca repor a publicação automaticamente. |
|
||
| R-DRAFT | Autor ou outro Promotor autorizado da organização, com representação/tipo válidos | Só rascunho eliminado logicamente e **nunca submetido/publicado**→`draft` privado. Motivo/auditoria, mesmoID/originais/histórico. Não concede restauro de arquivo publicado. |
|
||
|
||
Nenhuma destas políticas foi implementada ou tratada como aprovação implícita. O restauro de anexos já ensaiado é operação distinta e mantém a autorização existente.
|
||
|
||
## Dependências e preparação real do destino
|
||
|
||
**020000 já instalado →030000→040000.**030000 adiciona3tabelas e `documents.storage_encryption`;040000 adiciona4tabelas, `users.portal_access_revision` e3colunas de opportunities: **7tabelas/5colunas no total**. Nenhuma conta, organização, representação, atribuição, titular ou publicação automática.050000/COUNTRY02 já está instalado e ON: não reaplicar.190000 entra apenas quando o percurso integrado for disponibilizado; não é dependência DDL do workflow isolado.
|
||
|
||
As prévias autenticadas QA mostram ambas instaladas/coerentes, dependências verdadeiras e `ready=false`: instalação já demonstrada não é readiness do destino. Fingerprints atuais:030000`{deps['resources_preview']['code_hash']}`,040000`{backup['profile_fingerprint']}`. A prévia do alvo só será válida com a revisão, schema, recibos e serviços correspondentes; parar se divergir antes de aplicar.
|
||
|
||
Destino lido em14:11:18UTC: **288tabelas,13contas,0organizações/representações,1.990territórios,0geometrias**,020000/050000 presentes; demais flagsOFF. Backup do **destino real**, renovado em **{target['verified_at']}**, restaurado só em `{target['restored_target']['database']}:55441`: **288tabelas,31sequências,799ficheiros**, comparação de dados/sequências/hashes e2envelopesMFA. Inclui4originais,312ficheiros de código/configuração/locks,476itens de runtime/bundles (incluindo assets antigos retidos),2TLS e5Apache/vhosts. Não reiniciou Apache nem alterou a base ativa.
|
||
|
||
QAfuncional: restauro **{backup['at']}**,295tabelas/31sequências/288ficheiros, código final e bundle atual,17MFA recuperáveis; chave histórica preservada e controlo negativo19 permanece recusado. Diferença295/288: **as sete tabelas030000/040000**. O acervo29 e os três PDFs sintéticos54 estão no backupQA privado; não se transferem automaticamente ao destino nem entram no ZIP público.
|
||
|
||
**Ainda bloqueiam disponibilização:** ClamD3310 com assinaturas obsoletas (~53,8h, `signatures_stale`); execução supervisionada de scans/GD/derivadas/worker no destino; ensaio de atualização do clone restaurado do alvo e readiness por instalador; titulares/âmbitos funcionais legítimos não designados. Mapas administrativos exigem importação separadamente autorizada porque o destino tem0geometrias. Não inventar organizações/representações: fluxos organizacionais só com cadastro/representação legítimos; âmbito individual usa o fluxo aprovado, sem organização fictícia.
|
||
|
||
## Alterações, evidências e reversão
|
||
|
||
Face à8af:6ficheiros alterados, total14no delta; proteção comum C126, fingerprint inclui essa proteção, disponibilidade das categorias/variantes no servidor e avisos da interface. **Recompilação de produção executada**,158assets, manifesto`{build['manifest_sha256']}`. Verificação TypeScript passou. A regressão revelou a ocultação do erro de ocupação: corrigida a agregação dos erros e repetido com sucesso o teste afetado (50assertions);25passes não afetados reutilizados. O código não mudou HTTPS/cookie/APP_KEY/cifra/schema/dados ativos. A nova prévia COUNTRY02 muda o fingerprint comum, sem justificar reinstalar050000.
|
||
|
||
As provas sanitizadas novas estão ligadas por hash no manifesto; as anteriores são reutilizadas por critério. Sete casos aprovados/publicados mantêm versões/hashes; renda/periocidade54preservadas. Nova interface vista a390px; não extrapolar para dispositivos ou acessibilidade integral.
|
||
|
||
Contenção futura: desligar só as flags do workflow, **mantendo a correção de entrega de ficheiros**. Preservar COUNTRY02ON,HTTPS,chaves,tabelas,colunas,dados,originais/histórico. Não voltar ao serviço binário vulnerável nem executar down/restauro completo automaticamente. Restauro completo exige decisão própria e tratamento das escritas posteriores ao snapshot. Sem uso/instalação no ativo neste incremento, a contenção ainda não foi executada.
|
||
|
||
Mesma matriz:3.401requisitos/linhas,7.739ocorrências,10linhas existentes atualizadas por projeção; zeroIDsnovos. Estados gerais preservados:7concluídos,3.236parciais,152não implementados,1preparado não ativado e5decisões. O fecho deC126não fecha os critérios individuais/documentais/por modalidade restantes. **`activation_ready=false`; não se solicita ativação enquanto os bloqueios acima subsistirem.**
|
||
'''
|
||
# Normalize new report units only; exact IDs, hashes and history are retained.
|
||
import re
|
||
report=re.sub(r'(\d+)(tabelas|ficheiros|sequências|contas|territórios|geometrias|colunas|MFA|assets|originais|itens|requisitos|ocorrências|linhas|assertions|passes|parciais|decisões|TLS|Apache|IDs)(?=\b)',r'\1 \2',report)
|
||
report=report.replace('COUNTRY02ON','COUNTRY02 ON').replace('QAfuncional','QA funcional').replace('backupQA','backup QA').replace('perioci','periodici').replace('zeroIDsnovos','zero IDs novos')
|
||
(out/'relatorio.md').write_text(report,encoding='utf8')
|
||
procedure=f'''# Procedimento da candidata {revision[:12]} — preparação, não ativação
|
||
|
||
1. Fixar revisão/ZIP/14ficheiros/158assets e confirmar base ativa e COUNTRY02ON. Conservar a candidata anterior somente como referência impedida porC126. Nenhuma instalação ou flag é aplicada nesta fase.
|
||
2. Antes de qualquer futura disponibilização: resolver ClamD/worker/GD no destino; executar o ensaio de atualização/restauração no clone real do alvo e emitir recibos separados030000/040000 para código/fingerprint exatos. Backup alvo de{target['verified_at']}verificado; renovar se expirado, se o destino/revisão divergir ou depois de alterações relevantes. Não converter o backup em readiness por escrever booleans sem ensaio. O atual não autoriza aplicação.
|
||
3. Agrupar a designação humana: dois titulares legítimos confirmados com MFA, terceiro gestor existente para aprovação do bootstrap, âmbitos/perfis funcionais e substitutos aplicáveis. Não escolher pessoas, criar organizações ou atribuir representações para demonstrar. O calendário/SLA permanece separado. Pedir autorização somente quando o pacote e estes serviços/ensaios estiverem completos.
|
||
4. Após autorização própria: disponibilizar o código/bundle com as flags do workflowOFF, COUNTRY02ON. Se for necessário reinício para a revisão, usar o controlo normal do Laragon e conferir vhosts; este delta não altera TLS, PHP ou DLL. Prévia autenticada em`/management/opportunity-resources-install`: conferir target/hash/schema/backup/dependências. POST nessa rota com`hash,confirm,idempotency_key,reason`, mantendo a chave nas repetições. Aplicar **somente030000** se ausente/coerente. Já instalado: changed=false; não reinstalar. Parar antes de aplicar em qualquer divergência.
|
||
5. Só depois: prévia autenticada`/management/profile-install`,030000presente e íntegro. POST com os mesmos quatro campos e chave da operação040000; aplicar **somente040000**. Bootstrap é ação distinta`/management/profile-install/bootstrap`, titulares designados e aprovação independente, sem concessões automáticas.190000/050000 não integram a aplicação deste pacote.
|
||
6. Disponibilização funcional separada: habilitar só profile_access, opportunity_dashboard_access e opportunity_specialized_drafts conforme autorização. Manter modulares, legado e percurso integradoOFF; nenhuma importação/publicação automática. Concessões pelo fluxo existente com representação e tipo legítimos. Mostrar Minhas oportunidades/Nova oportunidade ou pedido de perfil conforme autorização.
|
||
7. Critérios de sucesso: dashboard→rascunho→guardar/recuperar→documentos/scan→submeter→correção→revisões independentes→aprovação→publicação explícita restrita/teaser→nova sessão. Hashes/renda/documentos/estados preservados; mesma tentativa não duplica dados. Gestor sem âmbito, organização alheia, visitante e grant revogado recusados em rotas próprias/genéricas/URLsassinados. Auditoria e COUNTRYO2(050000)intactos. Reutilizar A/B,C37 e critérios anteriores; repetir apenas o que a mudança ou o uso real afetar.
|
||
8. Contenção: desligar só flags deste workflow, **conservar a correção C126** e negar binários privados sem perfil vigente. Preservar COUNTRY02ON,HTTPS,cookie,chaves,DDL,dados/documentos/histórico. Nunca repor o serviço binário vulnerável. Falha DDL deve manter transação/ledger coerentes. Após uso, não executar down/drop ou restauro completo; eventual restauro exige decisão separada e reconciliação das escritas posteriores.
|
||
|
||
R-ARCHIVE e R-DRAFT continuam propostas separadas, sem implementação nesta entrega. Arquivo não é exclusão lógica do rascunho; nenhum restauro de oportunidade a torna pública automaticamente. A ausência de geometrias deve ser apresentada claramente; mostrar limites oficiais exige pacote/importação autorizados à parte.
|
||
'''
|
||
procedure=procedure.replace('COUNTRYO2','COUNTRY02').replace('COUNTRY02ON','COUNTRY02 ON')
|
||
procedure=re.sub(r'(\d+)(ficheiros|assets|tabelas|colunas)(?=\b)',r'\1 \2',procedure)
|
||
(out/'procedimento.md').write_text(procedure,encoding='utf8');(out/'evidencias-por-criterio.json').write_text(json.dumps({'new':core['QA_evidence'],'reused':core['reused_evidence'],'quality':quality},ensure_ascii=False,indent=2),encoding='utf8')
|
||
archive='investmoz-workflow-'+revision[:12]+'.zip'
|
||
with zipfile.ZipFile(out/archive,'w',zipfile.ZIP_DEFLATED)as z:
|
||
for file in sorted(payload.rglob('*')):
|
||
if file.is_file():z.write(file,file.relative_to(out).as_posix())
|
||
for n in ['manifesto.json','relatorio.md','procedimento.md','evidencias-por-criterio.json']:z.write(out/n,n)
|
||
with zipfile.ZipFile(out/archive)as z:
|
||
assert z.testzip()is None and len(z.namelist())==176
|
||
for n,h in payload_hashes.items():assert hashlib.sha256(z.read('payload/'+n)).hexdigest()==h
|
||
receipt={'revision':revision,'code_revision':scope['code_revision'],'archive':archive,'sha256':sha(out/archive),'manifest_sha256':sha(out/'manifesto.json'),'payload_files':172,'members':176,'activation_ready':False,'activation_authorized':False}
|
||
(out/'pacote.json').write_text(json.dumps(receipt,indent=2)+'\n',encoding='utf8')
|
||
note='\n<!-- workflow-scope-qa-20261011 -->\n## Candidata delimitada e proteção documental — 11/10/2026\n\nC126corrigido somenteemQA: rota geral não contorna a autorização da oportunidade;originais/derivadas/hash e revogação de perfil demonstrados. ACL individual continua indisponível e anunciada; restauração R-ARCHIVE/R-DRAFT é decisão separada. Seis categorias base, variantes imobiliárias excluídas guardáveis em preparação mas bloqueadas na submissão, com erros semânticos preservados.\n\nNova candidata **'+revision[:12]+'**, código **'+scope['code_revision'][:12]+'**;14ficheiros+158assets recompilados. [Relatório/âmbito/ACL/decisões](../../../../outputs/investmoz-opportunity-workflow-scope-20261011/relatorio.md), [procedimento](../../../../outputs/investmoz-opportunity-workflow-scope-20261011/procedimento.md), [manifesto](../../../../outputs/investmoz-opportunity-workflow-scope-20261011/manifesto.json). A referência8af63e2fe657permanece intacta mas está impedida para disponibilização porC126.\n\nBackup/restauro do DESTINO REAL renovado em'+target['verified_at']+':288tabelas/31sequências/799ficheiros/2MFA; somenteleituraativa e restauroemQA55441. Não é autorização/prontidão: ClamD destinoobsoleto,worker/GD,ensaio deatualização declone ereadiness/authprévia/titulareslegítimos permanecem dependências. QAfuncional295tabelas/31sequências/288ficheiros/17MFA. COUNTRY02ativo/A-B/C37preservados;190000separado. Mesma matriz3401requisitos/7739ocorrências;10IDsatualizados,0novos e estados preservados.\n'
|
||
for name in ['relatorio-executivo.md','backlog.md','workflow-criterios-saida-20261011.md','plano-ativacao.md']:
|
||
file=root/'docs/investmoz/v2/auditoria-portal'/name;text=file.read_text(encoding='utf8');assert '<!-- workflow-scope-qa-20261011 -->'not in text;file.write_text(note+'\n'+text,encoding='utf8')
|
||
(previous/'IMPEDIMENTO-C126.md').write_text('Referência selada preservada. C126 descoberto emQA impede disponibilizar este pacote. A correção e a delimitação posteriores estão em../investmoz-opportunity-workflow-scope-20261011/relatorio.md. Nenhuma alteração no ZIP/manifesto antigos.\n',encoding='utf8')
|
||
print(json.dumps(receipt))
|