231 lines
30 KiB
Python
231 lines
30 KiB
Python
from pathlib import Path
|
|
from datetime import datetime, timezone
|
|
from collections import Counter
|
|
import hashlib, json, csv, zipfile
|
|
|
|
R = Path(__file__).resolve().parent.parent
|
|
P = R / 'storage/app/private/investmoz-v2/portal-audit'
|
|
O = R / 'outputs/investmoz-workflow-execution-preparation-20261011'
|
|
load = lambda p: json.loads(p.read_text(encoding='utf-8-sig'))
|
|
sha = lambda p: hashlib.sha256(p.read_bytes()).hexdigest()
|
|
write = lambda p, data: p.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding='utf-8')
|
|
candidate = load(P/'consolidated-candidate-latest.json')
|
|
C = Path(candidate['output'])
|
|
manifest = load(C/'manifesto.json')
|
|
backup = load(P/'workflow-execution-target-backup.json')
|
|
compat = load(P/'workflow-execution-preflight-qa.json')
|
|
queue = load(P/'workflow-execution-active-queue.json')
|
|
services = load(P/'workflow-execution-services-latest.json')
|
|
local = load(C/'localservice-qa.json')
|
|
assert not O.exists(), 'Preserve any previously delivered preparation.'
|
|
assert candidate['revision'] == backup['candidate_revision'] == compat['candidate_revision']
|
|
assert sha(C/'manifesto.json') == candidate['manifest_sha256'] == backup['candidate_manifest_sha256']
|
|
assert sha(C/candidate['zip']) == candidate['zip_sha256'] == backup['candidate_zip_sha256']
|
|
assert backup['result'] == compat['result'] == 'passed'
|
|
assert backup['source_installations']['country_flag'] and backup['source_installations']['organization_count'] == 0
|
|
assert not queue['pending_by_class'] and queue['failed_jobs'] == 0 and not queue['effective_notifications_enabled']
|
|
assert queue['configured_notification_recipient_count'] == 0 and queue['active_jobs_consumed'] == 0
|
|
assert sha(Path(backup['dump_path'])) == backup['dump_sha256'] and sha(Path(backup['files_path'])) == backup['files_sha256']
|
|
assert compat['tables_before'] == 288 and compat['tables_after_030000'] == 291 and compat['tables_after_040000'] == 295 and compat['added_columns'] == 5
|
|
assert backup['MFA_envelopes_readable'] == 2 and backup['active_originals_backed_up'] == 4
|
|
O.mkdir()
|
|
revision = candidate['revision'][:12]
|
|
groups = Counter(name.split('/')[0] for name in backup['active_files_manifest'])
|
|
assert sum(groups.values()) == backup['file_count']
|
|
recorded = datetime.now(timezone.utc).isoformat()
|
|
independence = {
|
|
'recorded_at': recorded, 'source': 'Explicit owner reply in this conversation',
|
|
'question': 'As contas ID 2 (nala@tempo.co.mz) e ID 13 (onala@me.com) pertencem a duas pessoas diferentes, que serão responsáveis independentes pela confirmação cruzada?',
|
|
'answer': 'Sim, são duas pessoas diferentes',
|
|
'accounts': [{'id': 2, 'email': 'nala@tempo.co.mz'}, {'id': 13, 'email': 'onala@me.com'}],
|
|
'different_persons_confirmed_by_owner': True, 'identity_system_or_accounts_created': False,
|
|
'bootstrap_executed': False, 'active_privileges_changed': False,
|
|
'interpretation': 'B3 holder designation and independence resolved; execution of the crossed bootstrap requires the single proposed technical authorization. Operational designations remain separate.'
|
|
}
|
|
write(O/'confirmacao-titulares.json', independence)
|
|
public_backup = {
|
|
'verified_at': backup['verified_at'], 'source': backup['target'], 'restored_clone': backup['restored_target'],
|
|
'candidate_revision': candidate['revision'], 'code_revision': candidate['code_revision'],
|
|
'candidate_zip_sha256': candidate['zip_sha256'], 'candidate_manifest_sha256': candidate['manifest_sha256'],
|
|
'database_dump_sha256': backup['dump_sha256'], 'files_archive_sha256': backup['files_sha256'],
|
|
'table_count': len(backup['tables']), 'sequence_count': len(backup['sequences']), 'file_count': backup['file_count'],
|
|
'file_groups': dict(groups), 'original_files': 4, 'missing_files': len(backup['missing_files']),
|
|
'MFA_envelopes_readable_under_preserved_keys': 2, 'table_rows_sequences_and_file_bytes_restored_identically': True,
|
|
'service_snapshot_at': backup['services_snapshot_at'], 'signature_files': backup['signature_file_count'],
|
|
'tasks_exported': backup['service_task_export_count'], 'ACL_metadata_objects': backup['ACL_metadata_exported'],
|
|
'ACL_metadata_roundtrip': backup['ACL_metadata_roundtrip'],
|
|
'ACL_metadata_scope': backup['ACL_scope'], 'live_task_or_DACL_restoration_executed': False,
|
|
'baseline': backup['source_installations'], 'compatibility': compat,
|
|
'active_writes': 0, 'backup_location': 'Private recovery storage; secrets and original bytes excluded from this report.',
|
|
'validity_gate': 'Compare candidate/base/schema/configuration and renew a consistent snapshot if changed or proof is older than24hours before execution.'
|
|
}
|
|
write(O/'backup-destino-verificado.json', public_backup)
|
|
write(O/'fila-leitura-preparacao.json', queue)
|
|
|
|
designations = '''# Designações técnicas e operacionais
|
|
|
|
O responsável confirmou que **ID 2, nala@tempo.co.mz**, e **ID 13, onala@me.com**, pertencem a **duas pessoas diferentes**. Contas existentes, email verificado e MFA normal confirmado já foram conferidos por leitura e no clone; não foram concedidos privilégios. A declaração resolve a independência dos titulares para a cerimónia proposta. A autorização de execução continua necessária.
|
|
|
|
| Conta existente | Papel | Organização/âmbito | Responsabilidade | Estado |
|
|
| --- | --- | --- | --- | --- |
|
|
| ID 2 — nala@tempo.co.mz | Superutilizador titular | Administração de segurança do portal | Pode iniciar o pedido ou confirmar o pedido do outro titular, em sessão/MFA próprios | Designado; pessoa independente confirmada; bootstrap não executado |
|
|
| ID 13 — onala@me.com | Superutilizador titular | Administração de segurança do portal | Pode iniciar o pedido ou confirmar o pedido do outro titular, em sessão/MFA próprios | Designado; pessoa independente confirmada; bootstrap não executado |
|
|
| A preencher pelo responsável | Promotor | Organização existente e representação legítima; tipos e âmbito expressos | Criar, coeditar quando autorizado, corrigir e submeter oportunidades | Pendente para abrir o fluxo |
|
|
| A preencher pelo responsável | Validador | Organização/âmbito e tipos expressos | Rever, fundamentar correção/rejeição/aprovação, respeitando a independência do autor | Pendente para abrir o fluxo |
|
|
| A preencher pelo responsável | Publicador | Organização/âmbito, tipos e visibilidade expressos | Publicar ou suspender no âmbito autorizado, sem converter decisão interna em decisão externa | Pendente para abrir o fluxo |
|
|
|
|
Para cada designação operacional indicar **ID ou email de conta existente, organização/representação, tipos de oportunidade, âmbito e responsabilidade**. Nenhuma password ou informação MFA é necessária nesta tabela. Não atribuir automaticamente os três papéis aos titulares. A ausência atual de organizações/representações impede demonstrar uma atividade operacional legítima no destino, mas não impede B1/B2, 030000, 040000 ou o bootstrap autorizado.
|
|
|
|
Coordenação, suporte e recurso mantêm a correspondência funcional já registada; não inventar titulares, competências modulares ou SLA nesta intervenção. O papel Superutilizador, isoladamente, não dá leitura operacional universal de anexos.
|
|
'''
|
|
(O/'designacoes-operacionais.md').write_text(designations, encoding='utf-8')
|
|
|
|
procedure = f'''# Proposta única de execução técnica
|
|
|
|
**Candidata {revision}, código {candidate['code_revision'][:12]}, sem alteração adicional de código ou recompilação.** O pacote e o manifesto anteriores permanecem intactos. Este procedimento atualiza a preparação e a separação das condições técnicas/operacionais; substitui, para a decisão atual, a exigência histórica de autorizações sequenciais de serviços e bootstrap. A confirmação dos titulares não é autorização de intervenção no destino.
|
|
|
|
ZIP SHA-256: `{candidate['zip_sha256']}`. Manifesto SHA-256: `{candidate['manifest_sha256']}`. [Manifesto fixo](../investmoz-workflow-consolidated-20261011/manifesto.json). [Preparação e backup](backup-destino-verificado.json). [Designações](designacoes-operacionais.md).
|
|
|
|
## Âmbito da única autorização técnica a solicitar
|
|
|
|
| Componente | Alteração exata proposta | Efeito no destino |
|
|
| --- | --- | --- |
|
|
| Código e bundle | 22 ficheiros e 159 recursos do ZIP consolidado; .env, chaves, TLS, cookie, vendor e originais não são copiados de QA | Compatibilidade MFA normal, bootstrap cruzado e workflow incluído preparados; flags operacionais OFF |
|
|
| B1 ClamD | Manter ClamAV 1.5.4 x64 em 127.0.0.1:3310; alinhar as duas tarefas antigas com o runtime/config/base realmente usados; freshclam com NotifyClamd correto; atualizar assinaturas oficiais | Scan local e recarga verificados no destino; nenhuma importação/publicação |
|
|
| B2 supervisão | Nova tarefa LocalService S-1-5-19, sem nova conta Windows; uma execução por minuto, IgnoreNew, PT3M, lease210s | Fila default processada somente após nova leitura e aprovação dos consumidores conhecidos; notificações externas OFF |
|
|
| B2 PHP web | Só vhost HTTPS do portal: upload20M, POST24M, memória256M, execução180s; GD/WebP existentes; ini global permanece128M/2M/8M | Uploads até o limite do contrato; outros vhosts preservados e conferidos após um reinício normal do Laragon |
|
|
| B2 permissões | RX no código/vendor/config/.env/binários; Modify só em documentos/quarentena/temporários/cache/logs, bootstrap/cache e dados/logs do scanner; neutralizar escrita herdada excessiva no âmbito exportado | Sem escrita de LocalService no código/config, sem leitura de controlos privados alheios; preservar Apache e operadores legítimos |
|
|
| 030000 | Instalação autenticada de recursos | 3 tabelas e documents.storage_encryption |
|
|
| 040000, após030000 | Instalação autenticada de perfis | 4 tabelas, users.portal_access_revision e 3 colunas de opportunities |
|
|
| Bootstrap cruzado | Pedido por um dos IDs2/13; confirmação independente pelo outro, em sessão/MFA próprios, sem autoaprovação | Uma dupla de titulares e pedido/recibos/auditoria nas entidades existentes; zero novas contas, organizações ou representações |
|
|
|
|
As sete tabelas/cinco colunas são o total aditivo, **288 → 291 → 295 tabelas**. Não executar migrate geral. Preservar050000/COUNTRY02 ON.190000, importações cartográficas/acervo, publicação de anúncios, modulares/ofertas/SLA, restauração e partilha individual ficam fora. Não atribuir papéis operacionais nem abrir o dashboard/fluxos nesta autorização técnica.
|
|
|
|
## Preparação concluída e validade
|
|
|
|
Backup do **destino real investemoz:5432**, origem `https://portal-investidor.test`, renovado e fisicamente restaurado em **{backup['restored_target']['database']}:55441**. Verificado em **{backup['verified_at']}**: **288 tabelas,31 sequências,{backup['file_count']} ficheiros**,4 originais,0 ausentes,2 envelopes MFA legíveis com as chaves preservadas. Comparação integral das linhas, sequências e bytes passou. O clone novo também confirmou030000→040000 e reversão transacional vazia, sem alterar linhas/colunas/seq originais; não é instalação autenticada no destino.
|
|
|
|
Composição:{dict(groups)}. Inclui configuração privada estável, bundle/código realmente ativos, TLS/vhosts, PHP/scanner,4 ficheiros de assinaturas,2 XML de tarefas e metadados de {backup['ACL_metadata_exported']} ACLs. Os 191 ficheiros anteriores eram o ensaio de código/bundle/documentos da candidata em QA, não este inventário maior de recuperação do destino. Os799 anteriores continuam preservados; o acréscimo é a cobertura de serviços, não novos documentos de utilizador.
|
|
|
|
Os bytes e os metadados das ACLs/XML foram recuperados/validados em área privada. **Não se aplicaram DACLs nem tarefas restauradas no destino.** O inventário cobre raízes afetadas/ancestrais e diretórios operacionais; antes de qualquer alteração ACL recursiva futura, exportar os descendentes exatamente afetados. Não afirmar restauro de permissões Windows reais pela mera recuperação do JSON.
|
|
|
|
A evidência tem validade de24h para o mecanismo autenticado. Imediatamente antes da janela, comparar alvo, hashes, schema, configuração e alterações posteriores. Se divergirem ou a prova expirar, renovar o snapshot correspondente antes de aplicar; não pedir ao utilizador para testar um ambiente incompleto. A/B,C37,coedição e provas funcionais sem delta conservam-se.
|
|
|
|
## Uma janela preparada de intervenção, após autorização
|
|
|
|
1. Conferir pacote/manifesto/base e backup atual. Confirmar COUNTRY02 ON,050000 instalada,030000/040000 ausentes ou consistentes. Exportar novamente estado das tarefas e ACLs exatamente abrangidas. Manter o novo worker OFF. Nenhum job ativo é consumido na preparação.
|
|
2. Disponibilizar o código e bundle fixos, preservando chave/cifra, HTTPS/cookie, dados e flags operacionais OFF. Não copiar .env/QA fixtures. Conferir dependências e hashes carregados.
|
|
3. Alinhar as duas tarefas ClamAV pelos controlos normais do Agendador. Atuar só na instância3310 identificada, com mecanismo próprio de paragem/recarga; não tocar13310/QA. Atualizar assinaturas, conferir PING/VERSION, idade<48h e scan real. Aplicar ACLs restritas após prévia; conferir os direitos positivos e negativos sob LocalService. Se houver direitos excessivos ou consumidor diferente, parar e manter worker OFF.
|
|
4. Aplicar o fragmento de limites apenas ao vhost HTTPS do portal; validar sintaxe/vhosts. Fazer **um reinício normal pelo Laragon**, conferir todos os vhosts afetados e PHP web efetivo. Registar worker inicialmente desabilitado com o comando do plano:`php.exe -c php.ini -d memory_limit=256M artisan queue:work database --queue=default --once --tries=3 --timeout=150 --memory=256 --no-interaction`, cadência60s,IgnoreNew,PT3M. PCNTL ausente; o timeout de150s sozinho não é o limite real.
|
|
5. Preparar os ficheiros privados de readiness destinados a5432, usando este backup/restauro e as provas QA de código exato. Escrever esses controlos apenas na janela autorizada. Gestor existente com email verificado/MFA normal abre **https://portal-investidor.test/management/opportunity-resources-install**, confere prévia alvo/hash/fingerprint **{manifest['resources_fingerprint']}** e confirma POST nessa rota **somente030000**. A seguir abre **https://portal-investidor.test/management/profile-install**, confere020000/030000, backup e fingerprint **{manifest['profile_fingerprint']}**, confirma POST **somente040000**, com chave idempotente estável e motivo. `ready=true` não é instalação. Prévia409/hash diferente: parar antes do DDL. Instalação já íntegra: não repetir.
|
|
6. Conferir ledger/auditoria/schema e preservação de050000/COUNTRY02. **Ler novamente a fila imediatamente antes de habilitar o worker**, mantendo notificações externas OFF e destinatários0. Classes conhecidas: ScanDocumentForMalware (SQL/arquivos/ClamD),RunSimulation (cálculo/persistência local),CompareMneBusiness (consulta/comparação/telemetria local). NotifyInterestReceived ou classe desconhecida: parar, preservar o job e resolver o efeito antes de qualquer consumo. A leitura da preparação não substitui esta verificação. Habilitar supervisão só após os controlos; recuperação específica do job, sem retry all/purge/reenvio duplicado. Validar processamento normal permitido e resultados/auditoria recuperáveis. Não inserir documentos ou oportunidades sintéticos no destino para demonstrar; se não houver job documental legítimo, registar esse critério de destino pendente e conservar a prova completa do clone.
|
|
7. Na mesma autorização técnica, um titular ID2/13 autentica com MFA e cria **POST /management/profile-install/bootstrap**, incluindo hash atual/confirm/idempotency_key/first_user_id=autor/second_user_id=outro/motivo. O pedido não concede privilégio. O outro abre **/management/profile-install/bootstrap/{{uuid}}** em sessão própria e MFA recente, confere os IDs e confirma **POST /management/profile-install/bootstrap/{{uuid}}/confirm**. Validade15min; retomar o pedido existente após erro/nova sessão, sem duplicar. Conferir criação atómica da dupla, consumo do pedido, auditoria de ambos e recusa de autoaprovação. A responsabilidade administrativa não dá acesso universal aos anexos.
|
|
8. Terminar com COUNTRY02 ON e os fluxos operacionais **OFF**. Registar resultados efetivos de destino separadamente dos clones, incluindo critérios não demonstráveis sem atividade legítima. As designações Promotor/Validador/Publicador com organização,tipos e âmbito condicionam a futura abertura; não são uma pré-condição adicional para concluir esta intervenção técnica.
|
|
|
|
Intervenções humanas agrupadas antecipadamente: operação Windows com direitos administrativos nos objetos do plano, um reinício normal Laragon e as autenticações locais dos dois responsáveis com MFA. Não transmitir passwords, códigos, cookies ou segredos. A cerimónia não exige terceiro gestor. Esta proposta não obriga a mudar serviços agora: aguarda a autorização única.
|
|
|
|
## Aceitação e reversão
|
|
|
|
Aceitação técnica: pacote/hash/fingerprints correspondentes; scanner3310 atualizado/scan válido; PHP web20M/24M/256M/GD/WebP; supervisão LocalService e limites180s/lease210s com direitos restritos; fila conhecida e notificações OFF;030000/040000 sem duplicações,7 tabelas/5 colunas, auditoria e COUNTRY02 preservados; bootstrap2/13 com sessões/MFA/decisões independentes; nenhum grant operacional/publicação/importação implícitos.
|
|
|
|
Contenção: parar/desabilitar só worker e flags deste pacote pelos controlos normais, preservar fila/quarentena, HTTPS/cookie, chave/cifra, COUNTRY02, dados/schema/histórico. Repor apenas configurações, tarefas e ACLs dos objetos exportados, com processos próprios parados; não rebaixar assinaturas válidas nem repor leitura universal. Antes do DDL/uso pode repor código/bundle de referência, verificando compatibilidade. Depois de bootstrap/uso não voltar automaticamente ao código de cerimónia antiga. Não executar down/drop, key:generate, purge de filas ou restauro completo do destino. **Restauro completo requer decisão separada e reconciliação das escritas posteriores.** O up/down ensaiado foi apenas transacional, num clone vazio das extensões.
|
|
|
|
## Habilitação operacional separada
|
|
|
|
Preencher [designações operacionais](designacoes-operacionais.md) com contas existentes, organizações/representações legítimas, tipos e âmbito. Conceder papéis pelos mecanismos existentes com auditoria e independência. A futura decisão delimitará as flags PORTAL_PROFILE_ACCESS_ENABLED,PORTAL_OPPORTUNITY_DASHBOARD_ACCESS_ENABLED e PORTAL_OPPORTUNITY_SPECIALIZED_DRAFTS_ENABLED. Nenhuma delas será habilitada nesta preparação/intervenção técnica. Não criar organizações/representações para demonstração. Sem atores/âmbitos, o critério operacional permanece pendente, mesmo com instalações corretas.
|
|
'''
|
|
spacing = {'destino real investemoz':'destino real investemoz','288 tabelas,31':'288 tabelas, 31',
|
|
'ficheiros**,4':'ficheiros**, 4', 'originais,0':'originais, 0', 'ausentes,2':'ausentes, 2',
|
|
'Composição:':'Composição: ', 'Os799':'Os 799', 'de24h':'de 24 h', 'de24':'de 24',
|
|
'A/B,C37,coedição':'A/B, C37, coedição','após030000':'após 030000', 'preservar050000':'preservar 050000',
|
|
'instalada,030000/040000':'instalada, 030000/040000', 'conferir020000':'conferir 020000',
|
|
'confere020000':'confere 020000', 'somente030000':'somente 030000', 'somente040000':'somente 040000',
|
|
'destinados a5432':'destinados a 5432', 'instância3310':'instância 3310', 'tocar13310/QA':'tocar 13310/QA',
|
|
'scanner3310':'scanner 3310', 'worker OFF':'worker OFF', 'destinatários0':'destinatários 0',
|
|
'cadência60s,IgnoreNew,PT3M':'cadência 60 s, IgnoreNew, PT3M', 'de150s':'de 150 s',
|
|
'Validade15min':'Validade 15 min', 'bootstrap2/13':'bootstrap 2/13',
|
|
'supervisão LocalService e limites180s/lease210s':'supervisão LocalService e limites 180 s/lease 210 s',
|
|
'auditoria e COUNTRY02':'auditoria e COUNTRY02', 'organização,tipos':'organização, tipos',
|
|
'ID2/13':'ID 2/13', 'IDs2/13':'IDs 2/13', 'de {':'de {', 'respetivos':'respetivos',
|
|
'3 colunas':'3 colunas','7 tabelas/5 colunas':'7 tabelas/5 colunas',
|
|
'ON.190000':'ON. 190000', 'PHP web20M/24M/256M':'PHP web 20M/24M/256M',
|
|
'sha256':'sha256'}
|
|
for a,b in spacing.items(): procedure = procedure.replace(a,b)
|
|
(O/'procedimento-unico.md').write_text(procedure, encoding='utf-8')
|
|
|
|
report = f'''# Preparação técnica concluída para revisão
|
|
|
|
**A candidata continua {revision}; código e bundle não mudaram.** A independência dos titulares **ID2,nala@tempo.co.mz**, e **ID13,onala@me.com** foi confirmada expressamente pelo responsável: duas pessoas diferentes. Não há bootstrap nem novas permissões no destino. O pacote98a8e0b70892 e os documentos de serviços originais permanecem referências históricas.
|
|
|
|
Backup/restauro do **destino real**, verificado em **{backup['verified_at']}**:288 tabelas,31 sequências,{backup['file_count']} ficheiros;4 originais,0 ausentes,2 envelopes MFA legíveis. Base restaurada exclusivamente num novo clone55441; linhas/seq/hashes de todos os ficheiros iguais. Configuração/chaves permanecem privadas. [Resultado sanitizado](backup-destino-verificado.json). Acréscimo de {groups['services']} ficheiros de serviços face aos799:scanner/configuração/assinaturas/PHP,XML das tarefas e metadados ACL. O restauro191 era de QA e conserva âmbito distinto.
|
|
|
|
Compatibilidade verificada **apenas no clone novo**:030000 leva288→291 tabelas;040000 leva291→295;cinco colunas. Reversão transacional vazia preservou todas as linhas, colunas,31 sequências e050000. Os fingerprints coincidem com a candidata. A/B,C37,coedição,categorias e provas de LocalService/bootstrap anteriores foram reutilizadas; nenhuma repetição funcional indiscriminada.
|
|
|
|
**[Procedimento único para uma autorização](procedimento-unico.md)** reúne código/bundle,B1/B2,030000→040000 e confirmação cruzada2/13. Operacionais continuamOFF. Scanner3310 atualizado, tarefas/ACLs do destino, limites PHP web e supervisão ainda precisam ser executados/verificados sob essa autorização. O inventário ACL foi recuperado como metadados, não aplicado ao Windows ativo; qualquer alteração recursiva requer extensão dos objetos exportados antes de executar.
|
|
|
|
Fila READ ONLY em **{queue['at']}**:zero jobs/failed_jobs,notificações externasOFF,destinatários0,zero consumo. A proposta exige outra leitura **imediatamente antes de habilitar worker**. Novo job desconhecido ou NotifyInterestReceived interrompe essa etapa, preservando dados.
|
|
|
|
**Habilitação operacional é outra condição:**faltam Promotores,Validadores e Publicadores, com contas existentes,organização/representação,tipos e âmbito. [Tabela para preenchimento](designacoes-operacionais.md). Esses dados impedem abrir fluxos, mas não preparar/instalar a infraestrutura e o schema. A responsabilidade Superutilizador não concede leitura universal de anexos.
|
|
|
|
COUNTRY02 ativo,fechos A/B/C37 e demais flagsOFF preservados. Legado,190000,modulares/ofertas/SLA,restauração/partilha individual e publicações/importações fora. Contenção preservaHTTPS,chave/cifra,originais,schema,fila,auditoria;restauro completo exige decisão separada. **Nenhuma alteração em base,serviços,ACLs ou flags ativos.**
|
|
|
|
Próxima decisão:autorizar conjuntamente esta intervenção técnica na candidata fixa, incluindo bootstrap dos dois titulares confirmados. Após a intervenção, designar e autorizar o âmbito operacional correspondente. Não solicitar credenciais na conversa.
|
|
'''
|
|
for a,b in {'ID2,nala':'ID 2, nala','ID13,onala':'ID 13, onala','pacote98':'pacote 98',
|
|
':288':': 288', ',31':', 31', ',4':', 4', ';4':'; 4', ',0':', 0', ',2':', 2',
|
|
'clone55441':'clone 55441', 'aos799':'aos 799', ':scanner':': scanner',
|
|
'restauro191':'restauro 191', ':030000':': 030000', 'leva288':'leva 288', 'leva291':'leva 291',
|
|
';040000':'; 040000', ';cinco':'; cinco', 'e050000':'e 050000', 'código/bundle,B1':'código/bundle, B1',
|
|
',030000':', 030000', 'cruzada2/13':'cruzada 2/13', 'continuamOFF':'continuam OFF',
|
|
'Scanner3310':'Scanner 3310', ':zero':': zero', ',notificações':', notificações',
|
|
'externasOFF':'externas OFF', ',destinatários0':', destinatários 0', ',zero':', zero',
|
|
':faltam':': faltam', ',Validadores':', Validadores', ',organização':', organização',
|
|
',tipos':', tipos', 'ativo,fechos':'ativo, fechos', 'e demais flagsOFF':'e demais flags OFF',
|
|
',190000':', 190000', ',modulares':', modulares', ',restauração':', restauração',
|
|
'preservaHTTPS,chave/cifra,originais,schema,fila,auditoria;restauro':'preserva HTTPS, chave/cifra, originais, schema, fila e auditoria; restauro',
|
|
'base,serviços,ACLs ou flags':'base, serviços, ACLs ou flags', ':autorizar':': autorizar',
|
|
'A/B,C37,coedição,categorias':'A/B, C37, coedição, categorias'}.items(): report=report.replace(a,b)
|
|
(O/'relatorio-preparacao.md').write_text(report, encoding='utf-8')
|
|
|
|
attestation = {
|
|
'format': 'investmoz-technical-execution-preparation-v1', 'prepared_at': recorded,
|
|
'candidate': candidate, 'prior_candidate_preserved': '98a8e0b70892',
|
|
'scope_delta_vs_fixed_candidate': 'No code/build/schema change; renewed destination recovery proof, owner-confirmed different persons and unified technical authorization separated from operational enablement.',
|
|
'owners_confirmed_independent_accounts': [2,13], 'backup': public_backup,
|
|
'requested_single_authorization': ['22code+159build', 'B1_clamd_alignment_definitions_tasks', 'B2_worker_supervision_scoped_ACLs_vhost_limits', 'authenticated_030000_then040000', 'crossed_bootstrap_existing_holders2and13'],
|
|
'not_requested': ['operational_roles_or_opening_flows', 'new_accounts_organizations_or_representations', '050000_reinstallation', '190000', 'imports_or_publications', 'offers_modular_competences_SLA', 'full_target_restore'],
|
|
'technical_execution_authorized': False, 'operational_enablement_authorized': False,
|
|
'COUNTRY02_enabled': True, 'other_flow_flags_remain_disabled': True, 'active_writes': 0,
|
|
'conditions_remaining_for_technical_execution': ['Single owner execution authorization', 'Fresh hashes/base/readiness24h and exact previews', 'Windows administrative intervention and normal Laragon restart', 'Both holders local MFA for crossed confirmation', 'Fresh queue read before worker and no outbound notification or unknown class'],
|
|
'conditions_remaining_for_operational_opening': ['Legitimate operational accounts/organizations/representation/types/scopes', 'Separate opening authorization', 'Affected authorized destination activity with visible recoverable results'],
|
|
'files': {p.name: sha(p) for p in sorted(O.iterdir()) if p.is_file()}
|
|
}
|
|
write(O/'manifesto-preparacao.json', attestation)
|
|
write(P/'workflow-execution-preparation-latest.json', {'output':str(O), 'candidate_revision': candidate['revision'], 'preparation_manifest_sha256': sha(O/'manifesto-preparacao.json'), 'backup_verified_at': backup['verified_at']})
|
|
|
|
# Prepare private readiness documents, never write the destination functional readiness paths now.
|
|
readiness = {**backup, 'compatibility_verified':True, 'reversal_verified':True, 'qa_passed':True,
|
|
'qa_compatibility_proof':str(P/'workflow-execution-preflight-qa.json'), 'sha256':backup['dump_sha256'],
|
|
'authenticated_installation_still_required':True, 'destination_readiness_not_deployed':True}
|
|
backup_dir = Path(backup['dump_path']).parent
|
|
for kind, fingerprint in [('resources',manifest['resources_fingerprint']),('profiles',manifest['profile_fingerprint'])]:
|
|
write(backup_dir/f'{kind}-readiness-prepared-private.json', {**readiness, 'code_hash':fingerprint})
|
|
|
|
csv.field_size_limit(16777216)
|
|
matrix = R/'docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv'
|
|
rows = list(csv.reader(matrix.open(encoding='utf-8-sig', newline='')))
|
|
headers=rows[0];data={row[0]:dict(zip(headers,row)) for row in rows[1:]}
|
|
tag=f'[Preparação técnica {revision} 11/10/2026]'
|
|
updates={
|
|
'AUD-OPS-01':f'Backup/restauro do destino real investemoz:5432 renovado em {backup["verified_at"]}, restaurado somente num novo clone 55441: 288 tabelas/31 sequências/{backup["file_count"]} ficheiros, 4 originais/0 ausentes/2 MFA legíveis; bytes/linhas/seq iguais. Incluídos {groups["services"]} ficheiros de serviços e metadados de {backup["ACL_metadata_exported"]} ACLs, sem aplicação no Windows ativo. B1/B2 agrupados com 030000→040000 e bootstrap na proposta única; execução ainda não autorizada. Default lida sem consumo/SMTP; nova leitura imediatamente antes do worker. COUNTRY02/050000 e flags dos demais fluxos preservados.',
|
|
'AUD-PROFILE-15':'Responsável confirmou expressamente que ID 2 (nala@tempo.co.mz) e ID 13 (onala@me.com) são duas pessoas diferentes. Designação/independência dos titulares resolvidas sem grants ativos; bootstrap cruzado QA reutilizado e cerimónia no destino incluída na única autorização técnica proposta. Contas/organização/representação/tipos/âmbito de Promotores, Validadores e Publicadores condicionam a abertura operacional, não B1/B2 nem as instalações. Bootstrap no destino não executado.',
|
|
'AUD-PROFILE-31':f'Candidata fixa {revision}/código 117d2d889701/ZIP hash inalterados. Novo backup do destino ligado ao manifesto e fingerprints; compatibilidade/reversão 030→040 verificada apenas no clone novo: 288→291→295 tabelas e cinco colunas; todas as linhas/colunas/seq originais preservadas. Uma proposta técnica para código/bundle, B1/B2, instalações autenticadas e bootstrap independente2/13; habilitação de perfis/fluxos permanece separada e OFF. Preparação não equivale a instalação; nenhuma escrita ativa.'
|
|
}
|
|
updates={key:{'Evidência funcional':data[key]['Evidência funcional']+'\n'+tag+' '+value+' Ver outputs/investmoz-workflow-execution-preparation-20261011/procedimento-unico.md e backup-destino-verificado.json.'} for key,value in updates.items()}
|
|
assert len(rows)-1 == len({row[0] for row in rows[1:]}) == 3401
|
|
write(P/'workflow-execution-matrix-baseline.json', {'rows':rows,'updates':updates,'tag':tag})
|
|
builder=(R/'tools/portal-consolidated-matrix.mjs').read_text(encoding='utf-8')
|
|
builder=builder.replace('consolidated-matrix-baseline.json','workflow-execution-matrix-baseline.json').replace('consolidated-matrix-before.csv','workflow-execution-matrix-before.csv').replace('consolidated-matrix-proof.json','workflow-execution-matrix-proof.json')
|
|
(R/'tools/portal-workflow-execution-matrix.mjs').write_text(builder, encoding='utf-8')
|
|
print(json.dumps({'result':'technical_proposal_prepared_not_executed','revision':revision,'tables':288,'sequences':31,'restored_files':backup['file_count'],'confirmed_independent_holders':[2,13],'active_writes':0}))
|