diff --git a/docs/state/seed-gnome-minima.json b/docs/state/seed-gnome-minima.json index fcadd24d..378c4b1d 100644 --- a/docs/state/seed-gnome-minima.json +++ b/docs/state/seed-gnome-minima.json @@ -1,7 +1,7 @@ { - "schema": "hammer-seed-gnome/1", + "schema": "hammer-seed-gnome/2", "fuente": "nixpkgs metadata (NO se construye con nix — ADR 0004)", - "advertencia": "HIPÓTESIS. Cada frontera es dep-opcional / nix-ismo / hueco real. Autorar a mano.", + "advertencia": "El cierre de metadata SOBREESTIMA ~5-10× la frontera real de hammer (buildInputs de features máximas). Las cubetas son HIPÓTESIS, no verdad: la frontera real emerge autorando TOP-DOWN feature-minimal. NO promover a receta automáticamente.", "raices": [ "mutter", "gnome-shell", @@ -16,10 +16,848 @@ "resumen": { "visitados": 613, "conocida": 155, - "frontera": 465, + "frontera_cruda": 465, "nix_ismo": 61, "lab": 2, - "sin_attr": 95 + "sin_attr": 95, + "sustitucion": 4, + "tooling": 33, + "opcional": 75, + "espinazo": 353 + }, + "palo_largo": [ + "spidermonkey", + "gjs" + ], + "espinazo": [ + "gtk+3", + "json-glib", + "gsettings-desktop-schemas", + "libxcrypt", + "polkit", + "libgudev", + "libglvnd", + "gnutls", + "libselinux", + "libsoup", + "gst-plugins-base", + "libunwind", + "libxrandr", + "fuse", + "gnome-desktop", + "gstreamer", + "libtasn1", + "libxkbfile", + "acl", + "audit", + "avahi", + "gcr", + "iso-codes", + "libidn2", + "libmnl", + "librsvg", + "libseccomp", + "libxt", + "p11-kit", + "shared-mime-info", + "at-spi2-core", + "fftw-single", + "flac", + "keyutils", + "libcap-ng", + "libgweather", + "libopus", + "libplist", + "libsecret", + "libxinerama", + "libxshmfence", + "mesa-gl-headers", + "popt", + "pygobject", + "unzip", + "accountsservice", + "db", + "dbus-python", + "dconf", + "dri-pkgconfig-stub", + "font-util", + "gdbm", + "geocode-glib", + "gjs", + "glib-networking", + "glu", + "gnome-settings-daemon", + "gst-plugins-good", + "jansson", + "jinja2", + "libbpf", + "libedit", + "libical", + "libimobiledevice-glue", + "libjack2", + "libnotify", + "libraw1394", + "libsysprof-capture", + "libunistring", + "libxfont_2", + "libxpm", + "llvm", + "net-tools", + "nettle", + "numactl", + "protobuf", + "pygments", + "serd", + "setuptools", + "umockdev", + "upower", + "v4l-utils", + "xvfb-run", + "SPIRV-LLVM-Translator", + "abseil-cpp", + "adwaita-icon-theme", + "attr", + "boehm-gc", + "bubblewrap", + "clang", + "duktape", + "egl-wayland", + "flit-core", + "fmt", + "gd", + "getopt", + "glslang", + "gpgme", + "iptables", + "kmod", + "lame", + "libao", + "libapparmor", + "libatasmart", + "libbluray", + "libcdio", + "libconfig", + "libdatrie", + "libei", + "libev", + "libfido2", + "libfontenc", + "libgphoto2", + "libimobiledevice", + "libmbim", + "libmicrohttpd", + "libnetfilter_conntrack", + "libnfnetlink", + "libnftnl", + "libpciaccess", + "libpq", + "libproxy", + "libpsl", + "libsepol", + "libstemmer", + "libthai", + "libtirpc", + "liburing", + "libva-minimal", + "libwacom", + "libxcomposite", + "libxdamage", + "libxft", + "libxmu", + "libxxf86vm", + "lttng-ust", + "lv2", + "lzo", + "mobile-broadband-provider-info", + "nghttp3", + "nspr", + "nss", + "opencl-headers", + "ply", + "ppp", + "procps", + "pyyaml", + "scons", + "sord", + "sox", + "soxr", + "speex", + "spirv-tools", + "xkbcomp", + "xxhash", + "CUnit", + "JSON", + "Module-Build", + "Parse-Yapp", + "Pod-Parser", + "SGMLSpm", + "Syntax-Keyword-Try", + "Text-WrapI18N", + "Unicode-LineBreak", + "YAML-Tiny", + "adns", + "alabaster", + "amf-headers", + "argcomplete", + "audiofile", + "autogen", + "babel", + "boost-build", + "bpftools", + "c-ares", + "cargo-c", + "catch2", + "check", + "cjson", + "clang-only", + "cpio", + "cracklib", + "cython", + "dbus-cplusplus", + "dbus-glib", + "defusedxml", + "directx-headers", + "distutils", + "dnsmasq", + "double-conversion", + "eglexternalplatform", + "ell", + "ffado", + "fftw-double", + "gdm", + "glib-testing", + "glibmm", + "gnome-autoar", + "gnome-bluetooth", + "gnome-keyring", + "gpm", + "gptfdisk", + "graphite2", + "gsound", + "gts", + "guile", + "gusb", + "gweather-locations", + "hicolor-icon-theme", + "hwloc", + "ibus", + "imagesize", + "imlib2", + "jam", + "jasper", + "jbigkit", + "kexec-tools", + "kpsewhich", + "ldns", + "lerc", + "libaio", + "libargon2", + "libavc1394", + "libavif", + "libb2", + "libblake3", + "libblockdev", + "libbsd", + "libbytesize", + "libcbor", + "libcddb", + "libcdio-paranoia", + "libclc", + "libdaemon", + "libdbusmenu-gtk3", + "libdecor", + "libdeflate", + "libdex", + "libeatmydata", + "libebur128", + "libelf", + "libexif", + "libfreeaptx", + "libfyaml", + "libglycin", + "libgnomekbd", + "libid3tag", + "libiec61883", + "libieee1284", + "libipt", + "libmd", + "libmng", + "libmtp", + "libmysofa", + "libnma", + "libopenmpt", + "libpanel", + "libpaper", + "libpfm", + "libphonenumber", + "libpipeline", + "libpwquality", + "libqmi", + "libqrtr-glib", + "librest", + "librist", + "libsamplerate", + "libsigc++", + "libssh", + "libstartup-notification", + "libsystemtap", + "libtatsu", + "liburcu", + "libusbmuxd", + "libvmaf", + "libxaw", + "libxfont_1", + "libxklavier", + "libxml++", + "libxres", + "libxscrnsaver", + "libyuv", + "lilv", + "lksctp-tools", + "lmdb", + "lzip", + "malcontent", + "markdown", + "mbedtls", + "md4c", + "mpdecimal", + "mutest", + "mutter", + "netpbm", + "newt", + "nftables", + "nghttp2", + "ngtcp2", + "nv-codec-headers", + "ocl-icd", + "onetbb", + "openapv", + "openfec", + "openjpeg", + "opensp", + "pcsclite", + "plymouth", + "portaudio", + "protobuf-c", + "pth", + "publicsuffix-list", + "pybind11", + "pycparser", + "pytest-xdist", + "python-dbusmock", + "requests", + "rhash", + "roman-numerals", + "rpcsvc-proto", + "rust-bindgen", + "rust-cbindgen", + "sandbox-dbus-launch", + "setxkbmap", + "shaderc", + "slang", + "snowballstemmer", + "source-highlight", + "spandsp", + "spdlog", + "sphinxygen", + "spidermonkey", + "spirv-headers", + "sqlite-connector-odbc", + "sratom", + "sysprof", + "systemtap", + "tinysparql", + "typing-extensions", + "typogrify", + "udisks", + "uthash", + "volume_key", + "w3m", + "webrtc-audio-processing", + "xapian", + "xdg-desktop-portal", + "xorg-server", + "xvfb", + "xvidcore", + "xwayland", + "xxd", + "zip", + "zix" + ], + "triage": { + "sustitucion": [ + "libpulseaudio", + "systemd", + "systemd-minimal", + "systemd-minimal-libs" + ], + "tooling": [ + "autoconf", + "autoconf-archive", + "automake", + "bash-completion", + "byacc", + "cmocka", + "dejagnu", + "desktop-file-utils", + "docbook-sgml", + "docbook5", + "docutils", + "doxygen", + "expect", + "gdb", + "gengetopt", + "gi-docgen", + "graphviz", + "groff", + "gtest", + "help2man", + "man-db", + "nasm", + "po4a", + "prune-libtool-files", + "ragel", + "sphinx", + "swig", + "texinfo", + "vala", + "valgrind", + "validate-pkg-config", + "xmlto", + "yasm" + ], + "opcional": [ + "argyllcms", + "bluez", + "bluez-headers", + "colord", + "cryptsetup", + "cups", + "cyrus-sasl", + "dav1d", + "evolution-data-server", + "fdk-aac", + "ffmpeg-headless", + "flatpak", + "geoclue", + "gnome-clocks", + "gnome-online-accounts", + "gst-plugins-bad", + "gvfs", + "krb5", + "ldacbt", + "ldb", + "libaom", + "libass", + "libcamera", + "libiscsi", + "liblc3", + "libmad", + "libmpg123", + "libndctl", + "libnfs", + "libnvme", + "libtheora", + "libtpms", + "libvpx", + "lua", + "lvm2", + "mariadb-connector-c", + "mariadb-connector-odbc", + "mpg123", + "net-snmp", + "openjdk", + "openldap", + "opusfile", + "ostree", + "poppler-glib", + "psqlodbc", + "roc-toolkit", + "ruby", + "samba", + "sane-backends", + "sbc", + "sphinxcontrib-applehelp", + "sphinxcontrib-devhelp", + "sphinxcontrib-htmlhelp", + "sphinxcontrib-jsmath", + "sphinxcontrib-qthelp", + "sphinxcontrib-serializinghtml", + "sphinxcontrib-websupport", + "srt", + "svt-av1", + "swtpm", + "talloc", + "tcl", + "tdb", + "tevent", + "tpm2-tss", + "unbound", + "unixodbc", + "vid.stab", + "vorbis-tools", + "wavpack", + "webkitgtk", + "x264", + "x265", + "zimg", + "zvbi" + ], + "espinazo": [ + "CUnit", + "JSON", + "Module-Build", + "Parse-Yapp", + "Pod-Parser", + "SGMLSpm", + "SPIRV-LLVM-Translator", + "Syntax-Keyword-Try", + "Text-WrapI18N", + "Unicode-LineBreak", + "YAML-Tiny", + "abseil-cpp", + "accountsservice", + "acl", + "adns", + "adwaita-icon-theme", + "alabaster", + "amf-headers", + "argcomplete", + "at-spi2-core", + "attr", + "audiofile", + "audit", + "autogen", + "avahi", + "babel", + "boehm-gc", + "boost-build", + "bpftools", + "bubblewrap", + "c-ares", + "cargo-c", + "catch2", + "check", + "cjson", + "clang", + "clang-only", + "cpio", + "cracklib", + "cython", + "db", + "dbus-cplusplus", + "dbus-glib", + "dbus-python", + "dconf", + "defusedxml", + "directx-headers", + "distutils", + "dnsmasq", + "double-conversion", + "dri-pkgconfig-stub", + "duktape", + "egl-wayland", + "eglexternalplatform", + "ell", + "ffado", + "fftw-double", + "fftw-single", + "flac", + "flit-core", + "fmt", + "font-util", + "fuse", + "gcr", + "gd", + "gdbm", + "gdm", + "geocode-glib", + "getopt", + "gjs", + "glib-networking", + "glib-testing", + "glibmm", + "glslang", + "glu", + "gnome-autoar", + "gnome-bluetooth", + "gnome-desktop", + "gnome-keyring", + "gnome-settings-daemon", + "gnutls", + "gpgme", + "gpm", + "gptfdisk", + "graphite2", + "gsettings-desktop-schemas", + "gsound", + "gst-plugins-base", + "gst-plugins-good", + "gstreamer", + "gtk+3", + "gts", + "guile", + "gusb", + "gweather-locations", + "hicolor-icon-theme", + "hwloc", + "ibus", + "imagesize", + "imlib2", + "iptables", + "iso-codes", + "jam", + "jansson", + "jasper", + "jbigkit", + "jinja2", + "json-glib", + "kexec-tools", + "keyutils", + "kmod", + "kpsewhich", + "lame", + "ldns", + "lerc", + "libaio", + "libao", + "libapparmor", + "libargon2", + "libatasmart", + "libavc1394", + "libavif", + "libb2", + "libblake3", + "libblockdev", + "libbluray", + "libbpf", + "libbsd", + "libbytesize", + "libcap-ng", + "libcbor", + "libcddb", + "libcdio", + "libcdio-paranoia", + "libclc", + "libconfig", + "libdaemon", + "libdatrie", + "libdbusmenu-gtk3", + "libdecor", + "libdeflate", + "libdex", + "libeatmydata", + "libebur128", + "libedit", + "libei", + "libelf", + "libev", + "libexif", + "libfido2", + "libfontenc", + "libfreeaptx", + "libfyaml", + "libglvnd", + "libglycin", + "libgnomekbd", + "libgphoto2", + "libgudev", + "libgweather", + "libical", + "libid3tag", + "libidn2", + "libiec61883", + "libieee1284", + "libimobiledevice", + "libimobiledevice-glue", + "libipt", + "libjack2", + "libmbim", + "libmd", + "libmicrohttpd", + "libmng", + "libmnl", + "libmtp", + "libmysofa", + "libnetfilter_conntrack", + "libnfnetlink", + "libnftnl", + "libnma", + "libnotify", + "libopenmpt", + "libopus", + "libpanel", + "libpaper", + "libpciaccess", + "libpfm", + "libphonenumber", + "libpipeline", + "libplist", + "libpq", + "libproxy", + "libpsl", + "libpwquality", + "libqmi", + "libqrtr-glib", + "libraw1394", + "librest", + "librist", + "librsvg", + "libsamplerate", + "libseccomp", + "libsecret", + "libselinux", + "libsepol", + "libsigc++", + "libsoup", + "libssh", + "libstartup-notification", + "libstemmer", + "libsysprof-capture", + "libsystemtap", + "libtasn1", + "libtatsu", + "libthai", + "libtirpc", + "libunistring", + "libunwind", + "liburcu", + "liburing", + "libusbmuxd", + "libva-minimal", + "libvmaf", + "libwacom", + "libxaw", + "libxcomposite", + "libxcrypt", + "libxdamage", + "libxfont_1", + "libxfont_2", + "libxft", + "libxinerama", + "libxkbfile", + "libxklavier", + "libxml++", + "libxmu", + "libxpm", + "libxrandr", + "libxres", + "libxscrnsaver", + "libxshmfence", + "libxt", + "libxxf86vm", + "libyuv", + "lilv", + "lksctp-tools", + "llvm", + "lmdb", + "lttng-ust", + "lv2", + "lzip", + "lzo", + "malcontent", + "markdown", + "mbedtls", + "md4c", + "mesa-gl-headers", + "mobile-broadband-provider-info", + "mpdecimal", + "mutest", + "mutter", + "net-tools", + "netpbm", + "nettle", + "newt", + "nftables", + "nghttp2", + "nghttp3", + "ngtcp2", + "nspr", + "nss", + "numactl", + "nv-codec-headers", + "ocl-icd", + "onetbb", + "openapv", + "opencl-headers", + "openfec", + "openjpeg", + "opensp", + "p11-kit", + "pcsclite", + "ply", + "plymouth", + "polkit", + "popt", + "portaudio", + "ppp", + "procps", + "protobuf", + "protobuf-c", + "pth", + "publicsuffix-list", + "pybind11", + "pycparser", + "pygments", + "pygobject", + "pytest-xdist", + "python-dbusmock", + "pyyaml", + "requests", + "rhash", + "roman-numerals", + "rpcsvc-proto", + "rust-bindgen", + "rust-cbindgen", + "sandbox-dbus-launch", + "scons", + "serd", + "setuptools", + "setxkbmap", + "shaderc", + "shared-mime-info", + "slang", + "snowballstemmer", + "sord", + "source-highlight", + "sox", + "soxr", + "spandsp", + "spdlog", + "speex", + "sphinxygen", + "spidermonkey", + "spirv-headers", + "spirv-tools", + "sqlite-connector-odbc", + "sratom", + "sysprof", + "systemtap", + "tinysparql", + "typing-extensions", + "typogrify", + "udisks", + "umockdev", + "unzip", + "upower", + "uthash", + "v4l-utils", + "volume_key", + "w3m", + "webrtc-audio-processing", + "xapian", + "xdg-desktop-portal", + "xkbcomp", + "xorg-server", + "xvfb", + "xvfb-run", + "xvidcore", + "xwayland", + "xxd", + "xxhash", + "zip", + "zix" + ] }, "conocida": [ "alsa-lib", diff --git a/docs/state/targets.toml b/docs/state/targets.toml index 8e906ba6..8f7217ed 100644 --- a/docs/state/targets.toml +++ b/docs/state/targets.toml @@ -64,3 +64,17 @@ paquetes = [ # en un estilo genérico. Ver docs/state/frontera-triaje.toml para el porqué de cada uno. "shared-mime-info", "xwayland", "polkit-qt-1", "qqc2-breeze-style", ] + +[perfil.escritorio-gnome] +descripcion = "escritorio GNOME (Wayland-nativo) desde fuente — 3er escritorio, X11 al tacho" +cola = "incoming-gnome" +# Raíces de una sesión GNOME que bootea a un shell usable. El resto es CLAUSURA. Hoy son HUECOS +# (cero recetas en incoming-gnome): build-state SALTA este perfil hasta que su cola se cargue +# (--gnome), así que declararlo NO reporta raíces fantasma — sólo lo hace un objetivo de primera +# clase que el sistema conoce. La frontera de autoría se descubre con `seed-gnome.py` (bootstrap por +# metadata mientras no haya recetas); OJO: ese cierre SOBREESTIMA ~5-10× (ver docs/state/seed-gnome.json +# y la memoria frente-gnome). El palo largo / keystone es spidermonkey(mozjs) → gjs → gnome-shell. +paquetes = [ + "mutter", "gnome-shell", "gjs", "gnome-session", "gnome-settings-daemon", + "gsettings-desktop-schemas", "gnome-desktop", "gdm", "xdg-desktop-portal-gnome", +] diff --git a/scripts/seed-gnome.py b/scripts/seed-gnome.py index 37565f9e..1cab3ff6 100644 --- a/scripts/seed-gnome.py +++ b/scripts/seed-gnome.py @@ -32,6 +32,45 @@ MINIMA = [ # lo que una sesión GNOME necesita para BOOTEAR a un shell usable ( "gsettings-desktop-schemas", "gnome-desktop", "gdm", "xdg-desktop-portal-gnome", ] +# ── LA OPTIMIZACIÓN (el "yupana de gnome", no un sembrador crudo). El cierre de metadata de nixpkgs +# SOBREESTIMA ~5-10× la frontera real de hammer, porque declara buildInputs de features MÁXIMAS. Estas +# tablas son HIPÓTESIS de triage (NO verdad — la verdad emerge autorando feature-minimal), para que el +# reporte no mienta con "465 recetas". Cada una vuelve legible por qué un candidato probablemente NO es +# hueco. Clasificar a mano al autorar; mover entre cubetas es esperable. +SUSTITUCION = { # hammer YA tiene equivalente → mapeo, no hueco + "systemd", "systemd-minimal", "systemd-minimal-libs", # → elogind + "libpulseaudio", # → pipewire (libpulse compat) + "networkmanager", # → iwd / systemd-networkd (a elegir) +} +TOOLING = { # generadores de docs / build-glue: el lab los provee o se deshabilitan + "vala", "gi-docgen", "gtk-doc", "docutils", "doxygen", "texinfo", "autoconf", "automake", + "autoconf-archive", "xmlto", "nasm", "yasm", "cmocka", "gtest", "bash-completion", + "desktop-file-utils", "gettext", "itstool", "sassc", "meson", "ninja", "help2man", "gperf", + "appstream", "appstream-glib", "asciidoc", "docbook-xsl", "docbook-xml", "docbook-sgml", + "docbook5", "perl", "python3", "gobject-introspection", "sphinx", "graphviz", "groff", "swig", + "dejagnu", "expect", "valgrind", "gdb", "man-db", "po4a", "ragel", "byacc", "gengetopt", + "validate-pkg-config", "prune-libtool-files", +} +# subárboles de features/apps que una sesión mínima NO necesita (defer): media, impresión, red, +# almacenamiento, TPM, escáner, runtimes de scripting arrastrados por deps opcionales. +OPCIONAL_PREF = ( + "ffmpeg", "gst-plugins-bad", "gst-plugins-ugly", "gst-libav", "x264", "x265", "svt-av1", + "dav1d", "libaom", "libvpx", "fdk-aac", "libmad", "libmpg123", "mpg123", "opusfile", "wavpack", + "libtheora", "vorbis", "zimg", "vid.stab", "libass", "srt", "zvbi", "sbc", "ldacbt", "liblc3", + "samba", "talloc", "tevent", "tdb", "ldb", "libnfs", "libiscsi", "cyrus-sasl", "net-snmp", + "unbound", "cups", "sane", "colord", "argyllcms", "bluez", "freerdp", "evolution", + "gnome-online-accounts", "gnome-remote-desktop", "webkitgtk", "gnome-clocks", "flatpak", + "ostree", "gvfs", "openjdk", "ruby", "lua", "tcl", "tpm2", "swtpm", "libtpms", "cryptsetup", + "lvm2", "libnvme", "libndctl", "mariadb", "psqlodbc", "unixodbc", "openldap", "krb5", + "sphinxcontrib", "geoclue", "libcamera", "roc-toolkit", "exiv2", "poppler", +) + +def _cubeta(dep): + if dep in SUSTITUCION: return "sustitucion" + if dep in TOOLING: return "tooling" + if any(t in dep for t in OPCIONAL_PREF): return "opcional" + return "espinazo" + def main(): recs = sg.recetas() raices = MINIMA if (len(sys.argv) > 1 and sys.argv[1] == "--minima") else RAICES @@ -73,18 +112,37 @@ def main(): print(f" provisto por el lab: {len(lab)}") print(f" sin attr en nixpkgs: {len(sin_attr)}" + (f" ({' '.join(sin_attr[:8])}…)" if sin_attr else "")) - print(f"\n== frontera por demanda (cuántas recetas la piden) — top 40:") - for dep, quienes in sorted(demanda.items(), key=lambda kv: (-len(kv[1]), kv[0]))[:40]: - print(f" {len(quienes):3}× {dep:30} ← {' '.join(sorted(set(quienes))[:4])}" - + (" …" if len(set(quienes)) > 4 else "")) + # ── TRIAGE (hipótesis): parte la frontera cruda en cubetas para no mentir con el conteo bruto. + cubetas = {"sustitucion": [], "tooling": [], "opcional": [], "espinazo": []} + for d in frontera: + cubetas[_cubeta(d)].append(d) + espinazo = sorted(cubetas["espinazo"], key=lambda k: (-len(demanda.get(k, [])), k)) + # keystone / palo largo: gjs bloquea gnome-shell, y gjs cuelga de spidermonkey(mozjs). + palo_largo = [d for d in ("spidermonkey", "gjs", "mozjs") if d in frontera] + + print(f"\n== TRIAGE de la frontera cruda (HIPÓTESIS — el cierre de nixpkgs sobreestima ~5-10×):") + print(f" sustitución (systemd→elogind…): {len(cubetas['sustitucion'])}") + print(f" tooling/docs (lab o disable): {len(cubetas['tooling'])}") + print(f" opcional (media/print/red/…): {len(cubetas['opcional'])}") + print(f" ⇒ ESPINAZO candidato a autorar: {len(espinazo)} (SIGUE siendo cota ALTA)") + print(f" ⚠ palo largo / keystone: {' → '.join(palo_largo) or '—'} (bloquea gnome-shell)") + print(f"\n== espinazo por demanda — top 30 (hipótesis, clasificar al autorar):") + for d in espinazo[:30]: + print(f" {len(demanda.get(d, [])):3}× {d}") doc = dict( - schema="hammer-seed-gnome/1", + schema="hammer-seed-gnome/2", fuente="nixpkgs metadata (NO se construye con nix — ADR 0004)", - advertencia="HIPÓTESIS. Cada frontera es dep-opcional / nix-ismo / hueco real. Autorar a mano.", + advertencia=("El cierre de metadata SOBREESTIMA ~5-10× la frontera real de hammer (buildInputs " + "de features máximas). Las cubetas son HIPÓTESIS, no verdad: la frontera real " + "emerge autorando TOP-DOWN feature-minimal. NO promover a receta automáticamente."), raices=raices, - resumen=dict(visitados=len(grafo), conocida=len(conocidas), frontera=len(frontera), - nix_ismo=len(nixismos), lab=len(lab), sin_attr=len(sin_attr)), + resumen=dict(visitados=len(grafo), conocida=len(conocidas), frontera_cruda=len(frontera), + nix_ismo=len(nixismos), lab=len(lab), sin_attr=len(sin_attr), + sustitucion=len(cubetas["sustitucion"]), tooling=len(cubetas["tooling"]), + opcional=len(cubetas["opcional"]), espinazo=len(espinazo)), + palo_largo=palo_largo, + espinazo=espinazo, triage=cubetas, conocida=conocidas, frontera=frontera, nix_ismo=nixismos, lab=lab, sin_attr=sin_attr, demanda={d: sorted(set(q)) for d, q in sorted(demanda.items(), key=lambda kv:(-len(kv[1]),kv[0]))}, )