tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

gnome: integra el frente a yupana — perfil escritorio-gnome + reckoning honesto

1. targets.toml: [perfil.escritorio-gnome] (9 raíces de sesión, cola incoming-gnome)
   ⇒ `yupana objetivo` ya lo ve; fluye por targets.py. build-state lo SALTA hasta
   que la cola se cargue (--gnome), así declararlo no reporta raíces fantasma.
2. seed-gnome.py OPTIMIZADO: hornea la triage (sustitución/tooling/opcional/espinazo)
   como HIPÓTESIS con el caveat "el cierre de nixpkgs sobreestima ~5-10×", marca el
   keystone (spidermonkey→gjs→gnome-shell), y deja de mentir con el 465 crudo. El
   espinazo (353) se reporta como COTA ALTA, no como lista de build.

Falta (se activa al autorar): grafo build-state-gnome + flag --gnome ⇒ keystones/
drenar nativos sobre GNOME. Hoy la capa OBJETIVO del yupana-gnome está; la GRAFO no.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

0b333b4c9e0ccfaa5b4d031fb5877dbdcdaaf41d · ruwaq sergio · (3 killa ñawpaq) · tayta 224b15f23 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 2

scripts/seed-gnome.py

3 qillqakuna · +922 −12

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]))},
     )