khtst-rust / scripts /78_publicar_v010.py
PowerMachine's picture
v0.10.0: análise/prova/teste das críticas de engenharia Qwen3.8 lote 3 (r-35) — divisão SRP dos monólitos jepa/pensamento/moe/python em 26 submódulos (API estável via re-exports; 'Amdahl de compilação' refutada por experimento controlado, builds frios neutros), checkpoints atômicos SHA-256 puro FIPS 180-4 + fsync + rename + manifesto (CP-1..CP-3; correções da proposta: sem destruir estado anterior, manifesto com barreira, sem bincode/unwrap), TemperaturaInversa T-V3 (fronteira tipada da convexidade N-2; alegação compile-time corrigida), trait CamadaKhtst+CamadaHomeostatica (premissa do controlador refutada no fonte; Vec<Var>; adaptador MoeComPapel bit-a-bit), CLI Typer 75 (fachada aditiva com resume verificado por hash) — 123/123 cargo, 107/107 gates, treino real Wikipédia PT-BR com checkpoints íntegros
06e4b6f verified
Raw History Blame Contribute Delete
9.07 kB
#!/usr/bin/env python3
"""78_publicar_v010.py — Publicação da v0.10.0 no HF (UM ÚNICO upload_folder
organizado — o HF bloqueia envios parciais em sequência; upload atômico).
Fases:
1. inventário da conta + APAGAMENTO de estados de treino remanescentes;
2. varredura local do VALOR do token (nenhum arquivo pode contê-lo);
3. UM ÚNICO upload_folder com ignore_patterns EXPLÍCITOS +
delete_patterns p/ monólitos dissolvidos (src/jepa.rs → src/jepa/…);
4. verificação pós-upload (0 estados, módulos-chave presentes);
5. varredura REMOTA do valor do token;
6. apagamento dos estados de treino LOCAIS (checkpoints + manifestos).
v0.10.0: manifestos (*.manifest.json) NÃO são publicados — só têm sentido
ao lado do checkpoint correspondente (que também não é publicado).
Token: EXCLUSIVAMENTE via variável de ambiente HF_TOKEN (nunca em arquivo).
"""
import os, sys, tempfile
ARQUIVOS_EXCLUIR_DIRS = {"target", ".cargo", "__pycache__", ".git", ".venv",
"skills", "externos"}
ARQUIVOS_EXCLUIR_NOME = {"shard_treino.jsonl", "shard_validacao.jsonl",
"bpe.json", "rustup-init.sh"}
SUFIXOS_ESTADO = (".pt", ".pth", ".ckpt", ".safetensors", ".bin", ".npz",
".msgpack")
NOMES_ESTADO = {"gerador_conceitos.json", "tokenizador_conceitos.json",
"gerador_aritmetica.json", "_drill_ck.json"}
# monólitos da v0.9.0 dissolvidos em diretórios na v0.10.0 (r-35 §2)
MONOLITOS_VELHOS = ["src/python.rs", "src/jepa.rs", "src/pensamento.rs",
"src/moe_redirecionavel.rs"]
def coletar(pasta):
arquivos = {}
for raiz, dirs, fs in os.walk(pasta):
dirs[:] = [d for d in dirs if d not in ARQUIVOS_EXCLUIR_DIRS]
for f in fs:
if f in ARQUIVOS_EXCLUIR_NOME or f in NOMES_ESTADO:
continue
if f.endswith(SUFIXOS_ESTADO) or f.endswith(".estado.json"):
continue
if f.endswith(".manifest.json") or f.endswith(".manifest.json.tmp"):
continue
if f.endswith(".so") or f in (".gitignore", "Cargo.lock.ori"):
continue
if f.startswith("hf_") or f.startswith("intros_"):
continue
caminho = os.path.join(raiz, f)
arquivos[os.path.relpath(caminho, pasta)] = caminho
return arquivos
def varre_token_em_arquivos(token, pares):
tb = token.encode()
achados = []
for rel, p in pares.items():
try:
with open(p, "rb") as f:
if tb in f.read():
achados.append(rel)
except OSError:
pass
return achados
def main():
from huggingface_hub import HfApi
token = os.environ.get("HF_TOKEN")
if not token:
print("ERRO: HF_TOKEN ausente"); sys.exit(1)
api = HfApi(token=token)
repo = "PowerMachine/khtst-rust"
# ---------------- 1) inventário da conta + apaga estados ----------------
print("=== 1) inventário da conta HF (procura estados de treino) ===")
repos = list(api.list_models(author="PowerMachine"))
print(f"repos: {len(repos)}")
total_removidos = 0
for r in repos:
try:
files = api.list_repo_files(repo_id=r.id, repo_type="model")
except Exception as e:
print(f" {r.id}: erro ao listar ({e})"); continue
estados = [f for f in files
if f.endswith(SUFIXOS_ESTADO)
or f.split("/")[-1] in NOMES_ESTADO
or (".meta.json" in f and "checkpoint" in f)]
if estados:
print(f" {r.id}: APAGANDO {len(estados)} estados")
for f in estados:
api.delete_file(path_in_repo=f, repo_id=r.id, repo_type="model")
total_removidos += len(estados)
else:
print(f" {r.id}: {len(files)} arquivos, 0 estados")
print(f"estados removidos no total: {total_removidos}")
# ---------------- 2) varredura local do token ----------------
pasta = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
arquivos = coletar(pasta)
print(f"\n=== 2) varredura local: {len(arquivos)} arquivos ===")
achados = varre_token_em_arquivos(token, arquivos)
if achados:
print(f"ERRO: valor do token encontrado em: {achados}"); sys.exit(1)
print("varredura de token local: limpa")
# ---------------- 3) UM ÚNICO upload_folder ----------------
ignores = (
[f"{d}/**" for d in ARQUIVOS_EXCLUIR_DIRS]
+ [f"{d}" for d in ARQUIVOS_EXCLUIR_DIRS]
+ [f"**/{n}" for n in ARQUIVOS_EXCLUIR_NOME]
+ [f"**/{n}" for n in NOMES_ESTADO]
+ list(SUFIXOS_ESTADO)
+ ["*.so", ".gitignore", "hf_*.py", "hf_*.json", "intros_*.json",
"*.estado.json", "**/*.manifest.json", "**/*.manifest.json.tmp",
"*.tmp"]
)
print(f"\n=== 3) upload_folder ÚNICO ({len(arquivos)} arquivos) ===")
api.upload_folder(
repo_id=repo, repo_type="model", folder_path=pasta,
ignore_patterns=ignores,
delete_patterns=MONOLITOS_VELHOS,
commit_message="v0.10.0: análise/prova/teste das críticas de "
"engenharia Qwen3.8 lote 3 (r-35) — divisão SRP dos monólitos "
"jepa/pensamento/moe/python em 26 submódulos (API estável via "
"re-exports; 'Amdahl de compilação' refutada por experimento "
"controlado, builds frios neutros), checkpoints atômicos SHA-256 "
"puro FIPS 180-4 + fsync + rename + manifesto (CP-1..CP-3; "
"correções da proposta: sem destruir estado anterior, manifesto "
"com barreira, sem bincode/unwrap), TemperaturaInversa T-V3 "
"(fronteira tipada da convexidade N-2; alegação compile-time "
"corrigida), trait CamadaKhtst+CamadaHomeostatica (premissa do "
"controlador refutada no fonte; Vec<Var>; adaptador MoeComPapel "
"bit-a-bit), CLI Typer 75 (fachada aditiva com resume verificado "
"por hash) — 123/123 cargo, 107/107 gates, treino real Wikipédia "
"PT-BR com checkpoints íntegros",
)
print("upload concluído")
# ---------------- 4) verificação pós-upload ----------------
print("\n=== 4) verificação pós-upload ===")
files = api.list_repo_files(repo_id=repo, repo_type="model")
estados = [f for f in files if f.endswith(SUFIXOS_ESTADO)
or f.split("/")[-1] in NOMES_ESTADO
or f.endswith(".manifest.json")]
assert not estados, f"estados publicados: {estados}"
chaves = ["src/checkpoint.rs", "src/tipos.rs", "src/camadas.rs",
"src/jepa/mod.rs", "src/pensamento/mod.rs",
"src/moe_redirecionavel/mod.rs", "src/python/mod.rs",
"src/fnh.rs", "src/verificador.rs",
"scripts/75_cli.py", "scripts/76_telemetria_v010.py",
"scripts/77_suite_v010.py", "scripts/78_publicar_v010.py",
"docs/memorias/r-35-analise-provas-qwen-v010.md",
"resultados/suite_v010_final.json",
"resultados/telemetria_v010.json",
"resultados/fase_a_v010.json", "resultados/fase_b_v010.json",
"resultados/treino_v090.json"]
faltando = [c for c in chaves if c not in files]
assert not faltando, f"faltando: {faltando}"
velhos = [m for m in MONOLITOS_VELHOS if m in files]
assert not velhos, f"monólitos velhos ainda no repo: {velhos}"
print(f"repo: {len(files)} arquivos | 0 estados | módulos-chave OK | "
f"monólitos velhos removidos")
# ---------------- 5) varredura REMOTA do token ----------------
print("\n=== 5) varredura REMOTA do valor do token ===")
with tempfile.TemporaryDirectory() as tmp:
achados_remotos = []
for f in files:
if f.endswith((".py", ".rs", ".md", ".json", ".toml", ".sh", ".cfg",
".txt", ".jsonl")):
try:
p = api.hf_hub_download(repo_id=repo, repo_type="model",
filename=f, local_dir=tmp)
with open(p, "rb") as fh:
if token.encode() in fh.read():
achados_remotos.append(f)
except Exception:
pass
if achados_remotos:
print(f"ERRO: token remoto em: {achados_remotos}"); sys.exit(1)
print("varredura remota: limpa")
# ---------------- 6) apaga estados de treino LOCAIS ----------------
print("\n=== 6) estados de treino locais (checkpoints + manifestos) ===")
apagados = 0
for nome in sorted(NOMES_ESTADO):
for sufixo in ("", ".manifest.json"):
p = os.path.join(pasta, "resultados", nome + sufixo)
if os.path.exists(p):
os.remove(p)
apagados += 1
print(f" apagado: resultados/{nome}{sufixo}")
print(f"locais apagados: {apagados}")
print("\nPUBLICAÇÃO v0.10.0 CONCLUÍDA")
if __name__ == "__main__":
main()