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 1569Shell 203Rust 109Markdown 993728 Definitions

licencias: leer el LICENSE de verdad cuando GitHub dice «no sé» — 1053 de 1141 (92%)

Último recurso mecánico, `scripts/licencias-texto.sh`: para las 60 recetas donde la API de
GitHub devuelve NOASSERTION (el repo TIENE un LICENSE pero licensee no lo reconoce: texto
retocado, encabezado propio, dos licencias en un fichero), baja el texto y lo clasifica acá.
34 identificadas — 16 MIT, 10 Apache-2.0, 7 BSD-2-Clause, 1 BSD-3-Clause.

SÓLO PERMISIVAS, Y NO ES PEREZA. MIT, Apache-2.0, BSD, ISC, MPL-2.0 y Unlicense se
reconocen por frases inconfundibles y NO tienen variantes -only/-or-later ⇒ reconocer el
texto da el SPDX completo.

La familia GPL se deja al humano A PROPÓSITO, y la razón es sutil: el COPYING de la GPL es
IDÉNTICO tanto si el proyecto es «sólo v3» como «v3 o posterior» — lo que las distingue vive
en las cabeceras de los fuentes. Y encima el propio COPYING incluye, en su apéndice «cómo
aplicar la licencia», la frase «or (at your option) any later version», así que buscarla da
SIEMPRE positivo y parecería evidencia siendo texto de plantilla. Es exactamente la trampa
de la regla del `.a` no-PIC, donde grep contaba reubicaciones de .debug_* y mentía.

Comprobado a mano un caso que daba mala espina: el LICENSE de `conftest` empieza
«Conftest — Write tests against your config files / Copyright (C) 2019 …», que es el formato
típico de una cabecera GPL. Leído entero, dice «Licensed under the Apache License, Version
2.0». La clasificación era correcta; la sospecha, barata.

Hashes verificados sobre las 36 tocadas: idénticos.

Quedan 88, ya sin vía mecánica: los repos donde ni la API ni el texto deciden, la familia
GPL sin desambiguar, y tarballs de sitios propios (gmplib, xiph, sr.ht, codeberg…).

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

487e155f742b7b3396894764a5d58de7c4754c47 · by sergio · (2 months ago) · parent 0225aa4e0 · browse the tree at this commit

Semantic delta

No definition changed: this change is text, documentation or data.

38 files · +153 −0

diff --git a/docs/licencias-texto.tsv b/docs/licencias-texto.tsv
new file mode 100644
index 00000000..012e2551
--- /dev/null
+++ b/docs/licencias-texto.tsv
@@ -0,0 +1,42 @@
+# licencias-texto.tsv — GENERADO por scripts/licencias-texto.sh. No editar a mano.
+# Clasificación por el TEXTO del fichero LICENSE del repo, para los casos en que la API de
+# GitHub dice NOASSERTION. SÓLO permisivas (MIT/Apache/BSD/ISC/MPL/Unlicense): no tienen
+# variantes -only/-or-later, así que reconocer el texto da el SPDX completo. La familia GPL
+# se deja al humano A PROPÓSITO: su COPYING es idéntico en «sólo v3» y «v3 o posterior», y
+# encima incluye la frase «or (at your option) any later version» en su apéndice de plantilla
+# ⇒ buscarla da siempre positivo y parece evidencia sin serlo.
+# Tercera columna: owner/repo:fichero del que se leyó. Total 34
+amass	Apache-2.0	OWASP/Amass:LICENSE
+conftest	Apache-2.0	open-policy-agent/conftest:LICENSE
+dejavu-fonts	MIT	dejavu-fonts/dejavu-fonts:LICENSE
+dsq	Apache-2.0	multiprocessio/dsq:LICENSE.md
+duf	MIT	muesli/duf:LICENSE
+eksctl	Apache-2.0	weaveworks/eksctl:LICENSE
+evcxr	Apache-2.0	google/evcxr:LICENSE
+fq	MIT	wader/fq:LICENSE
+git-lfs	MIT	git-lfs/git-lfs:LICENSE.md
+gitsign	Apache-2.0	sigstore/gitsign:LICENSE
+gobetween	MIT	yyyar/gobetween:LICENSE
+go-migrate	MIT	golang-migrate/migrate:LICENSE
+goose	MIT	pressly/goose:LICENSE
+icu4c	MIT	unicode-org/icu:LICENSE
+itstool	MIT	sabotage-linux/gettext-tiny:LICENSE
+jq	MIT	jqlang/jq:COPYING
+k0sctl	Apache-2.0	k0sproject/k0sctl:LICENSE
+kubeval	Apache-2.0	instrumenta/kubeval:LICENSE
+libevent	BSD-2-Clause	libevent/libevent:LICENSE
+libpsl	MIT	rockdaboot/libpsl:LICENSE
+libsass	MIT	sass/libsass:LICENSE
+libva	MIT	intel/libva:COPYING
+linux-pam	BSD-2-Clause	linux-pam/linux-pam:COPYING
+miller	BSD-2-Clause	johnkerl/miller:LICENSE.txt
+musl-fts	BSD-3-Clause	void-linux/musl-fts:COPYING
+oniguruma	BSD-2-Clause	kkos/oniguruma:COPYING
+p11-kit	BSD-2-Clause	p11-glue/p11-kit:COPYING
+popeye	Apache-2.0	derailed/popeye:LICENSE
+qtkeychain	BSD-2-Clause	frankosterfeld/qtkeychain:COPYING
+richgo	MIT	kyoh86/richgo:LICENSE
+sassc	MIT	sass/sassc:LICENSE
+shadow	BSD-2-Clause	shadow-maint/shadow:COPYING
+utf8proc	MIT	JuliaLang/utf8proc:LICENSE.md
+vulkan-loader	Apache-2.0	KhronosGroup/Vulkan-Loader:LICENSE.txt
diff --git a/recipes/amass.toml b/recipes/amass.toml
index 08b067d0..2a00d913 100644
--- a/recipes/amass.toml
+++ b/recipes/amass.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "amass"
 version = "5.1.1"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/OWASP/Amass"
diff --git a/recipes/conftest.toml b/recipes/conftest.toml
index 44ff16c8..9119c1c5 100644
--- a/recipes/conftest.toml
+++ b/recipes/conftest.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "conftest"
 version = "0.63.0"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/open-policy-agent/conftest"
diff --git a/recipes/dsq.toml b/recipes/dsq.toml
index 810cb4ee..e4d8c83c 100644
--- a/recipes/dsq.toml
+++ b/recipes/dsq.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "dsq"
 version = "0.23.0"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/multiprocessio/dsq"
diff --git a/recipes/duf.toml b/recipes/duf.toml
index ada4226f..53a6ab3b 100644
--- a/recipes/duf.toml
+++ b/recipes/duf.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "duf"
 version = "0.9.1"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/muesli/duf"
diff --git a/recipes/eksctl.toml b/recipes/eksctl.toml
index 4da80f70..f5226ce5 100644
--- a/recipes/eksctl.toml
+++ b/recipes/eksctl.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "eksctl"
 version = "0.226.0"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/weaveworks/eksctl"
diff --git a/recipes/evcxr.toml b/recipes/evcxr.toml
index a02991db..9ac1d6fe 100644
--- a/recipes/evcxr.toml
+++ b/recipes/evcxr.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "evcxr"
 version = "0.21.1"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/google/evcxr"
diff --git a/recipes/fq.toml b/recipes/fq.toml
index 445d5886..f67f754d 100644
--- a/recipes/fq.toml
+++ b/recipes/fq.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "fq"
 version = "0.17.0"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/wader/fq"
diff --git a/recipes/git-lfs.toml b/recipes/git-lfs.toml
index 4b7f53c2..29d4d26e 100644
--- a/recipes/git-lfs.toml
+++ b/recipes/git-lfs.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "git-lfs"
 version = "3.7.1"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/git-lfs/git-lfs"
diff --git a/recipes/gitsign.toml b/recipes/gitsign.toml
index 954de1e9..22ce0dfe 100644
--- a/recipes/gitsign.toml
+++ b/recipes/gitsign.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "gitsign"
 version = "0.16.1"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/sigstore/gitsign"
diff --git a/recipes/go-migrate.toml b/recipes/go-migrate.toml
index c3a54ce2..4549406b 100644
--- a/recipes/go-migrate.toml
+++ b/recipes/go-migrate.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "go-migrate"
 version = "4.19.1"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/golang-migrate/migrate"
diff --git a/recipes/gobetween.toml b/recipes/gobetween.toml
index eb8240a0..65fbbab9 100644
--- a/recipes/gobetween.toml
+++ b/recipes/gobetween.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "gobetween"
 version = "0.8.1"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/yyyar/gobetween"
diff --git a/recipes/goose.toml b/recipes/goose.toml
index c9394477..26757255 100644
--- a/recipes/goose.toml
+++ b/recipes/goose.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "goose"
 version = "3.27.1"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/pressly/goose"
diff --git a/recipes/incoming-cosmic/dejavu-fonts.toml b/recipes/incoming-cosmic/dejavu-fonts.toml
index 5020cd5f..4522df39 100644
--- a/recipes/incoming-cosmic/dejavu-fonts.toml
+++ b/recipes/incoming-cosmic/dejavu-fonts.toml
@@ -2,6 +2,7 @@
 # sin ellas el escritorio renderiza sin texto legible. Data-only: copia los .ttf a /usr/share/fonts.
 name    = "dejavu-fonts"
 version = "2.37"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-fonts-ttf-2.37.tar.bz2"
diff --git a/recipes/incoming-gnome/icu4c.toml b/recipes/incoming-gnome/icu4c.toml
index 622ac029..e1b53aa7 100644
--- a/recipes/incoming-gnome/icu4c.toml
+++ b/recipes/incoming-gnome/icu4c.toml
@@ -3,6 +3,7 @@
 # el tarball descomprime a `icu/source/` → todas las fases entran con `cd source`. musl, shared.
 name    = "icu4c"
 version = "77.1"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/unicode-org/icu/releases/download/release-77-1/icu4c-77_1-src.tgz"
diff --git a/recipes/incoming-gnome/libpsl.toml b/recipes/incoming-gnome/libpsl.toml
index 81475480..5f21ec95 100644
--- a/recipes/incoming-gnome/libpsl.toml
+++ b/recipes/incoming-gnome/libpsl.toml
@@ -16,6 +16,7 @@
 # ISLA DINÁMICA: shared, igual que el resto de la onda 3.
 name    = "libpsl"
 version = "0.21.5"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/rockdaboot/libpsl/releases/download/0.21.5/libpsl-0.21.5.tar.gz"
diff --git a/recipes/incoming-gnome/p11-kit.toml b/recipes/incoming-gnome/p11-kit.toml
index 76314710..b6b3092a 100644
--- a/recipes/incoming-gnome/p11-kit.toml
+++ b/recipes/incoming-gnome/p11-kit.toml
@@ -13,6 +13,7 @@
 # ser es el enlace tardío.
 name    = "p11-kit"
 version = "0.26.4"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/p11-glue/p11-kit/releases/download/0.26.4/p11-kit-0.26.4.tar.xz"
diff --git a/recipes/incoming-kde/dejavu-fonts.toml b/recipes/incoming-kde/dejavu-fonts.toml
index 5020cd5f..4522df39 100644
--- a/recipes/incoming-kde/dejavu-fonts.toml
+++ b/recipes/incoming-kde/dejavu-fonts.toml
@@ -2,6 +2,7 @@
 # sin ellas el escritorio renderiza sin texto legible. Data-only: copia los .ttf a /usr/share/fonts.
 name    = "dejavu-fonts"
 version = "2.37"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-fonts-ttf-2.37.tar.bz2"
diff --git a/recipes/incoming-kde/icu4c.toml b/recipes/incoming-kde/icu4c.toml
index 622ac029..e1b53aa7 100644
--- a/recipes/incoming-kde/icu4c.toml
+++ b/recipes/incoming-kde/icu4c.toml
@@ -3,6 +3,7 @@
 # el tarball descomprime a `icu/source/` → todas las fases entran con `cd source`. musl, shared.
 name    = "icu4c"
 version = "77.1"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/unicode-org/icu/releases/download/release-77-1/icu4c-77_1-src.tgz"
diff --git a/recipes/incoming-kde/libva.toml b/recipes/incoming-kde/libva.toml
index ddc17490..1c9e3e91 100644
--- a/recipes/incoming-kde/libva.toml
+++ b/recipes/incoming-kde/libva.toml
@@ -7,6 +7,7 @@
 # arrastrar más cadena; el driver DRM es el que usa kpipewire).
 name    = "libva"
 version = "2.22.0"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/intel/libva/archive/refs/tags/2.22.0.tar.gz"
diff --git a/recipes/incoming-kde/musl-fts.toml b/recipes/incoming-kde/musl-fts.toml
index db1b1bfa..ee2c2dc7 100644
--- a/recipes/incoming-kde/musl-fts.toml
+++ b/recipes/incoming-kde/musl-fts.toml
@@ -3,6 +3,7 @@
 # (sin autotools): fts.c → libfts.so + libfts.a + fts.h en /usr.
 name    = "musl-fts"
 version = "1.2.7"
+license = "BSD-3-Clause"
 
 [source]
 tarball = "https://github.com/void-linux/musl-fts/archive/refs/tags/v1.2.7.tar.gz"
diff --git a/recipes/incoming-kde/qtkeychain.toml b/recipes/incoming-kde/qtkeychain.toml
index 8d74d546..e40f09ce 100644
--- a/recipes/incoming-kde/qtkeychain.toml
+++ b/recipes/incoming-kde/qtkeychain.toml
@@ -9,6 +9,7 @@
 # OJO: el tag de git es `0.16.0`, SIN prefijo `v` (v0.16.0 da 404).
 name    = "qtkeychain"
 version = "0.16.0"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/frankosterfeld/qtkeychain/archive/refs/tags/0.16.0.tar.gz"
diff --git a/recipes/incoming-kde/vulkan-loader.toml b/recipes/incoming-kde/vulkan-loader.toml
index 9f197b8a..170791ae 100644
--- a/recipes/incoming-kde/vulkan-loader.toml
+++ b/recipes/incoming-kde/vulkan-loader.toml
@@ -5,6 +5,7 @@
 # sellado ⇒ lo apago (no es esencial para libvulkan.so). Python3 sólo si LOADER_CODEGEN (default OFF).
 name    = "vulkan-loader"
 version = "1.4.350.1"
+license = "Apache-2.0"
 
 [source]
 tarball = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.350.1.tar.gz"
diff --git a/recipes/itstool.toml b/recipes/itstool.toml
index cb20cd25..f9631e33 100644
--- a/recipes/itstool.toml
+++ b/recipes/itstool.toml
@@ -4,6 +4,7 @@
 # lo que necesita appstream/libadwaita aquí. Satisface i18n.itstool_join de meson. [source]=carrier.
 name    = "itstool"
 version = "2.0.7"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/sabotage-linux/gettext-tiny/archive/refs/tags/v0.3.2.tar.gz"
diff --git a/recipes/jq.toml b/recipes/jq.toml
index 4e1be5df..c091662d 100644
--- a/recipes/jq.toml
+++ b/recipes/jq.toml
@@ -24,6 +24,7 @@
 
 name    = "jq"
 version = "1.8.1"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/jqlang/jq/releases/download/jq-1.8.1/jq-1.8.1.tar.gz"
diff --git a/recipes/k0sctl.toml b/recipes/k0sctl.toml
index 4a792e56..a29d9cf9 100644
--- a/recipes/k0sctl.toml
+++ b/recipes/k0sctl.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "k0sctl"
 version = "0.31.0"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/k0sproject/k0sctl"
diff --git a/recipes/kubeval.toml b/recipes/kubeval.toml
index ae7ea92f..f1258e55 100644
--- a/recipes/kubeval.toml
+++ b/recipes/kubeval.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "kubeval"
 version = "0.16.1"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/instrumenta/kubeval"
diff --git a/recipes/libevent.toml b/recipes/libevent.toml
index 1e9872d9..a31c2011 100644
--- a/recipes/libevent.toml
+++ b/recipes/libevent.toml
@@ -1,6 +1,7 @@
 # libevent 2.1.12 — lib C base (de-Alpinizada, Etapa G). compiler=zig-cc (migrado de gcc, matar-gcc 2026-07-16), configure-split, estático.
 name    = "libevent"
 version = "2.1.12"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz"
diff --git a/recipes/libsass.toml b/recipes/libsass.toml
index 48f41309..7bba7029 100644
--- a/recipes/libsass.toml
+++ b/recipes/libsass.toml
@@ -2,6 +2,7 @@
 # Makefile propio; BUILD=static + CXX=zig c++. Primer ladrillo C++ del stack GUI.
 name    = "libsass"
 version = "3.6.6"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/sass/libsass/archive/refs/tags/3.6.6.tar.gz"
diff --git a/recipes/linux-pam.toml b/recipes/linux-pam.toml
index 84dde187..720dcc54 100644
--- a/recipes/linux-pam.toml
+++ b/recipes/linux-pam.toml
@@ -4,6 +4,7 @@
 # Build mínimo: sin docs (evita xmlto/docbook), sin NLS, sin examples. autotools split (como expat).
 name    = "linux-pam"
 version = "1.6.1"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/linux-pam/linux-pam/releases/download/v1.6.1/Linux-PAM-1.6.1.tar.xz"
diff --git a/recipes/miller.toml b/recipes/miller.toml
index e2808e74..840aa786 100644
--- a/recipes/miller.toml
+++ b/recipes/miller.toml
@@ -1,6 +1,7 @@
 # miller — receta Go (Etapa G frente Go). main en ./cmd/mlr, binario `mlr`.
 name    = "miller"
 version = "6.18.1"
+license = "BSD-2-Clause"
 
 [source]
 repo   = "https://github.com/johnkerl/miller"
diff --git a/recipes/oniguruma.toml b/recipes/oniguruma.toml
index 84724d51..53d32707 100644
--- a/recipes/oniguruma.toml
+++ b/recipes/oniguruma.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "oniguruma"
 version = "6.9.10"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/kkos/oniguruma/releases/download/v6.9.10/onig-6.9.10.tar.gz"
diff --git a/recipes/popeye.toml b/recipes/popeye.toml
index 49c0c7c4..e67ffd7e 100644
--- a/recipes/popeye.toml
+++ b/recipes/popeye.toml
@@ -4,6 +4,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "popeye"
 version = "0.22.1"
+license = "Apache-2.0"
 
 [source]
 repo   = "https://github.com/derailed/popeye"
diff --git a/recipes/richgo.toml b/recipes/richgo.toml
index e40fe7a1..3937adeb 100644
--- a/recipes/richgo.toml
+++ b/recipes/richgo.toml
@@ -9,6 +9,7 @@
 # - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
 name    = "richgo"
 version = "0.3.12"
+license = "MIT"
 
 [source]
 repo   = "https://github.com/kyoh86/richgo"
diff --git a/recipes/sassc.toml b/recipes/sassc.toml
index 8cfe323d..8da0a55c 100644
--- a/recipes/sassc.toml
+++ b/recipes/sassc.toml
@@ -2,6 +2,7 @@
 # Linkea libsass (C++) ⇒ CC='zig c++' (trae libc++ al link). SASS_LIBSASS_PATH=/usr halla headers+lib.
 name    = "sassc"
 version = "3.6.2"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/sass/sassc/archive/refs/tags/3.6.2.tar.gz"
diff --git a/recipes/shadow.toml b/recipes/shadow.toml
index d4818b80..0f21881e 100644
--- a/recipes/shadow.toml
+++ b/recipes/shadow.toml
@@ -3,6 +3,7 @@
 # sha256 del tarball (el wrapper lo calcula), y adaptar build/install del shell de abuild.
 name    = "shadow"
 version = "4.18.0"
+license = "BSD-2-Clause"
 
 [source]
 tarball = "https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz"
diff --git a/recipes/utf8proc.toml b/recipes/utf8proc.toml
index f5dbe300..e45320f3 100644
--- a/recipes/utf8proc.toml
+++ b/recipes/utf8proc.toml
@@ -3,6 +3,7 @@
 # sha256 del tarball (el wrapper lo calcula), y adaptar build/install del shell de abuild.
 name    = "utf8proc"
 version = "2.11.3"
+license = "MIT"
 
 [source]
 tarball = "https://github.com/JuliaLang/utf8proc/archive/v2.11.3/utf8proc-2.11.3.tar.gz"
diff --git a/scripts/licencias-texto.sh b/scripts/licencias-texto.sh
new file mode 100755
index 00000000..9fb3a733
--- /dev/null
+++ b/scripts/licencias-texto.sh
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+# licencias-texto.sh — último recurso: LEER el fichero LICENSE del repo y clasificarlo por su texto.
+#
+# ── PARA QUÉ, SI YA ESTÁ licencias-detectar.sh ─────────────────────────────────────────────────
+# Aquél pregunta a GitHub «¿qué licencia detectás?» y GitHub a veces contesta NOASSERTION: el repo
+# tiene un LICENSE pero licensee no lo reconoce (texto retocado, dos licencias en un fichero, un
+# encabezado propio…). Quedaron 66 recetas así. Éste baja el TEXTO y lo clasifica acá.
+#
+# ── SÓLO LICENCIAS PERMISIVAS, Y ESO NO ES PEREZA ──────────────────────────────────────────────
+# MIT, Apache-2.0, BSD, ISC y MPL-2.0 se identifican por frases inconfundibles y **no tienen
+# variantes `-only` / `-or-later`** ⇒ reconocer el texto basta para dar el SPDX completo.
+#
+# La familia GPL NO se clasifica acá, a propósito. El fichero COPYING de la GPL es el mismo tanto si
+# el proyecto es «sólo v3» como «v3 o posterior»: lo que distingue una de otra vive en las CABECERAS
+# DE LOS FUENTES, no en el COPYING. Peor todavía: el propio COPYING incluye, en su apéndice «cómo
+# aplicar la licencia», la frase «either version 3 of the License, or (at your option) any later
+# version» — o sea que buscar esa frase en el COPYING da SIEMPRE positivo y **parecería** evidencia
+# siendo puro texto de plantilla. Es la trampa exacta de la regla del `.a` no-PIC, donde `grep`
+# contaba reubicaciones de `.debug_*` y mentía. Las GPL se dejan al humano.
+#
+# Uso:  scripts/licencias-texto.sh      (escribe docs/licencias-texto.tsv)
+set -uo pipefail
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
+SALIDA="${SALIDA:-docs/licencias-texto.tsv}"
+JOBS="${JOBS:-12}"
+command -v gh >/dev/null && gh auth status >/dev/null 2>&1 || { echo "!!  'gh' ausente o sin auth"; exit 1; }
+TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
+
+./scripts/licencias.sh --faltan 2>/dev/null | while IFS= read -r n; do
+  f=$(ls "recipes/$n.toml" 2>/dev/null | head -1)
+  [ -z "$f" ] && f=$(ls recipes/incoming-*/"$n.toml" 2>/dev/null | head -1)
+  [ -z "$f" ] && continue
+  u=$(grep -m1 -E '^[[:space:]]*(tarball|repo)[[:space:]]*=' "$f" 2>/dev/null)
+  case "$u" in *github.com*) ;; *) continue ;; esac
+  slug=$(printf '%s\n' "$u" | sed -E 's#.*github\.com[:/]+([^/"]+)/([^/"]+).*#\1/\2#; s/\.git$//')
+  case "$slug" in */*) printf '%s\t%s\n' "$n" "$slug" ;; esac
+done | sort -u > "$TMP/obj.tsv"
+echo "==> a inspeccionar: $(wc -l < "$TMP/obj.tsv")"
+
+export TMP
+xargs -P "$JOBS" -I{} sh -c '
+  n=$(printf "%s" "{}" | cut -f1); slug=$(printf "%s" "{}" | cut -f2)
+  for fich in LICENSE LICENSE.md LICENSE.txt COPYING LICENCE license; do
+    c=$(gh api "repos/$slug/contents/$fich" --jq ".content" 2>/dev/null) || continue
+    [ -z "$c" ] && continue
+    t=$(printf "%s" "$c" | base64 -d 2>/dev/null | head -60 | tr "[:upper:]" "[:lower:]" | tr -s " \n" "  ")
+    [ -z "$t" ] && continue
+    lic=""
+    case "$t" in
+      *"apache license"*"version 2.0"*) lic="Apache-2.0" ;;
+      *"mozilla public license version 2.0"*) lic="MPL-2.0" ;;
+      *"permission is hereby granted, free of charge"*) lic="MIT" ;;
+      *"permission to use, copy, modify, and/or distribute this software for any purpose"*) lic="ISC" ;;
+      *"neither the name of"*"may be used to endorse or promote"*) lic="BSD-3-Clause" ;;
+      *"redistributions in binary form must reproduce"*) lic="BSD-2-Clause" ;;
+      *"this is free and unencumbered software released into the public domain"*) lic="Unlicense" ;;
+    esac
+    [ -n "$lic" ] && printf "%s\t%s\t%s:%s\n" "$n" "$lic" "$slug" "$fich" >> "$TMP/ok.tsv"
+    break
+  done
+' < "$TMP/obj.tsv"
+
+N=$(wc -l < "$TMP/ok.tsv" 2>/dev/null || echo 0)
+{
+  echo "# licencias-texto.tsv — GENERADO por scripts/licencias-texto.sh. No editar a mano."
+  echo "# Clasificación por el TEXTO del fichero LICENSE del repo, para los casos en que la API de"
+  echo "# GitHub dice NOASSERTION. SÓLO permisivas (MIT/Apache/BSD/ISC/MPL/Unlicense): no tienen"
+  echo "# variantes -only/-or-later, así que reconocer el texto da el SPDX completo. La familia GPL"
+  echo "# se deja al humano A PROPÓSITO: su COPYING es idéntico en «sólo v3» y «v3 o posterior», y"
+  echo "# encima incluye la frase «or (at your option) any later version» en su apéndice de plantilla"
+  echo "# ⇒ buscarla da siempre positivo y parece evidencia sin serlo."
+  echo "# Tercera columna: owner/repo:fichero del que se leyó. Total $N"
+  sort "$TMP/ok.tsv" 2>/dev/null
+} > "$SALIDA"
+echo "==> $N clasificadas por texto → $SALIDA"