fix(proactive): retain unnamed administrative rows and preserve accepted import snapshot
This commit is contained in:
@@ -1667,14 +1667,16 @@ A base interna de oferta não exige transformar cada empresa numa organização
|
||||
|
||||
Incremento sobre o código entregue `569a1cd7`, ramo `codex/proactive-supply-qa-20261028`: **demonstrado em QA isolada, sem instalação nem importação no activo**. O relatório de conferência anterior permanece histórico: no destino activo, o uso das listas continua não demonstrado. Reutilizam-se a aceitação do percurso, o inventário de 13 ficheiros, os originais, as fontes e as provas anteriores; não se reabre a decisão da Tempo nem se encerra o estudo de mercado nacional.
|
||||
|
||||
Carregadas privadamente **343.041 observações**: 140.847 da lista 2014–2022, 201.917 de empresas licenciadas e 277 do cadastro turístico (duas folhas com estruturas distintas). Os quatro hashes dos originais e do CAE foram conferidos. Pré-visualização, análise Microsoft Defender sem ameaças e repetição idempotente 343.041→343.041 demonstradas. Os 139.591 registos com a mesma projecção administrativa são conservados como repetições; não representam empresas únicas nem duplicados de ficheiros por bytes. As 113.154 observações com denominações divergentes para um identificador partilhado ficam assinaladas, sem fusão automática. Contactos, documentos de identidade e NUIT não são devolvidos pela consulta.
|
||||
Carregadas privadamente **361.464 observações**: 148.556 da lista 2014–2022, 212.631 de empresas licenciadas e 277 do cadastro turístico (duas folhas com estruturas distintas). Os quatro hashes dos originais e do CAE foram conferidos. Pré-visualização, análise Microsoft Defender sem ameaças e repetição idempotente 343.041→343.041 demonstradas. Os 147.165 registos com a mesma projecção administrativa são conservados como repetições; não representam empresas únicas nem duplicados de ficheiros por bytes. As 113.880 observações com denominações divergentes para um identificador partilhado ficam assinaladas, sem fusão automática. Contactos, documentos de identidade e NUIT não são devolvidos pela consulta.
|
||||
|
||||
Consulta interna por localização canónica (incluindo descendentes), sector CAE e actividade; resultados paginados conservam fonte, folha/linha, hash e data original. O sector provém da hierarquia SELF_ID do CAE fornecido, sem inventar correspondência com os sectores de navegação. A selecção permite comparar possível concorrência, complementaridade, parceiro ou relação por determinar, com fundamento e incertezas. O servidor recupera a origem, impede reclassificar a evidência interna como pública e conserva-a no rascunho e no dossier privado. Não transforma a lista em anúncios, promotores, clientes confirmados ou publicação de directório.
|
||||
|
||||
**Gurué:** o operador QA sintético 1021 consultou 410 observações distintas, comparou dois registos reais (serviços agrícolas CAE 01610 e comércio de plantas/sementes/fertilizantes CAE 47732) com a hipótese já preparada de apoio à colheita e qualidade da folha verde. A oferta possível exige verificar sobreposição e colaboração, sem presumir mercado vazio. Rascunho 402 passa de v1 a v2, mantendo integralmente as cinco evidências anteriores, a ideia e o histórico. O mesmo dossier `883c8ec3-59a3-4074-b91c-b7d4a5d88ff0` passa de contexto1 a2 por pré-visualização e confirmação idempotente, preservando título e campos deliberados. A necessidade permanece **hipótese**, sem procura, falta de oferta ou viabilidade confirmadas. Gravação, recarregamento, acesso privado e resultado vazio como **informação insuficiente** demonstrados no navegador. Isto é prova técnica, sem substituir observação/aceitação da equipa.
|
||||
**Gurué:** o operador QA sintético 1021 consultou 410 observações distintas na primeira demonstração (435 após o complemento de registos sem denominação), comparou dois registos reais (serviços agrícolas CAE 01610 e comércio de plantas/sementes/fertilizantes CAE 47732) com a hipótese já preparada de apoio à colheita e qualidade da folha verde. A oferta possível exige verificar sobreposição e colaboração, sem presumir mercado vazio. Rascunho 402 passa de v1 a v2, mantendo integralmente as cinco evidências anteriores, a ideia e o histórico. O mesmo dossier `883c8ec3-59a3-4074-b91c-b7d4a5d88ff0` passa de contexto1 a2 por pré-visualização e confirmação idempotente, preservando título e campos deliberados. A necessidade permanece **hipótese**, sem procura, falta de oferta ou viabilidade confirmadas. Gravação, recarregamento, acesso privado e resultado vazio como **informação insuficiente** demonstrados no navegador. Isto é prova técnica, sem substituir observação/aceitação da equipa.
|
||||
|
||||
**Cobertura e pendências:** 198.112 observações sem correspondência territorial canónica única (incluindo 19 ambiguidades), 325 apenas com província e 80.796 sem designação de actividade CAE correspondente. Mantêm-se os rótulos originais e a incerteza; não há atribuição territorial aproximada nem preenchimento presumido. O cadastro de alojamento não é um censo exaustivo de hotéis/restaurantes. Situação operacional actual, capacidade, preços, procura e compromissos continuam por demonstrar. O incremento nacional é parcial; não encerra os requisitos amplos de mercado, clusters ou liquidação anual. **L8 permanece parcial e inalterado.**
|
||||
**Cobertura e pendências:** 205.608 observações sem correspondência territorial canónica única (incluindo 19 ambiguidades), 336 apenas com província e 82.864 sem designação de actividade CAE correspondente. Mantêm-se os rótulos originais e a incerteza; não há atribuição territorial aproximada nem preenchimento presumido. O cadastro de alojamento não é um censo exaustivo de hotéis/restaurantes. Situação operacional actual, capacidade, preços, procura e compromissos continuam por demonstrar. O incremento nacional é parcial; não encerra os requisitos amplos de mercado, clusters ou liquidação anual. **L8 permanece parcial e inalterado.**
|
||||
|
||||
Sete testes dirigidos/62 asserções, TypeScript e compilação QA passaram. As duas tabelas internas têm RLS forçada; teste com identidade sem privilégios confirma ocultação sem contexto de actor e leitura com contexto autorizado. Conferidos os hashes de todas as linhas anteriores nos sete conjuntos do inventário: só o rascunho402 e o mesmo dossier sofreram o delta intencional; Songo401, projectos, territórios, sectores, documentos e cadeias foram conservados. Provas fiscais aceites reutilizadas, sem repetir as suas suites.
|
||||
|
||||
Actualizados os cinco requisitos existentes `RF-CLU-003`, `MASTER-471012ab-0010`, `M2-d0c06a75-0147`, `M2-d0c06a75-0151` e `MASTER-1f0a4cde-0002`, preservando o restante estado e pendências. Nenhuma matriz ou backlog novo. A entrega activa futura mantém conferência de capacidade/compatibilidade com main, backup/restauro fresco, operação autenticada e delta instalado. Relatório: `docs/investmoz/unification/proactive-existing-supply-qa-20261028.json`.
|
||||
|
||||
Complemento final: as 18.423 linhas empresariais sem denominação social também foram conservadas, com essa lacuna explícita e sem reutilizar o nome pessoal do requerente. As 343.041 observações da primeira fotografia permaneceram idênticas; extensão e repetição idempotente atingem 361.464 sem substituir registos, alterar as comparações ou rever as provas aceites. Os exemplares e as fotografias anteriores foram preservados.
|
||||
|
||||
@@ -37,17 +37,18 @@
|
||||
}
|
||||
],
|
||||
"source_rows": {
|
||||
"companies.xlsx": 140847,
|
||||
"licensed.xlsx": 201917,
|
||||
"companies.xlsx": 148556,
|
||||
"licensed.xlsx": 212631,
|
||||
"tourism.xlsx": 277
|
||||
},
|
||||
"catalog": {
|
||||
"records": 343041,
|
||||
"repeated_projection": 139591,
|
||||
"identity_conflicts": 113154,
|
||||
"activity_unclassified": 80796,
|
||||
"territory_unmapped": 198112,
|
||||
"province_only": 325
|
||||
"records": 361464,
|
||||
"repeated_projection": 147165,
|
||||
"identity_conflicts": 113880,
|
||||
"activity_unclassified": 82864,
|
||||
"territory_unmapped": 205608,
|
||||
"province_only": 336,
|
||||
"unnamed_observations": 18423
|
||||
},
|
||||
"duplicate_meaning": "same projected administrative fields including entity identifier, licence/process,date,place,activity,name;all source sightings retained,not a unique-company count or byte-identical-file claim",
|
||||
"classification": {
|
||||
@@ -76,7 +77,27 @@
|
||||
"RLS": "forced on both;non-owner QA policy proof:0 rows without actor/read context;authorized context recovers row",
|
||||
"contacts_identity_documents_nuit_not_returned_by_query": true,
|
||||
"no_automatic_directory_publication": true,
|
||||
"no_promoters_or_user_organizations_created": true
|
||||
"no_promoters_or_user_organizations_created": true,
|
||||
"extension_first": {
|
||||
"before": 343041,
|
||||
"after": 361464,
|
||||
"sha256": "dec9db62a52a8bac5f1e2675aecbeb4239f2b1f4fa521db01693c32bdfeef01e",
|
||||
"extension": true,
|
||||
"previous_snapshot": "6a9c820c73a8c535ed3cdfc03db0311edf0300f1f97ade75f0fce3d3c84a02e1",
|
||||
"publication": false,
|
||||
"database": "proactive_investment_20261027_test",
|
||||
"port": 55441
|
||||
},
|
||||
"extension_replay": {
|
||||
"before": 361464,
|
||||
"after": 361464,
|
||||
"sha256": "dec9db62a52a8bac5f1e2675aecbeb4239f2b1f4fa521db01693c32bdfeef01e",
|
||||
"extension": true,
|
||||
"previous_snapshot": "6a9c820c73a8c535ed3cdfc03db0311edf0300f1f97ade75f0fce3d3c84a02e1",
|
||||
"publication": false,
|
||||
"database": "proactive_investment_20261027_test",
|
||||
"port": 55441
|
||||
}
|
||||
},
|
||||
"proactive_delta": "private authenticated territory query,CAE sector/activity filters,pagination,source/row/date/hash;select existing observations,compare competition/complementarity/possible partner/uncertain with rationale and limitations;server resolves source lineage,keeps list-derived evidence internal;save/reload and private dossier preserve references",
|
||||
"gurue": {
|
||||
@@ -107,7 +128,15 @@
|
||||
"context_revision": 2,
|
||||
"deliberate_dossier_title_and_fields_preserved": true,
|
||||
"prior_source_v1_history_retained": true,
|
||||
"songo_401_unchanged": true
|
||||
"songo_401_unchanged": true,
|
||||
"refreshed_offer_query_total": 435,
|
||||
"initial_browser_proof_retained": true,
|
||||
"dossier_comparisons_visible": {
|
||||
"existing_dossier_comparison_1_visible": true,
|
||||
"existing_dossier_comparison_2_visible": true,
|
||||
"read_only_after_commit": true,
|
||||
"errors": []
|
||||
}
|
||||
},
|
||||
"verification": {
|
||||
"delta_tests": 7,
|
||||
@@ -160,9 +189,9 @@
|
||||
},
|
||||
"remaining": [
|
||||
"No installation or import in active portal;there the list-backed use remains not demonstrated until delivery.",
|
||||
"198112 observations lack a unique canonical territorial match,including19 ambiguous names;325 have province only. Raw source territory remains available in private originals.",
|
||||
"80796 observations lack an exact supplied CAE activity label;do not impute sector/activity.",
|
||||
"113154 observations have differing names for a shared valid-shaped identifier;identity needs reconciliation,not automatic merger.",
|
||||
"205608 observations lack a unique canonical territorial match,including19 ambiguous names;336 have province only. Raw source territory remains available in private originals.",
|
||||
"82864 observations lack an exact supplied CAE activity label;do not impute sector/activity.",
|
||||
"113880 observations have differing names for a shared valid-shaped identifier;identity needs reconciliation,not automatic merger.",
|
||||
"Historical administrative records do not establish current operating status,capacity,prices,demand,contracts or market vacancy.",
|
||||
"National mapping/classification completeness and actual team use remain partial;Gurué proof does not close all market-study/cluster requirements.",
|
||||
"Active delivery requires capability/compatibility review,fresh backup+restore,authenticated operation and installed delta check through the existing Git procedure."
|
||||
@@ -176,7 +205,26 @@
|
||||
"outputs/proactive-supply-20261028/gurue-ui-proof.json",
|
||||
"outputs/proactive-supply-20261028/preservation-proof.json",
|
||||
"outputs/proactive-supply-20261028/tests-receipt.json",
|
||||
"outputs/proactive-supply-20261028/dossier-visual-proof.json"
|
||||
"outputs/proactive-supply-20261028/dossier-visual-proof.json",
|
||||
"outputs/proactive-supply-20261028/supply-extension-preservation.json",
|
||||
"outputs/proactive-supply-20261028/refreshed-gurue-query.json"
|
||||
],
|
||||
"L8": "unchanged,partial;this increment has no fiscal calculation change"
|
||||
"L8": "unchanged,partial;this increment has no fiscal calculation change",
|
||||
"supplement": {
|
||||
"previous_snapshot_records": 343041,
|
||||
"added_unnamed_source_rows": 18423,
|
||||
"placeholder": "Denominação não indicada;never the personal applicant name",
|
||||
"all_previous_observations_unchanged": {
|
||||
"old_observations_unchanged": 343041,
|
||||
"new_observations": 18423
|
||||
},
|
||||
"preview_both_hashes_bound": {
|
||||
"previous_observations_unchanged": 343041,
|
||||
"new_observations": 18423,
|
||||
"no_replacement": true,
|
||||
"previous_sha256": "6a9c820c73a8c535ed3cdfc03db0311edf0300f1f97ade75f0fce3d3c84a02e1",
|
||||
"sha256": "dec9db62a52a8bac5f1e2675aecbeb4239f2b1f4fa521db01693c32bdfeef01e"
|
||||
},
|
||||
"original_source_rows_accounted_for": "148556 companies+212631 licensed nonempty data rows,excluding headers;277 tourism establishment sightings from two structures"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7225,14 +7225,16 @@ A base interna de oferta não exige transformar cada empresa numa organização
|
||||
|
||||
Incremento sobre o código entregue `569a1cd7`, ramo `codex/proactive-supply-qa-20261028`: **demonstrado em QA isolada, sem instalação nem importação no activo**. O relatório de conferência anterior permanece histórico: no destino activo, o uso das listas continua não demonstrado. Reutilizam-se a aceitação do percurso, o inventário de 13 ficheiros, os originais, as fontes e as provas anteriores; não se reabre a decisão da Tempo nem se encerra o estudo de mercado nacional.
|
||||
|
||||
Carregadas privadamente **343.041 observações**: 140.847 da lista 2014–2022, 201.917 de empresas licenciadas e 277 do cadastro turístico (duas folhas com estruturas distintas). Os quatro hashes dos originais e do CAE foram conferidos. Pré-visualização, análise Microsoft Defender sem ameaças e repetição idempotente 343.041→343.041 demonstradas. Os 139.591 registos com a mesma projecção administrativa são conservados como repetições; não representam empresas únicas nem duplicados de ficheiros por bytes. As 113.154 observações com denominações divergentes para um identificador partilhado ficam assinaladas, sem fusão automática. Contactos, documentos de identidade e NUIT não são devolvidos pela consulta.
|
||||
Carregadas privadamente **361.464 observações**: 148.556 da lista 2014–2022, 212.631 de empresas licenciadas e 277 do cadastro turístico (duas folhas com estruturas distintas). Os quatro hashes dos originais e do CAE foram conferidos. Pré-visualização, análise Microsoft Defender sem ameaças e repetição idempotente 343.041→343.041 demonstradas. Os 147.165 registos com a mesma projecção administrativa são conservados como repetições; não representam empresas únicas nem duplicados de ficheiros por bytes. As 113.880 observações com denominações divergentes para um identificador partilhado ficam assinaladas, sem fusão automática. Contactos, documentos de identidade e NUIT não são devolvidos pela consulta.
|
||||
|
||||
Consulta interna por localização canónica (incluindo descendentes), sector CAE e actividade; resultados paginados conservam fonte, folha/linha, hash e data original. O sector provém da hierarquia SELF_ID do CAE fornecido, sem inventar correspondência com os sectores de navegação. A selecção permite comparar possível concorrência, complementaridade, parceiro ou relação por determinar, com fundamento e incertezas. O servidor recupera a origem, impede reclassificar a evidência interna como pública e conserva-a no rascunho e no dossier privado. Não transforma a lista em anúncios, promotores, clientes confirmados ou publicação de directório.
|
||||
|
||||
**Gurué:** o operador QA sintético 1021 consultou 410 observações distintas, comparou dois registos reais (serviços agrícolas CAE 01610 e comércio de plantas/sementes/fertilizantes CAE 47732) com a hipótese já preparada de apoio à colheita e qualidade da folha verde. A oferta possível exige verificar sobreposição e colaboração, sem presumir mercado vazio. Rascunho 402 passa de v1 a v2, mantendo integralmente as cinco evidências anteriores, a ideia e o histórico. O mesmo dossier `883c8ec3-59a3-4074-b91c-b7d4a5d88ff0` passa de contexto1 a2 por pré-visualização e confirmação idempotente, preservando título e campos deliberados. A necessidade permanece **hipótese**, sem procura, falta de oferta ou viabilidade confirmadas. Gravação, recarregamento, acesso privado e resultado vazio como **informação insuficiente** demonstrados no navegador. Isto é prova técnica, sem substituir observação/aceitação da equipa.
|
||||
**Gurué:** o operador QA sintético 1021 consultou 410 observações distintas na primeira demonstração (435 após o complemento de registos sem denominação), comparou dois registos reais (serviços agrícolas CAE 01610 e comércio de plantas/sementes/fertilizantes CAE 47732) com a hipótese já preparada de apoio à colheita e qualidade da folha verde. A oferta possível exige verificar sobreposição e colaboração, sem presumir mercado vazio. Rascunho 402 passa de v1 a v2, mantendo integralmente as cinco evidências anteriores, a ideia e o histórico. O mesmo dossier `883c8ec3-59a3-4074-b91c-b7d4a5d88ff0` passa de contexto1 a2 por pré-visualização e confirmação idempotente, preservando título e campos deliberados. A necessidade permanece **hipótese**, sem procura, falta de oferta ou viabilidade confirmadas. Gravação, recarregamento, acesso privado e resultado vazio como **informação insuficiente** demonstrados no navegador. Isto é prova técnica, sem substituir observação/aceitação da equipa.
|
||||
|
||||
**Cobertura e pendências:** 198.112 observações sem correspondência territorial canónica única (incluindo 19 ambiguidades), 325 apenas com província e 80.796 sem designação de actividade CAE correspondente. Mantêm-se os rótulos originais e a incerteza; não há atribuição territorial aproximada nem preenchimento presumido. O cadastro de alojamento não é um censo exaustivo de hotéis/restaurantes. Situação operacional actual, capacidade, preços, procura e compromissos continuam por demonstrar. O incremento nacional é parcial; não encerra os requisitos amplos de mercado, clusters ou liquidação anual. **L8 permanece parcial e inalterado.**
|
||||
**Cobertura e pendências:** 205.608 observações sem correspondência territorial canónica única (incluindo 19 ambiguidades), 336 apenas com província e 82.864 sem designação de actividade CAE correspondente. Mantêm-se os rótulos originais e a incerteza; não há atribuição territorial aproximada nem preenchimento presumido. O cadastro de alojamento não é um censo exaustivo de hotéis/restaurantes. Situação operacional actual, capacidade, preços, procura e compromissos continuam por demonstrar. O incremento nacional é parcial; não encerra os requisitos amplos de mercado, clusters ou liquidação anual. **L8 permanece parcial e inalterado.**
|
||||
|
||||
Sete testes dirigidos/62 asserções, TypeScript e compilação QA passaram. As duas tabelas internas têm RLS forçada; teste com identidade sem privilégios confirma ocultação sem contexto de actor e leitura com contexto autorizado. Conferidos os hashes de todas as linhas anteriores nos sete conjuntos do inventário: só o rascunho402 e o mesmo dossier sofreram o delta intencional; Songo401, projectos, territórios, sectores, documentos e cadeias foram conservados. Provas fiscais aceites reutilizadas, sem repetir as suas suites.
|
||||
|
||||
Actualizados os cinco requisitos existentes `RF-CLU-003`, `MASTER-471012ab-0010`, `M2-d0c06a75-0147`, `M2-d0c06a75-0151` e `MASTER-1f0a4cde-0002`, preservando o restante estado e pendências. Nenhuma matriz ou backlog novo. A entrega activa futura mantém conferência de capacidade/compatibilidade com main, backup/restauro fresco, operação autenticada e delta instalado. Relatório: `docs/investmoz/unification/proactive-existing-supply-qa-20261028.json`.
|
||||
|
||||
Complemento final: as 18.423 linhas empresariais sem denominação social também foram conservadas, com essa lacuna explícita e sem reutilizar o nome pessoal do requerente. As 343.041 observações da primeira fotografia permaneceram idênticas; extensão e repetição idempotente atingem 361.464 sem substituir registos, alterar as comparações ou rever as provas aceites. Os exemplares e as fotografias anteriores foram preservados.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -65,6 +65,7 @@ def main():
|
||||
p.add_argument('--sources', required=True)
|
||||
p.add_argument('--output', required=True)
|
||||
p.add_argument('--only-tourism', action='store_true', help='Rebuild only tourism in an existing private preview')
|
||||
p.add_argument('--only-missing-names', action='store_true', help='Add nonempty company rows without a social denomination; never substitute the personal applicant name')
|
||||
a = p.parse_args()
|
||||
output = Path(a.output)
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
@@ -101,7 +102,8 @@ def main():
|
||||
counts = {}
|
||||
if a.only_tourism:
|
||||
db.execute('delete from records where source_hash=?',(SOURCES['tourism.xlsx'][0],))
|
||||
for alias in (('tourism.xlsx',) if a.only_tourism else ('companies.xlsx','licensed.xlsx','tourism.xlsx')):
|
||||
aliases=('companies.xlsx','licensed.xlsx') if a.only_missing_names else (('tourism.xlsx',) if a.only_tourism else ('companies.xlsx','licensed.xlsx','tourism.xlsx'))
|
||||
for alias in aliases:
|
||||
source_hash, _, period = SOURCES[alias]
|
||||
count = 0
|
||||
province = ''
|
||||
@@ -130,8 +132,13 @@ def main():
|
||||
continue
|
||||
old = alias == 'companies.xlsx'
|
||||
name = c.get('L','')
|
||||
if not name:
|
||||
if a.only_missing_names and name:
|
||||
continue
|
||||
if not any(c.values()):
|
||||
continue
|
||||
# A missing social denomination is a data gap, not a reason to
|
||||
# discard an authorised source row or publish an applicant's name.
|
||||
name = name or 'Denominação não indicada'
|
||||
province, district = c.get('Y' if old else 'V',''), c.get('X' if old else 'U','')
|
||||
cae = c.get('S' if old else 'O','')
|
||||
activity = labels.get(cae, '')
|
||||
@@ -156,12 +163,14 @@ def main():
|
||||
db.commit()
|
||||
counts[alias] = count
|
||||
print(json.dumps({'source':alias,'rows_processed':count}), flush=True)
|
||||
db.execute('update records set identity_conflict=1 where entity_key in (select entity_key from records group by entity_key having count(distinct lower(name))>1)')
|
||||
db.execute('update records set identity_conflict=0')
|
||||
db.execute("update records set identity_conflict=1 where entity_key in (select entity_key from records where name<>'Denominação não indicada' group by entity_key having count(distinct lower(name))>1)")
|
||||
db.commit()
|
||||
counts={alias:db.execute('select count(*) from records where source_hash=?',(SOURCES[alias][0],)).fetchone()[0] for alias in ('companies.xlsx','licensed.xlsx','tourism.xlsx')}
|
||||
manifest.update(rows_processed=counts, records=db.execute('select count(*) from records').fetchone()[0],
|
||||
duplicate_sightings=db.execute('select count(*) from records where duplicate_of is not null').fetchone()[0],
|
||||
conflicting_identity_sightings=db.execute('select count(*) from records where identity_conflict=1').fetchone()[0],
|
||||
unnamed_observations=db.execute("select count(*) from records where name='Denominação não indicada'").fetchone()[0],
|
||||
unclassified_activity=db.execute("select count(*) from records where activity=''").fetchone()[0],
|
||||
unresolved_territory=db.execute("select count(*) from records where district='' or province=''").fetchone()[0])
|
||||
db.close()
|
||||
|
||||
@@ -23,7 +23,7 @@ if($operation==='schema'){
|
||||
}
|
||||
echo "QA schema available; no existing table altered.\n";exit;
|
||||
}
|
||||
if($operation==='import'){
|
||||
if(in_array($operation,['import','extend'],true)){
|
||||
$dir=$out.'/private-v2';
|
||||
$manifest=json_decode(file_get_contents($dir.'/preview.json'),true,512,JSON_THROW_ON_ERROR);
|
||||
$scan=json_decode(file_get_contents($out.'/private/scan.json'),true,512,JSON_THROW_ON_ERROR);
|
||||
@@ -31,11 +31,25 @@ if($operation==='import'){
|
||||
$file=$dir.'/observations.jsonl';$hash=hash_file('sha256',$file);
|
||||
if(($argv[2]??'')!==$hash)throw new RuntimeException('Review preview and supply exact JSONL hash');
|
||||
$before=DB::table('proactive_supply_observations')->count();
|
||||
DB::transaction(function()use($manifest,$file,$hash){
|
||||
$extension=$operation==='extend';$previousHash=$argv[3]??null;
|
||||
if($extension){
|
||||
$delta=json_decode(file_get_contents($dir.'/extension-preview.json'),true,512,JSON_THROW_ON_ERROR);
|
||||
if(($delta['sha256']??null)!==$hash||($delta['previous_sha256']??null)!==$previousHash||empty($delta['no_replacement'])||$delta['previous_observations_unchanged']+$delta['new_observations']!==$manifest['records'])throw new RuntimeException('Extension must prove all previously accepted observations unchanged and bind both snapshot hashes.');
|
||||
}
|
||||
DB::transaction(function()use($manifest,$file,$hash,$extension,$previousHash){
|
||||
DB::select("select pg_advisory_xact_lock(hashtext('proactive-supply-import-v1'))");
|
||||
foreach($manifest['sources']as$s){
|
||||
$existing=DB::table('proactive_supply_sources')->where('sha256',$s['sha256'])->first();
|
||||
if($existing && data_get(json_decode($existing->receipt,true),'transport_sha256')!==$hash)throw new RuntimeException('Existing source has a different prepared classification snapshot; preserve it and prepare an explicit mapping delta instead of silently replacing observations.');
|
||||
if($existing && data_get(json_decode($existing->receipt,true),'transport_sha256')!==($extension?$previousHash:$hash))throw new RuntimeException('Existing source has a different prepared classification snapshot; preserve it and prepare an explicit mapping delta instead of silently replacing observations.');
|
||||
if($extension){
|
||||
if(!$existing)throw new RuntimeException('An extension must reference the already imported originals.');
|
||||
$receipt=json_decode($existing->receipt,true);
|
||||
$history=$receipt['extensions']??[];
|
||||
if(!in_array($hash,array_column($history,'transport_sha256'),true)){
|
||||
$history[]=['transport_sha256'=>$hash,'rows_in_extended_preview'=>$manifest['records'],'at'=>now()->toIso8601String(),'operation'=>'append previously unrepresented source rows;existing observations immutable'];
|
||||
DB::table('proactive_supply_sources')->where('sha256',$s['sha256'])->update(['receipt'=>json_encode([...$receipt,'extensions'=>$history])]);
|
||||
}
|
||||
}
|
||||
DB::table('proactive_supply_sources')->insertOrIgnore(['sha256'=>$s['sha256'],'name'=>$s['name'],'period'=>$s['period'],'limitations'=>$manifest['limitations'],'receipt'=>json_encode(['source'=>$s,'preview_rows'=>$manifest['records'],'transport_sha256'=>$hash,'scan'=>'Defender custom scan, no threats, hash-specific receipt','scope'=>'isolated QA, internal analysis only']),'imported_at'=>now()]);
|
||||
}
|
||||
$f=fopen($file,'rb');$batch=[];$n=0;
|
||||
@@ -48,7 +62,7 @@ if($operation==='import'){
|
||||
fclose($f);if($batch)DB::table('proactive_supply_observations')->insertOrIgnore($batch);
|
||||
if($n!==$manifest['records'])throw new RuntimeException('Incomplete candidate');
|
||||
});
|
||||
$receipt=['before'=>$before,'after'=>DB::table('proactive_supply_observations')->count(),'sha256'=>$hash,'publication'=>false,'database'=>'proactive_investment_20261027_test','port'=>55441];
|
||||
file_put_contents($out.'/import-'.($before?'replay':'first').'.json',json_encode($receipt,JSON_PRETTY_PRINT));echo json_encode($receipt)."\n";exit;
|
||||
$receipt=['before'=>$before,'after'=>DB::table('proactive_supply_observations')->count(),'sha256'=>$hash,'extension'=>$extension,'previous_snapshot'=>$previousHash,'publication'=>false,'database'=>'proactive_investment_20261027_test','port'=>55441];
|
||||
file_put_contents($out.'/import-'.($extension?'extension':($before?'replay':'first')).'.json',json_encode($receipt,JSON_PRETTY_PRINT));echo json_encode($receipt)."\n";exit;
|
||||
}
|
||||
throw new RuntimeException('Use geography, schema, import <reviewed hash>, or test; exclusively isolated QA.');
|
||||
throw new RuntimeException('Use geography,schema,import <reviewed hash>,extend <reviewed hash> <previous snapshot hash>,or test;exclusively isolated QA.');
|
||||
|
||||
Reference in New Issue
Block a user