#!/usr/bin/env python3 """declarar.py — convierte los servicios de un censo en una SEMILLA de arje (SDD 29 etapa 3). El paso que cierra la mudanza. Copiar un binario no lo levanta al arrancar: hay que DECLARARLO. Esto toma lo que el censo leyó de `/proc` —la invocación real— y emite `seed.card.json`. ── POR QUÉ NO ALCANZA CON `arje-absorb` ──────────────────────────────────────────────────────── `arje-absorb` ya traduce sysvinit/runit/dinit/openrc a una Semilla, y está bien hecho. Pero lee **la declaración del init ajeno**, que es exactamente la que miente: en gioser `rc-status` daba `stopped` para cinco servicios que estaban vivos, y los que NADIE declara —los `no-declarado`, que son el trabajo real— no aparecen en ninguna. Absorber la declaración reproduce el agujero. Esto lee lo VIVO. Los dos se complementan: absorb para lo declarado, esto para lo que corre. ── LAS TRES REGLAS ───────────────────────────────────────────────────────────────────────────── 1. **Un servicio sin `cmdline` legible NO se emite**, y se dice. Una tarjeta que no puede arrancar es peor que una tarjeta ausente: la ausente falla ruidosamente al primer arranque, la rota arranca el sistema y deja el servicio caído sin que nada avise. 2. **El `cwd` se preserva envolviendo**, porque el payload `Native` de arje acepta `exec`/`argv`/ `envp` y **NO `cwd`** (comprobado sobre la semilla real). Un servicio que depende de su directorio —como `puerta-f6e393ff`, que corre con `cwd=/mnt/vvv/tawasuyu/shared/tejido`— arrancaría en `/` y fallaría de un modo difícil de atribuir. Se envuelve en `sh -c 'cd … && exec …'`, que es el idioma que la propia tarjeta de `sshd` ya usa. 3. **Los IDs son DETERMINISTAS**, derivados del nombre. El mismo censo produce la misma semilla byte a byte, así que dos corridas se pueden comparar con `diff` — que es lo que vuelve revisable un fichero generado. ⚠ NO se copia el entorno. El censo no lo lee (trae tokens), así que un servicio que dependa de variables de entorno va a necesitar que alguien las escriba. Se avisa por nombre. Uso: scripts/mudanza/declarar.py --censo censo.toml [--label mi-servidor] --out seed.card.json """ import argparse, hashlib, json, os, shlex, sys, tomllib sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from planear import origen_binario, alternativas, _REPO # noqa: E402 import formatos # noqa: E402 def perfil(censo, label, repo): """Emite un `[perfil.