aboutsummaryrefslogtreecommitdiff
path: root/blog
diff options
context:
space:
mode:
Diffstat (limited to 'blog')
-rwxr-xr-xblog/build.sh3
-rw-r--r--blog/content/2004/01/preservaciones.gmi10
-rw-r--r--blog/content/2004/03/momento-retro.gmi4
-rw-r--r--blog/content/2006/12/ratas-del-aire.gmi49
-rw-r--r--blog/content/2007/07/everything-is-connected.gmi15
-rw-r--r--blog/content/2008/02/gentlemen-you-can-t-fight-in-here-this-is-the-war-room.gmi25
-rw-r--r--blog/content/2010/03/gatos-azucarados.gmi22
-rw-r--r--blog/content/2011/01/django-o-la-fabrica-de-churros.gmi4
-rw-r--r--blog/content/2011/10/apuntes-sobre-dart.gmi8
-rw-r--r--blog/content/2012/06/desarrollo-web-como-dios-manda.gmi4
-rw-r--r--blog/content/2012/11/que-es-el-rpc.gmi2
-rw-r--r--blog/content/2013/09/recopilatorios-de-grandes-exitos.gmi4
-rw-r--r--blog/content/2014/01/integracion-apis-y-no-me-toques-los-bezos.gmi29
-rw-r--r--blog/content/2020/07/isos-y-usbs.gmi2
-rw-r--r--blog/content/2021/03/los-gemelos-golpean-dos-veces.gmi4
-rw-r--r--blog/content/2022/07/la-caja-de-herramientas.gmi2
-rw-r--r--blog/content/2022/11/origenes.gmi2
-rw-r--r--blog/content/2024/01/ahi-vamos-de-nuevo.gmi2
-rw-r--r--blog/content/2024/07/ovejas.gmi2
-rw-r--r--blog/content/2024/08/tu-transportas.gmi4
-rw-r--r--blog/content/2024/11/la-x-no-marca-el-lugar.gmi2
-rw-r--r--blog/content/2024/11/otros-relojes-apocalipticos.gmi2
-rw-r--r--blog/content/2025/05/jugando-al-monopoly.gmi2
-rw-r--r--blog/content/2025/05/la-web.gmi3
-rw-r--r--blog/content/2026/03/me-gusta-el-futbol.gmi25
-rw-r--r--blog/content/2026/03/notas.gmi32
-rw-r--r--blog/content/2026/03/peligros-de-bolsillo.gmi45
-rw-r--r--blog/content/2026/03/this-was-supposed-to-be-the-future.gmi27
-rw-r--r--blog/content/2026/04/breve-e-incompleta-historia-del-desarrollo-web.gmi93
-rw-r--r--blog/content/2026/04/el-enemigo-en-casa.gmi35
-rw-r--r--blog/content/gemini.gmi30
-rw-r--r--blog/content/laspelis/1041.gmi5
-rw-r--r--blog/content/laspelis/1061.gmi4
-rw-r--r--blog/content/notas/comprar-bajo-en-sodio.gmi176
-rw-r--r--blog/content/notas/ficcion/conmutatividad.gmi73
-rw-r--r--blog/content/notas/ficcion/cuentos-del-triangulo-verde.gmi133
-rw-r--r--blog/content/notas/ficcion/el-principe.gmi65
-rw-r--r--blog/content/notas/ficcion/en-los-mejores-cines.gmi57
-rw-r--r--blog/content/notas/ficcion/invoco-al-diablo.gmi121
-rw-r--r--blog/content/notas/ficcion/lucifer-martinez.gmi77
-rw-r--r--blog/content/notas/ficcion/maldito-clip.gmi73
-rw-r--r--blog/content/notas/ficcion/mariano-el-programador.gmi53
-rw-r--r--blog/content/notas/ficcion/un-paseo-por-el-rio.gmi37
-rw-r--r--blog/content/notas/index.gmi31
-rw-r--r--blog/content/notas/tecnologia/mama-quiero-ser-programador.gmi115
-rw-r--r--blog/content/notas/tecnologia/problemas.gmi63
-rw-r--r--blog/content/notas/tecnologia/quiero-instalar-linux.gmi271
-rw-r--r--blog/content/notas/tele/el-estado-de-esta-nacion-grabando.gmi60
-rw-r--r--blog/content/notas/tele/teles.gmi75
-rw-r--r--blog/content/notes/cliffs/governable-spaces.gmi115
-rw-r--r--blog/content/notes/cliffs/mythical-man-month.gmi19
-rw-r--r--blog/content/notes/cliffs/peopleware.gmi272
-rw-r--r--blog/content/notes/cliffs/the-tyranny-of-structurelessness.gmi98
-rw-r--r--blog/content/notes/greek-task-list.gmi83
-rw-r--r--blog/content/notes/index.gmi44
-rw-r--r--blog/content/notes/interesting-articles.gmi195
-rw-r--r--blog/content/notes/tech/about-apis.gmi26
-rw-r--r--blog/content/notes/tech/about-django.gmi115
-rw-r--r--blog/content/notes/tech/about-relational-databases.gmi27
-rw-r--r--blog/content/notes/tech/about-web-development.gmi5
-rw-r--r--blog/content/notes/tech/containers-might-not-be-the-right-answer.gmi100
-rw-r--r--blog/content/notes/tech/crud-is-an-important-unsolved-problem.gmi78
-rw-r--r--blog/content/notes/tech/document-formats.gmi97
-rw-r--r--blog/content/notes/tech/gadgets/about-headphones.gmi152
-rw-r--r--blog/content/notes/tech/gadgets/pocket-computers.gmi38
-rw-r--r--blog/content/notes/tech/gadgets/x12.gmi47
-rw-r--r--blog/content/notes/tech/git-advice.gmi21
-rw-r--r--blog/content/notes/tech/github-annoyances.gmi7
-rw-r--r--blog/content/notes/tech/internet-communication-channels.gmi131
-rw-r--r--blog/content/notes/tech/ledger.gmi58
-rw-r--r--blog/content/notes/tech/migadu.gmi100
-rw-r--r--blog/content/notes/tech/misc-linux-stuff.gmi116
-rw-r--r--blog/content/notes/tech/misc-python-stuff.gmi62
-rw-r--r--blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi61
-rw-r--r--blog/content/notes/tech/prolog-vs-sql.gmi114
-rw-r--r--blog/content/notes/tech/python-modules-primer.gmi229
-rw-r--r--blog/content/notes/tech/ripping.gmi67
-rw-r--r--blog/content/notes/tech/running-commands-in-linux.gmi259
-rw-r--r--blog/content/notes/tech/so-you-want-to-play-with-functional-programming.gmi201
-rw-r--r--blog/content/notes/tech/ssh-for-beginners.gmi88
-rw-r--r--blog/content/notes/tech/take-the-less-traveled-road.gmi29
-rw-r--r--blog/content/notes/tech/the-tragedy-of-the-geeks.gmi65
-rwxr-xr-xblog/post-receive10
83 files changed, 4957 insertions, 154 deletions
diff --git a/blog/build.sh b/blog/build.sh
index 27371f6c..97b4f0cf 100755
--- a/blog/build.sh
+++ b/blog/build.sh
@@ -20,6 +20,9 @@ cat >index.gmi <<EOF
Envíame email a alex arroba corcoles punto net.
+=> notas/ Notas
+=> notes/ Notes
+
EOF
find . -path './2???/??/*.gmi' -type f -print0 | coppewebite-indexer . >>index.gmi
diff --git a/blog/content/2004/01/preservaciones.gmi b/blog/content/2004/01/preservaciones.gmi
index 15bc60fe..6b5cddaf 100644
--- a/blog/content/2004/01/preservaciones.gmi
+++ b/blog/content/2004/01/preservaciones.gmi
@@ -1,11 +1,7 @@
# 2004-01-24 Preservaciones
-En Slashdot [1] enlazan a una guía para mantener en buen estado de conservación CDs y DVDs [2] del programa del NIST para la preservación digital [3]. Hay un resumen para los impacientes [4].
+=> https://www.nist.gov/publications/care-and-handling-cds-and-dvds-guide-librarians-and-archivists En Slashdot enlazan a una guía para mantener en buen estado de conservación CDs y DVDs del programa del NIST para la preservación digital.
-El NIST mola. Esto me recuerda su fantástico Diccionario de Algoritmos y Estructuras de Datos [5], esencial para programadores.
+El NIST mola. Esto me recuerda su fantástico Diccionario de Algoritmos y Estructuras de Datos, esencial para programadores:
-=> http://slashdot.org [1] Slashdot
-=> http://www.itl.nist.gov/div895/carefordisc/CDandDVDCareandHandlingGuide.pdf [2] una guía para mantener en buen estado de conservación CDs y DVDs
-=> http://www.itl.nist.gov/div895/carefordisc/index.html [3] programa del NIST para la preservación digital
-=> http://www.itl.nist.gov/div895/carefordisc/onepage.pdf [4] resumen para los impacientes
-=> http://www.nist.gov/dads/ [5] Diccionario de Algoritmos y Estructuras de Datos
+=> http://www.nist.gov/dads/
diff --git a/blog/content/2004/03/momento-retro.gmi b/blog/content/2004/03/momento-retro.gmi
index ee351879..09ad2687 100644
--- a/blog/content/2004/03/momento-retro.gmi
+++ b/blog/content/2004/03/momento-retro.gmi
@@ -1,5 +1,3 @@
# 2004-03-24 Momento retro
-Momento retro [1]
-
-=> http://www.thinkgeek.com/computing/drives/6908/?cpg=wnrss [1] Momento retro
+=> https://web.archive.org/web/20050308131313/http://www.thinkgeek.com/computing/drives/6908/?cpg=wnrss Momento retro
diff --git a/blog/content/2006/12/ratas-del-aire.gmi b/blog/content/2006/12/ratas-del-aire.gmi
index 0caa035b..3a981247 100644
--- a/blog/content/2006/12/ratas-del-aire.gmi
+++ b/blog/content/2006/12/ratas-del-aire.gmi
@@ -1,50 +1,13 @@
# 2006-12-25 Ratas del aire
-Sólo hay una manera en la que un británico de pura cepa puede responder al titular de "se contrata francotirados para eliminar las palomas de Kingston". Llenar la página de la noticia [1] de comentarios surrealistas. Algunos extractos:
+=> https://www.surreycomet.co.uk/news/1039169.marksman_called_in_to_kill_kingstons_pigeons/ Sólo hay una manera en la que un británico de pura cepa puede responder al titular de "se contrata francotirados para eliminar las palomas de Kingston". Llenar la página de la noticia de comentarios surrealistas. Algunos extractos:
-=> http://www.surreycomet.co.uk/pigeoncomments/display.var.1039169.0.marksman_called_in_to_kill_kingstons_pigeons.php [1] la página de la noticia
+> What a lot of fuss over nothing. Everyone knows pigeons can't be killed, they are immortal and immune to bullets. Where I come from we worship the pigeon deity and never look them in the eye as this can turn a man to stone.
->
->
->
-> What a lot of fuss over nothing. Everyone knows pigeons can't be killed,
-> they are immortal and immune to bullets. Where I come from we worship the
-> pigeon deity and never look them in the eye as this can turn a man to
-> stone.
->
->
+> I'm horrified at the very idea anyone might want to harm these gentle creatures. I myself was raised by pigeons after being abandoned in Trafalgar Square as a young nipper. Therefore I know how noble and generous a species they really are. If anyone were to kill a pigeon in this way, it would be as though they are slaughtering one of my own family. It's murder, I say!
->
->
->
-> I'm horrified at the very idea anyone might want to harm these gentle
-> creatures. I myself was raised by pigeons after being abandoned in
-> Trafalgar Square as a young nipper. Therefore I know how noble and
-> generous a species they really are. If anyone were to kill a pigeon in
-> this way, it would be as though they are slaughtering one of my own
-> family. It's murder, I say!
->
->
->
> [...]
->
->
->
-> I know what you mean, reader. I was raised by yaks but I'm sure the
-> experience was similar. How about a council worker cull instead.
->
->
->
->
->
-> My elder sister was held captive for nine days by a flock of rock pigeons
-> on a small island near Malta in 1979 - it may have been Gozo but I'm not
-> too sure. (Sorry about that.) As you might gather she suffers from
-> nightmares and flashbacks but she has also developed a loathing of millet
-> seeds for some strange reason. She is in full support of the cull and, in
-> actual fact, she has already applied for the job and fully intends to
-> carry out her duties as soon as possible - whether she gets the job or
-> not. Be careful around town folks - she's not a good shot.
->
->
+> I know what you mean, reader. I was raised by yaks but I'm sure the experience was similar. How about a council worker cull instead.
+
+> My elder sister was held captive for nine days by a flock of rock pigeons on a small island near Malta in 1979 - it may have been Gozo but I'm not too sure. (Sorry about that.) As you might gather she suffers from nightmares and flashbacks but she has also developed a loathing of millet seeds for some strange reason. She is in full support of the cull and, in actual fact, she has already applied for the job and fully intends to carry out her duties as soon as possible - whether she gets the job or not. Be careful around town folks - she's not a good shot.
diff --git a/blog/content/2007/07/everything-is-connected.gmi b/blog/content/2007/07/everything-is-connected.gmi
index f4552c08..fe576d52 100644
--- a/blog/content/2007/07/everything-is-connected.gmi
+++ b/blog/content/2007/07/everything-is-connected.gmi
@@ -1,18 +1,9 @@
# 2007-07-09 Everything is connected
-De los The B-52's [1], a Blondie [2] a...
+=> https://www.youtube.com/watch?v=rSEMjZ6YqGI De los The B-52's...
-=> https://youtube.com/watch?v=Y4dUS7v2NIQ [1] The B-52's
-=> https://youtube.com/watch?v=qW6OrdLkCLU [2] Blondie
+=> https://www.youtube.com/watch?v=O_WLw_0DFQQ ... a Blondie a...
->
->
->
-> Hi, it's Deb. You know, when I woke up this morning I had a realization
-> about myself. I was always Blondie. People always called me Blondie, ever
-> since I was a little kid. What I realized ia that at some point I became
-> Dirty Harry. I couldn't be Blondie anymore, so I became Dirty Harry.
->
->
+> Hi, it's Deb. You know, when I woke up this morning I had a realization about myself. I was always Blondie. People always called me Blondie, ever since I was a little kid. What I realized ia that at some point I became Dirty Harry. I couldn't be Blondie anymore, so I became Dirty Harry.
...¡el tito Clint!
diff --git a/blog/content/2008/02/gentlemen-you-can-t-fight-in-here-this-is-the-war-room.gmi b/blog/content/2008/02/gentlemen-you-can-t-fight-in-here-this-is-the-war-room.gmi
index b838390d..fc8021c0 100644
--- a/blog/content/2008/02/gentlemen-you-can-t-fight-in-here-this-is-the-war-room.gmi
+++ b/blog/content/2008/02/gentlemen-you-can-t-fight-in-here-this-is-the-war-room.gmi
@@ -1,26 +1,11 @@
# 2008-02-29 Gentlemen, you can't fight in here! This is the War Room
->
->
->
-> According to our sources, the Home lobby for the Incognito dogfighter will
-> serve as a "war room" where up to eight players can meet to discuss their
-> strategy for an upcoming match. Sure, you could do that with text or voice
-> chat, but it sounds like the developers have gone the extra mile to make
-> planning your battles even cooler.
->
->
->
-> Using a three-dimensional "sand table" replication of the level, Warhawk
-> players are said to be able to lay out their strategies in a properly
-> scaled space. They'll even be able to place little army men avatars around
-> the map to envision their formations, something we hope they can also do
-> with teeny tiny Warhawk planes, tanks and Jeeps.
->
->
+> According to our sources, the Home lobby for the Incognito dogfighter will serve as a "war room" where up to eight players can meet to discuss their strategy for an upcoming match. Sure, you could do that with text or voice chat, but it sounds like the developers have gone the extra mile to make planning your battles even cooler.
-Es sólo un rumor [1], no pienso comprarme una PS3 y no creo que juegue al Warhawk.
+> Using a three-dimensional "sand table" replication of the level, Warhawk players are said to be able to lay out their strategies in a properly scaled space. They'll even be able to place little army men avatars around the map to envision their formations, something we hope they can also do with teeny tiny Warhawk planes, tanks and Jeeps.
-=> http://kotaku.com/361562/how-warhawk-makes-home-really-really-cool [1] un rumor
+Es sólo un rumor, no pienso comprarme una PS3 y no creo que juegue al Warhawk.
Pero mola. Mucho.
+
+=> https://web.archive.org/web/20090422074114/http://kotaku.com/361562/how-warhawk-makes-home-really-really-cool Kotaku - How Warhawk Makes Home Really, Really Cool
diff --git a/blog/content/2010/03/gatos-azucarados.gmi b/blog/content/2010/03/gatos-azucarados.gmi
index 46076866..e98e6f6e 100644
--- a/blog/content/2010/03/gatos-azucarados.gmi
+++ b/blog/content/2010/03/gatos-azucarados.gmi
@@ -1,23 +1,5 @@
# 2010-03-16 Gatos azucarados
->
->
->
-> 8 Professors are in the 9th year of a 12 year encyclopedia writing
-> project. The youngest is Bertram Potts who specializes in language and
-> grammar. When Professor Potts discovers that his section on slang is
-> outdated, he sets out to research the topic. Nightclub performer Sugarpuss
-> O'Shea is engaged to gangster Joe Lilac. When she discovers that the
-> police are after her, she must find a place to lay low. Then Potts meets
-> Sugarpuss. He is impressed with her slang and wants to study it further.
-> Sugarpuss uses his study as an excuse to invite herself to stay with the 8
-> Professors at their residence--a perfect hideout. She wins over the older
-> Professors teaching them how to do a Conga Line and earns a marriage
-> proposal from 'Pottsie' by showing him 'yum-yum'. However, Joe Lilac
-> resurfaces with other plans for Sugarpuss.
->
->
+> 8 Professors are in the 9th year of a 12 year encyclopedia writing project. The youngest is Bertram Potts who specializes in language and grammar. When Professor Potts discovers that his section on slang is outdated, he sets out to research the topic. Nightclub performer Sugarpuss O'Shea is engaged to gangster Joe Lilac. When she discovers that the police are after her, she must find a place to lay low. Then Potts meets Sugarpuss. He is impressed with her slang and wants to study it further. Sugarpuss uses his study as an excuse to invite herself to stay with the 8 Professors at their residence--a perfect hideout. She wins over the older Professors teaching them how to do a Conga Line and earns a marriage proposal from 'Pottsie' by showing him 'yum-yum'. However, Joe Lilac resurfaces with other plans for Sugarpuss.
-Otra peli [1] por ver...
-
-=> https://www.imdb.com/title/tt0033373/ [1] Otra peli
+=> https://www.imdb.com/title/tt0033373/ Otra peli por ver...
diff --git a/blog/content/2011/01/django-o-la-fabrica-de-churros.gmi b/blog/content/2011/01/django-o-la-fabrica-de-churros.gmi
index 904dd1a4..0935fbe9 100644
--- a/blog/content/2011/01/django-o-la-fabrica-de-churros.gmi
+++ b/blog/content/2011/01/django-o-la-fabrica-de-churros.gmi
@@ -7,7 +7,7 @@ Estos días me he encontrado frente a una web sencilla, pero que a mi juicio no
¿A parte de esto, qué otras virtudes tiene Django?
* Vistas genéricas. En particular, lista/detalle sobre los modelos de datos, resolviendo correctamente paginación, ordenación, filtrado, etc. Tiene también vistas y maquinaria para hacer CRUD, que supongo funcionan bien pero que no he usado
-* Usa HTML/HTTP "correcto" sin hacer cosas raras, añadir Javascripts innecesarios, serializaciones raras, etc. Todo muy limpio
+* Usa HTML/HTTP "correcto" sin hacer cosas raras, añadir JavaScripts innecesarios, serializaciones raras, etc. Todo muy limpio
* Está documentado. No llega al nivel de Java o Spring, pero desde luego, comparado con Rails y otras estrellas de código libre...
* No usa generación de código. Odiamos la generación de código.
@@ -18,7 +18,7 @@ Pero también le encuentro algún que otro defecto:
* El sistema de plantillas está muy bien, pero es "regular" y no "gramatical", con lo que no admite expresiones donde debería ni otras estructuras muy convenientes. JSP con fragmentos de tag es *muy* superior
* Tengo la sospecha que el funcionamiento sobre JVM no será para tirar cohetes. Además, si nos interesa funcionar sobre JVM, nos tenemos que limitar a Django 1.1 y evitar 1.2 de momento.
* En general el sistema de internacionalización está muy bien, pero no soporta internacionalización en el modelo de datos (i.e. campos multilingües en las entidades)
-* No viene con nada para hacer Javascript/AJAX, aunque seguramente no sería de mi agrado, claro
+* No viene con nada para hacer JavaScript/AJAX, aunque seguramente no sería de mi agrado, claro
A pesar de esto, creo que es el mejor "framework completo" que he visto. Como plataforma "básica", sigo prefiriendo Java + Spring + Servlets + JSP + JSTL, pero creo que Django puede tener un lugar bastante importante en el arsenal de un desarrollador web. La pregunta es, ¿cuál es ese lugar?
diff --git a/blog/content/2011/10/apuntes-sobre-dart.gmi b/blog/content/2011/10/apuntes-sobre-dart.gmi
index 2fb60e7e..432378e7 100644
--- a/blog/content/2011/10/apuntes-sobre-dart.gmi
+++ b/blog/content/2011/10/apuntes-sobre-dart.gmi
@@ -2,9 +2,9 @@
Google ha sacado hoy Dart[1].
-El apunte rápido (que seguro que otros mejoran) es que es un verdadero **Java**script. Es un lenguaje muy muy Java que compila a Javascript. Las diferencias con Java van por dos lados:
+El apunte rápido (que seguro que otros mejoran) es que es un verdadero **Java**Script. Es un lenguaje muy muy Java que compila a JavaScript. Las diferencias con Java van por dos lados:
-* Adecuaciones para funcionar bien cuando se compila a Javascript- i.e. no hay threads, hay "isolates", etc.
+* Adecuaciones para funcionar bien cuando se compila a JavaScript- i.e. no hay threads, hay "isolates", etc.
* Esas mejoras puntuales de Java que llevamos pidiendo a gritos desde hace siglos
Las mejoras de Java son de ovación cerrada:
@@ -18,11 +18,11 @@ Las mejoras de Java son de ovación cerrada:
Siendo realistas, cubre la mayoría de "defectos" "resolubles" de Java. No, no tiene inferencia de tipos, ni lambdas con excepciones chulas, ni "final" por defecto... y quizás no es todo como uno lo había soñado, pero es una solución práctica y disponible **hoy**.
-Eso es lo positivo. En lo negativo, el tipado opcional me escama- y me duele que signifique sacrificios (hay ahí una cosilla un poco rara con las funciones que no devuelven valor que me deja intranquilo). Me queda la curiosidad de estudiar los isolates para saber si aportan algo o si son sencillamente la manera correcta de montar concurrencia en código que será compilado a Javascript y ejecutado por los motores de Javascript existentes.
+Eso es lo positivo. En lo negativo, el tipado opcional me escama- y me duele que signifique sacrificios (hay ahí una cosilla un poco rara con las funciones que no devuelven valor que me deja intranquilo). Me queda la curiosidad de estudiar los isolates para saber si aportan algo o si son sencillamente la manera correcta de montar concurrencia en código que será compilado a JavaScript y ejecutado por los motores de JavaScript existentes.
He visto otras cosas que aún no me he mirado a fondo que no sé dónde colocar: soporte en el lenguaje para factorías, "const" el sistema de librerías y que null sea un objeto; es difícil saber si serán cosas buenas o malas.
-En fin, cosas interesantes. No parece, sin embargo, que Dart aspire de momento a ser algo más que un sustituto de Javascript (algo que no me interesa mucho- el principal problema de Javascript no es el lenguaje en sí, en mi opinión)... con lo que **para mi**, no es muy interesante de momento.  Si algún día se planta como una alternativa para desarrollo de aplicaciones y para programación, tiene  la oportunidad de ser Java++, pero sin añadir la complejidad y cerradez de C#... pero ni siquiera sé si Google pretende que lo sea (ese rol lo quieren para... ¿Go? ¿Dart? ¿Java? ¿Python?) .
+En fin, cosas interesantes. No parece, sin embargo, que Dart aspire de momento a ser algo más que un sustituto de JavaScript (algo que no me interesa mucho- el principal problema de JavaScript no es el lenguaje en sí, en mi opinión)... con lo que **para mi**, no es muy interesante de momento.  Si algún día se planta como una alternativa para desarrollo de aplicaciones y para programación, tiene  la oportunidad de ser Java++, pero sin añadir la complejidad y cerradez de C#... pero ni siquiera sé si Google pretende que lo sea (ese rol lo quieren para... ¿Go? ¿Dart? ¿Java? ¿Python?) .
=> http://www.dartlang.org/ 1: http://www.dartlang.org/
diff --git a/blog/content/2012/06/desarrollo-web-como-dios-manda.gmi b/blog/content/2012/06/desarrollo-web-como-dios-manda.gmi
index e100c7c6..3b1ea8a9 100644
--- a/blog/content/2012/06/desarrollo-web-como-dios-manda.gmi
+++ b/blog/content/2012/06/desarrollo-web-como-dios-manda.gmi
@@ -14,13 +14,13 @@ Una manera fácil de comenzar es por el lenguaje. Es conveniente que escojamos u
Comenzando por el principio, un buen punto de partida es mi querido TIOBE[1]. El TIOBE es un ránking de la popularidad de los lenguajes de programación calculado a partir de su presencia en la web. La metodología es inevitablemente discutible, pero el ránking está bastante alineado con mi percepción, así que para mi, es una opción cómoda.
-En el top 20 (a junio de 2012) encontramos tan solo 8 lenguajes utilizados comunmente para el desarrollo web: Java, C#, PHP, Python, Perl, Ruby, Javascript y Visual Basic .NET. Fuera del Top 20 encontramos muy poquitas opciones (Haskell, Scala y poco más), así que nos ceñiremos a estos.
+En el top 20 (a junio de 2012) encontramos tan solo 8 lenguajes utilizados comunmente para el desarrollo web: Java, C#, PHP, Python, Perl, Ruby, JavaScript y Visual Basic .NET. Fuera del Top 20 encontramos muy poquitas opciones (Haskell, Scala y poco más), así que nos ceñiremos a estos.
Vamos a descartar unos pocos:
* PHP[2]: pese a ser un lenguaje explícitamente diseñado para el desarrollo web, en mi opinión PHP nunca debe usarse para desarrollar un proyecto desde 0- a no ser que lo que queramos desarrollar sea extremadamente mínimo- ya sea porque se trate de un desarrollo extremadamente pequeño o bien que pretendamos reutilizar completamente un desarrollo existente como Wordpress o Magento. Desarrollar grandes bases de código en PHP es un ejercicio frustrante ya que, sencillamente, no está pensado para ello. Sus limitaciones en cuanto a modelo de ejecución, estructura y modularidad son motivo suficiente para descartarlo, pues el resto de lenguajes que consideramos lo superan ampliamente en estos aspectos, ofreciendo PHP muy poco para compensar (su velocidad para proyectos mínimos).Puede sernos útil conocer PHP, pues existe mucho trabajo manteniendo código PHP (sin embargo, no se trata de un trabajo especialmente gratificante) y en algún momento nos puede ser útil. Pero debe ser erradicado lo antes posible.
* Perl[3]: durante mucho tiempo fue una de las mejores opciones disponibles, en realidad, una de las pocas viables. Una vez más, el resto de lenguajes de la lista le superan en virtudes sin que Perl ofrezca muchas ventajas propias. El mercado de Perl decae lentamente y cada vez se inician menos proyectos que lo utilicen.
-* JavaScript[4]: si bien deberemos conocer JavaScript para desarrollar efectivamente sobre la web, aún no lo considero una opción viable en el lado servidor. Tendremos que aprender JavaScript, pero el grueso del proyecto deberá ser siempre en otro de los lenguajes. Soy anti-aplicaciones web 100% Javascript, creo que su campo de aplicación es extremadamente limitado y presentan desventajas considerables, pero hay quien les encuentra virtudes
+* JavaScript[4]: si bien deberemos conocer JavaScript para desarrollar efectivamente sobre la web, aún no lo considero una opción viable en el lado servidor. Tendremos que aprender JavaScript, pero el grueso del proyecto deberá ser siempre en otro de los lenguajes. Soy anti-aplicaciones web 100% JavaScript, creo que su campo de aplicación es extremadamente limitado y presentan desventajas considerables, pero hay quien les encuentra virtudes
C#[5] y Visual Basic .NET[6] son dos opciones que el lector mismo puede escoger descartar o considerar- desarrollar razonablemente en ambos supone unos costes que yo prefiero no asumir (se necesitan licencias de Windows para el desarrollo y despliegue y las versiones gratuitas de Visual Studio tienen bastantes limitaciones)- a parte de que soy un firme creyente en que las herramientas de desarrollo deben ser libres y gratuitas. Si eso no supone un impedimento para el lector, puede aplicar mi opinión sobre Java, ambas plataformas son extremadamente similares; quizás .NET goce de herramientas más sencillas de utilizar inicialmente, el sistema base es más completo que el de Java pero el ecosistema goza de menor vida.
diff --git a/blog/content/2012/11/que-es-el-rpc.gmi b/blog/content/2012/11/que-es-el-rpc.gmi
index 717bea63..501b3b55 100644
--- a/blog/content/2012/11/que-es-el-rpc.gmi
+++ b/blog/content/2012/11/que-es-el-rpc.gmi
@@ -11,7 +11,7 @@ y que la suma se realice en el sistema remoto. A esto le llamaron llamada de pro
Sun implementó uno de los primeros sistemas de RPC para implementar el sistema de archivos distribuido NFS, y a lo largo del tiempo han ido apareciendo diferentes mecanismos de RPC para diferentes plataformas y necesidades.
-Con la popularización de la WWW, el protocolo HTTP y Javascript en los 90, pronto la gente comenzó a implementar comunicaciones entre sistema utilizándolos. Por ejemplo, una web podía exponer algunos de sus contenidos y funcionalidades en HTML para consumo humano, pero también exponerlos para consumo de otros sistemas. Mecanismos simples como poner una URL en la que si hacemos un POST http con unos argumentos, nos devuelve el resultado de una operación en un formato fácilmente parseable.
+Con la popularización de la WWW, el protocolo HTTP y JavaScript en los 90, pronto la gente comenzó a implementar comunicaciones entre sistema utilizándolos. Por ejemplo, una web podía exponer algunos de sus contenidos y funcionalidades en HTML para consumo humano, pero también exponerlos para consumo de otros sistemas. Mecanismos simples como poner una URL en la que si hacemos un POST http con unos argumentos, nos devuelve el resultado de una operación en un formato fácilmente parseable.
Pronto, uno de los padres fundadores del HTTP, procesó los principios fundamentales del HTTP y la WWW, en concreto que todo era una cuestión de URLs y acciones como GET/POST/PUT/DELETE que soporta el protocolo HTTP; cada URL representa un recurso y podemos expresar acciones mediante los "verbos" HTTP. A esto le llamó REST y supuso una perspectiva limpia y poderosa de lo que es la WWW.
diff --git a/blog/content/2013/09/recopilatorios-de-grandes-exitos.gmi b/blog/content/2013/09/recopilatorios-de-grandes-exitos.gmi
index c08c9e6b..6e76e871 100644
--- a/blog/content/2013/09/recopilatorios-de-grandes-exitos.gmi
+++ b/blog/content/2013/09/recopilatorios-de-grandes-exitos.gmi
@@ -18,9 +18,9 @@ En general, los compiladores suelen ser de lenguajes de mayor nivel a menor nive
En estos casos, la cosa se suele complicar mucho más porque una implementación naíf de un compilador a ensamblador suele redundar en programas que al ejecutarse son espectacularmente ineficientes. Conseguir ejecutables eficientes es un problema completo en sí mismo sobre el que se han escrito toneladas de libros.
-Sin embargo, recientemente son más habituales los compiladores que compilan lenguajes a cosas que no son ensamblador- por diversos motivos entre los que destaca que un compilador a ensamblador sólo es útil para una familia de CPUs, y pese a que la familia x86 de Intel y los ARM copan la mayor parte del mercado, sigue habiendo muchos otros procesadores en uso hoy en día. Por otra parte, plataformas como la máquina virtual Java, LLVM o incluso Javascript también son populares como destinos de los compiladores- en el caso de Java o LLVM por ser más simples para la generación de código sin sacrificar eficiencia, y en el caso de Javascript, por ser un destino particularmente útil ya que nos permite ejecutar el código compilado en un navegador.
+Sin embargo, recientemente son más habituales los compiladores que compilan lenguajes a cosas que no son ensamblador- por diversos motivos entre los que destaca que un compilador a ensamblador sólo es útil para una familia de CPUs, y pese a que la familia x86 de Intel y los ARM copan la mayor parte del mercado, sigue habiendo muchos otros procesadores en uso hoy en día. Por otra parte, plataformas como la máquina virtual Java, LLVM o incluso JavaScript también son populares como destinos de los compiladores- en el caso de Java o LLVM por ser más simples para la generación de código sin sacrificar eficiencia, y en el caso de JavaScript, por ser un destino particularmente útil ya que nos permite ejecutar el código compilado en un navegador.
-Tanto la JVM como la LLVM han sido diseñadas especialmente para este propósito, con lo que tienden a simplificarnos el proceso de compilación. En el caso de Javascript, pese a estar pensado con otros propósitos, proyectos como GWT o Emscripten han hecho grandes esfuerzos para hacer funcionar compiladores sobre Javascript. Mozilla incluso ha lanzado la iniciativa asm.js para definir un subconjunto de Javascript que sea práctico como plataforma a la que compilar de una manera eficiente.
+Tanto la JVM como la LLVM han sido diseñadas especialmente para este propósito, con lo que tienden a simplificarnos el proceso de compilación. En el caso de JavaScript, pese a estar pensado con otros propósitos, proyectos como GWT o Emscripten han hecho grandes esfuerzos para hacer funcionar compiladores sobre JavaScript. Mozilla incluso ha lanzado la iniciativa asm.js para definir un subconjunto de JavaScript que sea práctico como plataforma a la que compilar de una manera eficiente.
El proceso no se queda aquí, ya que una vez tenemos un lenguaje funcional con intérprete o compilador, siempre hay un interés en acelerarlo- tanto el proceso de compilación como la ejecución de los programas. Una vez más, se trata de un área complicada y sutilezas- se han llegado a técnicas extremadamente sofisticadas que incluso "aprenden" de la ejecución del programa y modifican su funci0namiento para adaptarse y mejorar "en vivo".
diff --git a/blog/content/2014/01/integracion-apis-y-no-me-toques-los-bezos.gmi b/blog/content/2014/01/integracion-apis-y-no-me-toques-los-bezos.gmi
index 4cc8a2fb..070e3d7d 100644
--- a/blog/content/2014/01/integracion-apis-y-no-me-toques-los-bezos.gmi
+++ b/blog/content/2014/01/integracion-apis-y-no-me-toques-los-bezos.gmi
@@ -2,23 +2,18 @@
Según Steve Yegge, un día Jeff Bezos, el capo de Amazon, envió un memorándum interno que venía a decir:
-> 1.
-> All teams will henceforth expose their data and functionality through service interfaces.
->
-> 2.
-> Teams must communicate with each other through these interfaces.
->
-> 3.
-> There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team's data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.
->
-> 4.
-> It doesn't matter what technology they use. HTTP, Corba, Pubsub, custom protocols -- doesn't matter. Bezos doesn't care.
->
-> 5.
-> All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.
->
-> 6.
-> Anyone who doesn't do this will be fired.
+> 1. All teams will henceforth expose their data and functionality through service interfaces.
+
+> 2.Teams must communicate with each other through these interfaces.
+
+> 3. There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team's data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.
+
+> 4. It doesn't matter what technology they use. HTTP, Corba, Pubsub, custom protocols -- doesn't matter. Bezos doesn't care.
+
+> 5. All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.
+
+> 6. Anyone who doesn't do this will be fired.
+
Este puñetero memo, y toda la gente que lo ha leído y ha aplicado el silogismo falaz de "En Amazon son unos cracks, en Amazon siguen este credo ergo si yo sigo este credo seré un crack" son un maldito dolor de cabeza.
Conste que no es que considere que las APIs sean una plaga a exterminar, ni mucho menos, pero debería olernos mal las sentencias absolutistas y los razonamientos de talla única. No todos los entornos son iguales, ni se enfrentan a los mismos problemas- y por tanto lo que funciona para unos, no funciona para otros. Adicionalmente, es difícil razonar que la aplicación ciega de esta doctrina es lo que ha llevado a Amazon al éxito y estoy seguro que no en pocas ocasiones mejor les hubiera ido siendo un poco más críticos.
diff --git a/blog/content/2020/07/isos-y-usbs.gmi b/blog/content/2020/07/isos-y-usbs.gmi
index 94776f30..3c367362 100644
--- a/blog/content/2020/07/isos-y-usbs.gmi
+++ b/blog/content/2020/07/isos-y-usbs.gmi
@@ -1,6 +1,6 @@
# 2020-07-01 ISOs y USBs
-=> https://github.com/alexpdp7/alexpdp7/blob/master/hardware/using-an-rpi-zero-as-an-usb-drive-to-install-operating-systems.md EDIT 2025-01-12: Aquí documento una manera de hacer estas cosas con una Raspberry Pi Zero.
+=> https://github.com/alexpdp7/rpi-zero-usb-iso EDIT 2027-04-14: Aquí documento una manera de hacer estas cosas con una Raspberry Pi Zero.
Actualización 2024-12-24: Tras un tiempo usándolo, estoy investigando otras vías porque Ventoy da algunos problemillas. IODD fabrica cacharros algo caros que hacen esto. También está el sistema "USB Gadget" de Linux que permite a algo tipo Raspberry actuar como CDROM USB.
diff --git a/blog/content/2021/03/los-gemelos-golpean-dos-veces.gmi b/blog/content/2021/03/los-gemelos-golpean-dos-veces.gmi
index f0551a76..98d5f1c9 100644
--- a/blog/content/2021/03/los-gemelos-golpean-dos-veces.gmi
+++ b/blog/content/2021/03/los-gemelos-golpean-dos-veces.gmi
@@ -1,12 +1,14 @@
# 2021-03-13 Los gemelos golpean dos veces
+=> ../../2026/02/la-antigua-nueva-escuela EDIT 2026-04-14: Post de este blog donde explico la última iteración de su implementación
+
Esta es la primera entrada que creo en mi blog en el Geminiespacio (¿Gemeloespacio? ¿Geminispacio? Dudo que la RAE o la Fundéu me ayuden con esto). El Geminiespacio es un fascinante proyecto del que ya os hablé[1] anteriormente que define un protocolo parecido a la web, pero simplificado al máximo- los que recuerden el protocolo Gopher les sonará- pero el Geminiespacio está modernizado (requiere TLS, por ejemplo) y aprende unas cuantas lecciones de la web.
Es un protocolo muy inflexible (si quisiesemos implementar un buscador, por ejemplo, no permite formularios aunque sí permite pedir al usuario una cadena de texto) que impide todo lo que odiamos de la web moderna. Una cápsula Gemini sólo es hipertexto y nada más, ni lo bueno ni lo maligno.
He publicado el código fuente del terrible invento rubegoldberesco que me ha permitido migrar este blog de WordPress a un extraño injerto estático y el proxy a través del cuál muy probablemente estéis leyendo esta entrada mediante un navegador convencional. Lo podéis encontrar aquí:
-=> https://github.com/alexpdp7/gemini_blog/ El repositorio con el código de sostiene este blog
+=> ../../2026/02/la-antigua-nueva-escuela EDIT 2026-04-14: Post de este blog donde explico la última iteración de su implementación
Espero no provocar demasiados problemas con esta migración. Me temo que los que uséis RSS seguramente veréis republicadas las últimas diez entradas del blog, eso sí.
diff --git a/blog/content/2022/07/la-caja-de-herramientas.gmi b/blog/content/2022/07/la-caja-de-herramientas.gmi
index 702f4a9d..c3db3b2b 100644
--- a/blog/content/2022/07/la-caja-de-herramientas.gmi
+++ b/blog/content/2022/07/la-caja-de-herramientas.gmi
@@ -1,6 +1,6 @@
# 2022-07-11 La caja de herramientas
-=> https://github.com/alexpdp7/alexpdp7/blob/master/hardware/using-an-rpi-zero-as-an-usb-drive-to-install-operating-systems.md EDIT 2025-01-21: Aquí documento como hacer esto con una Raspberry Pi Zero.
+=> https://github.com/alexpdp7/rpi-zero-usb-iso EDIT 2027-04-14: Aquí documento una manera de hacer estas cosas con una Raspberry Pi Zero.
Cuando uno se lía con lo que no debería, hace gastos inútiles, pero lo que aprende igual le sirve a alguien.
diff --git a/blog/content/2022/11/origenes.gmi b/blog/content/2022/11/origenes.gmi
index 906582f0..9f431f41 100644
--- a/blog/content/2022/11/origenes.gmi
+++ b/blog/content/2022/11/origenes.gmi
@@ -2,7 +2,7 @@
Para los que estéis perdidos sin esa web de la que usted me habla, mi insomnio ha decidido que os dedique un ratito.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/FUENTES.md He recopilado algunos de los sitios en Internet que sigo por RSS.
+EDIT 2026-04-14: Aquí tenía un enlace a mis fuentes de RSS, pero estaba obsoleto y lo he borrado.
Ahora mismo son treinta y pico sitios web que tienen feed RSS, ligeramente clasificados.
diff --git a/blog/content/2024/01/ahi-vamos-de-nuevo.gmi b/blog/content/2024/01/ahi-vamos-de-nuevo.gmi
index b402745d..8a2ce1ce 100644
--- a/blog/content/2024/01/ahi-vamos-de-nuevo.gmi
+++ b/blog/content/2024/01/ahi-vamos-de-nuevo.gmi
@@ -14,7 +14,7 @@ Demasiado escribo sobre esta nueva brujería, pero como sabéis, la evolución d
Y el resto, en batiburrillo:
=> https://blog.google/products/search/improvements-to-using-spanish-in-search-and-gboard/ Sería mucho más interesante si esta colaboración de la RAE con Google resultase en algún recurso que podamos usar todos.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/hardware/about_headphones.md Por cierto que también escribo demasiado en otros sitios. He comenzado a ir moviendo artículos a un repositorio en GitHub. El otro día añadí una referencia sobre auriculares.
+=> ../../2026/03/notas Por cierto que también escribo demasiado en otros sitios. He comenzado a ir moviendo artículos a un repositorio en GitHub. El otro día añadí una referencia sobre auriculares. EDIT 2026-04-14: Ahora lo he reemplazado por una web simple, esto enlaza a otra entrada del blog explicándolo.
=> https://blog.google/products/gmail/gmail-emoji-reactions/ Aunque os sorprenda, reaccionar con emojis a correos electrónicos me parece un paso en la dirección adecuada. Aunque lo suyo sería poder reaccionar con un simple +1.
=> https://plus.nasa.gov/ Muchas plataformas, pero esta es gratis y tiene plataformas de lanzamiento.
=> https://www.politico.eu/article/inside-giorgia-meloni-hobbit-fantasy-world-lord-of-the-rings-fratelli-italia-brothers-italy-politics/ Pobres hóbbits
diff --git a/blog/content/2024/07/ovejas.gmi b/blog/content/2024/07/ovejas.gmi
index b6c948bb..4b19aca7 100644
--- a/blog/content/2024/07/ovejas.gmi
+++ b/blog/content/2024/07/ovejas.gmi
@@ -30,7 +30,7 @@ Voy soltando reflexiones chorras en el Fediverso que me da un poco de vergüenza
=> https://sansec.io/research/polyfill-supply-chain-attack Y cómo las optimizaciones innecesarias... (y otras manías mías)... nos exponen a peligrosos agujeros de seguridad.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/misc/comprar-bajo-en-sodio.org Consejos para comprar sin sal, de alguien que NO es una autoridad (yo).
+=> ../../notas/comprar-bajo-en-sodio Consejos para comprar sin sal, de alguien que NO es una autoridad (yo).
=> https://en.m.wikipedia.org/wiki/The_Vanilla_Ice_Project The Vanilla Ice Project is an American reality television series on the DIY Network. It is hosted by construction contractor and rapper Rob Van Winkle, a.k.a. Vanilla Ice, who has significant experience with home improvement and real estate flipping.
diff --git a/blog/content/2024/08/tu-transportas.gmi b/blog/content/2024/08/tu-transportas.gmi
index 3883ee80..015b2a4e 100644
--- a/blog/content/2024/08/tu-transportas.gmi
+++ b/blog/content/2024/08/tu-transportas.gmi
@@ -15,6 +15,6 @@ Después de ese batiburrillo, otro batiburrillo:
=> https://www.netflix.com/es-en/title/81217220 Me temo que no tendrá a Sarah, pero bueno...
=> https://www.cnx-software.com/2024/07/19/radxa-x4-low-cost-credit-card-sized-intel-n100-sbc-raspberry-pi-5-alternative/ ¿Una Raspberry Pi sin los problemas de las Raspberry Pi?
=> https://www.rockfm.fm/al-dia/noticias/dia-que-rosendo-conocio-rory-gallagher-unos-majaras-que-estan-locos-por-20220302_1936126 Era obvio, pero Rosendo es fan de Rory Gallagher.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/misc/problemas.md Una pequeña lista de problemas que me tocan alguna fibra determinada
-=> https://github.com/alexpdp7/alexpdp7/blob/master/FUENTES.md Ajustes a mis sugerencias RSS
+=> ../../notas/tecnologia/problemas Una pequeña lista de problemas que me tocan alguna fibra determinada
+Ajustes a mis sugerencias RSS. EDIT 2026-04-14: Eliminé este documento por estar obsoleto
=> https://en.wikipedia.org/wiki/What3words Inesperadamente controvertidos sistemas de codificar coordenadas
diff --git a/blog/content/2024/11/la-x-no-marca-el-lugar.gmi b/blog/content/2024/11/la-x-no-marca-el-lugar.gmi
index b1b1c0d3..b777f753 100644
--- a/blog/content/2024/11/la-x-no-marca-el-lugar.gmi
+++ b/blog/content/2024/11/la-x-no-marca-el-lugar.gmi
@@ -10,7 +10,7 @@ Este mes también he decidido abandonar otra comunidad online más personal. Y l
Creo que es importante saber encontrar comunidades online a las que pertenecer. Yo creo que pertenezco a varias, pero estas dos que he abandonado cubrían cosas que he perdido. No tengo una buena comunidad extendida local profesional, y sigue habiendo gente valiosa escribiendo en Twitter.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/misc/take-the-less-traveled-road.md Pero creo que hoy más que nunca tenemos que tomar decisiones "ilógicas".
+EDIT 2026-04-14: Enlace eliminado a un documento obsoleto
(Tengo cuenta de BlueSky, pero sólo he puesto dos mensajes allí explicando que no hay que usar BlueSky.)
diff --git a/blog/content/2024/11/otros-relojes-apocalipticos.gmi b/blog/content/2024/11/otros-relojes-apocalipticos.gmi
index 1480ecb3..1004ace2 100644
--- a/blog/content/2024/11/otros-relojes-apocalipticos.gmi
+++ b/blog/content/2024/11/otros-relojes-apocalipticos.gmi
@@ -25,4 +25,4 @@ El resto, en batiburrillo:
=> https://github.com/mastodon/mastodon/issues/23153 Pero este es el mayor obstáculo para navegar el Fediverso desde una terminal, en mi opinión.
=> https://typst.app/blog/2024/typst-0.12 Typst pinta guay, aunque incide en mi sorpresa ante la insistencia en la paginación. Pero esto parece que podría cambiar.
=> https://hurmet.org/sample Esto también son cálculos en papel, pero más bien en pergamino.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/hardware/ES-teles.md Artículo propio sobre la caja tonta
+=> ../../notas/tele/teles Artículo propio sobre la caja tonta
diff --git a/blog/content/2025/05/jugando-al-monopoly.gmi b/blog/content/2025/05/jugando-al-monopoly.gmi
index bce97ba5..01a41db4 100644
--- a/blog/content/2025/05/jugando-al-monopoly.gmi
+++ b/blog/content/2025/05/jugando-al-monopoly.gmi
@@ -45,5 +45,5 @@ Mis recomendaciones iniciales pasan por:
=> https://mastodon.social/@chechar/114444705177197924 [1] opino que la mejor sanción contra las prácticas monopolísticas ilegales de Google...
=> https://en.wikipedia.org/wiki/Microsoft_litigation [2] Microsoft en los juzgados
=> ../../2025/01/epistolas-inmediatas [3] Sobre mensajería instantánea en español
-=> https://github.com/alexpdp7/alexpdp7/blob/master/misc/internet-communication-channels.md [4] Sobre mensajería instantánea en inglés
+=> ../../notes/tech/internet-communication-channels [4] Sobre mensajería instantánea en inglés
=> ../../2025/03/viajar-en-el-tiempo-a-2006-para-comerle-la-cabeza-a-jack [5] Sobre redes sociales
diff --git a/blog/content/2025/05/la-web.gmi b/blog/content/2025/05/la-web.gmi
index d372fe10..9bd976f0 100644
--- a/blog/content/2025/05/la-web.gmi
+++ b/blog/content/2025/05/la-web.gmi
@@ -4,8 +4,7 @@ Vuelvo a escribir porque me suena una alarma y que llevabais más de un mes sin
Pero bueno, haré trampa; simplemente quiero dar bombo a dos artículos a los que, por diversos motivos, he estado haciendo mejoras esta mañana.
-=> https://github.com/alexpdp7/alexpdp7/blob/master/programming/the-content-web-manifesto/README.md The content web manifesto
-=> https://github.com/alexpdp7/alexpdp7/blob/master/programming/a_plan_against_the_current_web.md A plan against the current web
+Editado 2026-04-12: me cargué estos artículos porque al final todo se puede reducir a "haz que tu web funcione en lynx", que ya pongo más abajo.
La web es una de las facetas más valiosas de Internet; ambas son juntas algo *importante* para todos nosotros. Pero están en peligro.
diff --git a/blog/content/2026/03/me-gusta-el-futbol.gmi b/blog/content/2026/03/me-gusta-el-futbol.gmi
new file mode 100644
index 00000000..ae74e497
--- /dev/null
+++ b/blog/content/2026/03/me-gusta-el-futbol.gmi
@@ -0,0 +1,25 @@
+# 2026-03-19 Me gusta el fútbol
+
+Pero ya nunca veo partidos y básicamente sólo me entero de cosas porque no escaparía de los gritos ni en el fondo de la fosa de las Marianas. ¿Por qué?
+
+En 2011 escribí por aquí sobre Cruyff y la liga española[1].
+
+=> ../../2011/04/holandeses-voladores-ciclos-y-tendencias [1] Holandeses voladores, ciclos y tendencias
+
+Tengo algún recuerdo de Lineker, así que igual me acuerdo de 1986, pero pongamos que me aficioné con la primera liga de Cruyff.
+
+Entre la temporada 90-91 y la temporada 2003-2004, que es la última liga que ganó el Valencia, de esas catorce ligas hubo cuatro ligas que ganadas por tres equipos que no son ni Madrid ni Barcelona. (Dos del Valencia, una del Atlético de Madrid y otra para el Depor.)
+
+A partir de la 2004-2005, el Atlético de Madrid ha ganado dos ligas y las otras veinte, todas para Madrid y Barcelona.
+
+Por mucho que mi equipo preferido haya ganado 12 ligas frente a 7 de su eterno rival, que la competición con más partidos sea una moneda al aire entre los mismos dos equipos siempre (con el canto para el mismo tercer equipo siempre) me parece un soberano aburrimiento. Desde que el Valencia quedó tercero en la liga 2011-2012, sólo el Girona en la 2023-2024 ha conseguido colarse entre los tres primeros (para quedar el decimosexto la siguiente temporada). En mi opinión, la imprevisibilidad es uno de los factores que más contribuye al entretenimiento.
+
+Además, el recuerdo quizá endulzado por el tiempo que tengo del periodismo deportivo (por ejemplo, El Día Después con Michael Robinson, que echó el cierre en 2005) ha sido sustituido por el ruido y la furia vacíos a la que yo atribuyo su comienzo a la temporada 2009-2010. (Más o menos por esa época se labran más polarizaciones, curiosamente. Casualmente, es 2007 cuando Facebook superó a MySpace en como la plataforma social más popular del mundo y Twitter tuvo su explosión durante la conferencia South by Southwest Interactive.)
+
+Pero lo que me llama más la atención es lo absurdamente caro que te puede salir ver fútbol. Mirad lo que os costaría ver los 90 minutos semanales de vuestro equipo favorito en liga y comparad con lo que os costaría tener streaming hasta aburriros de cualquier otra cosa.
+
+Sigo considerando que el fútbol no se lo come todo por casualidad. (Aunque me parece que la introducción del videoarbitraje allá por 2017 en mi opinión rompe una de sus virtudes: que los aficionados juegan prácticamente a lo mismo que los equipos de primer nivel.) Pero mi consejo es que hay deporte para aburrir con la misma o más emoción, gratis y sin la toxicidad del fútbol de primer nivel al que estaba tan aficionado de joven.
+
+(Personalmente, principalmente veo ping pong y baloncesto, que son los dos deportes que he practicado más, y casi con cualquier cosa libremente disponible sin piratear en Internet, aunque por diversos motivos, raramente estoy viendo nada de más de diez minutos.)
+
+Apéndice 2026-04-05: menuda turra que solté sin mencionar lo más reciente. Que ahora cada vez que hay fútbol, cortan la mitad de Internet. El bonus es que es un conflicto entre varias partes en el que todas las partes me caen mal. El fútbol se lo come todo, huid si podéis.
diff --git a/blog/content/2026/03/notas.gmi b/blog/content/2026/03/notas.gmi
new file mode 100644
index 00000000..0a1da7b0
--- /dev/null
+++ b/blog/content/2026/03/notas.gmi
@@ -0,0 +1,32 @@
+# 2026-03-01 Notas
+
+Hoy tocaba escribir en el blog, pero en vez de ello me he dedicado a migrar más contenido (principalmente "ensayos") a esta web.
+
+Durante mucho tiempo, metía ficheros de texto (mayoritariamente en Markdown) en mi "monorepo" Git personal. (El monorepo es un amalgama de un montón de cosas, incluido este blog y muchas más cosas.) Esta técnica no funciona mal y es muy cómoda, pero me ataba demasiado a GitHub.
+
+Ahora podéis leer ese contenido en:
+
+=> ../../notes/ Notes (en inglés)
+=> ../../notas/ Notas (en español)
+
+Con lo que ahora todo tiene URLs controladas por un servidor.
+
+Además, he convertido todo (a manopla) al formato gemtext de Gemini. gemtext es mucho más limitado que Markdown, con lo que he tenido que simplificar un poco el formato. Pero creo que esta "sencillez obligada" me ayuda a estructurar las cosas de una manera más simple y más adaptable a distintos formatos. (Como que por ejemplo, podéis leer todo usando un navegador de Gemini, lo que ofrece en mi opinión muchas ventajas.)
+
+Tras borrar también bastante contenido obsoleto o de baja calidad, creo que ya no queda casi nada susceptible de pasarse a gemtext. Todavía hay algo material, pero es mayormente:
+
+* Listados en formato Org con mucha jerarquía que no funcionarían muy bien en gemtext.
+* Un par de artículos que debería actualizar y modernizar bastante... cosa que seguramente no haré a corto plazo y esperaré a que necesiten un remodelado profundo.
+
+Con esto creo que cierro una primera fase de la iteración de este sitio web (ahora cápsula y no sólo blog). Curiosamente he "perdido" funcionalidad:
+
+* Falta navegabilidad; básicamente sólo podemos desandar nuestros pasos en la nueva web usando el botón de "atrás" de nuestro navegador.
+* He perdido la editabilidad que me daba GitHub; antes los textos en GitHub tenían un botón editar la mar de majo y las entradas del blog tenían un enlace para editarlas en GitHub.
+
+Lo primero creo que tengo maneras de resolverlas que intentaré aplicar igual a corto plazo.
+
+Lo segundo me fastidia mucho más y no se me ocurre una buena manera de subsanarlo. Podría seguir usando las funcionalidades de GitHub, pero claro, estoy intentando reducir mi dependencia. Podría usar software equivalente a GitHub, pero me estoy inclinando por alternativas mucho más sencillas para hospedar Git que no tienen funcionalidad equivalente (y que me resultan muy atractivas por otros motivos).
+
+Para cerrar comentaré que ahora mismo el contenido de esta web es más o menos de 700.000 palabras. A veces en mi cabeza le llamo a esto "mi universo cinemático", porque no es más que una película que me he montado en la cabeza durante más de un cuarto de siglo. Por suerte o por desgracia no soy Jack Kerouac[1], pero al menos os diré que tanta verborrea me entretiene y creo que me enriquece. Os animo a montar vuestros propios universos cinemáticos.
+
+=> https://sabr.org/journal/article/jack-kerouac-the-beat-of-fantasy-baseball/ [1] Jack Kerouac: The Beat of Fantasy Baseball
diff --git a/blog/content/2026/03/peligros-de-bolsillo.gmi b/blog/content/2026/03/peligros-de-bolsillo.gmi
new file mode 100644
index 00000000..2464ed43
--- /dev/null
+++ b/blog/content/2026/03/peligros-de-bolsillo.gmi
@@ -0,0 +1,45 @@
+# 2026-03-20 Peligros de bolsillo
+
+Google lleva un tiempo intentando controlar los programas que uno puede ejecutar en su móvil Android. La idea es que toda aplicación deba estar aprobada por Google, lo que incluye que Google pueda identificar a la persona física responsable de la aplicación.
+
+Esta es la enésima versión de cosas de las que ya he hablado varias veces por aquí:
+
+=> ../../2025/02/el-lento-adios-a-la-magia-de-los-ordenadores El lento adiós a la magia de los ordenadores (2025, sobre que nos limiten en el uso de nuestros dispositivos)
+
+=> ../../2015/12/por-que-no-uso-productos-apple Por qué no uso productos Apple (2015, sobre cómo Apple me parece de lo peor en este sentido)
+
+Pero la verdad, las medidas en concreto que Google propone ahora no me gustan, pero tampoco se me ocurre nada mejor.
+
+Básicamente, la opción que va a dar Google para que podamos ejecutar aplicaciones que no controlan parece draconiana: entre otras cosas, el botón para habilitar esta funcionalidad tardará un día entero en tomar efecto (y además estará bastante escondido).
+
+Para mí, esto es bastante más satisfactorio que lo que proponían antes y no se me ocurre una opción mejor.
+
+Los autores de F-Droid, un excelente sistema para distribuir aplicaciones de código libre en Android de donde instalo bastantes aplicaciones, firman la siguiente carta abierta en contra de estas medidas:
+
+=> https://keepandroidopen.org/es/ Keep Android Open
+
+Enlazo a la traducción en español que todavía no está actualizada con la respuesta a la última propuesta de Google, donde rechazan la propuesta. La verdad que su contraargumento principal es que todavía no se puede verificar que Google hará esto y que Google puede volver a cambiar las reglas cuando quiera. Ambas son ciertas y estoy de acuerdo, pero también dan énfasis a que las medidas son un poco draconianas.
+
+En mi opinión, Google está reaccionando a una amenaza concreta. Según Google, hay muchos entes malignos haciendo llamadas telefónicas a gente y engañándoles para que instalen aplicaciones maliciosas en su teléfono. Si esto es cierto, ¿qué hacemos?
+
+Antes de responder a esta pregunta, en este punto creo que debemos preguntarnos varias cosas.
+
+Lo primero es que cómo hemos llegado a esta situación. Instalar una aplicación maliciosa en tu móvil puede ser muy peligroso. Por muchas medidas de protección que se pongan, es inevitable que pongamos en peligro cualquier cosa a la que podamos acceder por ese móvil. Y eso, por muchos motivos distintos, incluye muchísimas cosas importantes.
+
+Y hoy en día, estamos casi obligados a usar en móvil y casi obligados a manejar cosas sensibles a través de él. Por ejemplo, hoy en día el canal de comunicación con muchos de nuestros allegados es por (mal que me pese) WhatsApp. Muchos bancos restringen el acceso a mucha funcionalidad útil a su aplicación del móvil. Incluso algunos organismos oficiales nos hacen pasar por el móvil.
+
+(Y ojo, esto no es para nada algo exclusivo del móvil. Esto ya no pasa tanto con los ordenadores de escritorio y portátiles porque simplemente están muriendo. Creo que todo el mundo tiene móvil y cada vez menos gente tiene ordenadores porque los móviles son más sencillos y requieren menos esfuerzo de uso que los ordenadores tradicionales.)
+
+Entonces viene la pregunta de si, siendo el móvil un dispositivo imprescindible para la vida moderna, todo el mundo debe aprender a manejarlo con responsabilidad para estar protegido.
+
+Yo creo que es mejor si podemos dar a la gente una opción para poder comunicarse por WhatsApp y gestionar su dinero de una manera segura sin tener que dedicar un esfuerzo importante en formación para no correr un peligro real y significativo.
+
+Y en ese punto, creo que las medidas de Google pueden ser útiles y no veo opciones mejores si quiero dar a la gente la opción que acabo de mencionar. Porque me creo que ese bloqueo de un día puede ser altamente efectivo.
+
+Pero que yo defienda estas medidas no quiere decir que esté contento con ellas. Que hayamos llegado hasta aquí es un problema, y que la gente que está dispuesta a aprender a protegerse tenga que aceptar todas las cosas malas que vienen en este paquete me parece terrible.
+
+Porque en efecto, todos estamos prácticamente obligados a usar un dispositivo totalmente controlado por Apple o Google, dos empresas privadas cuyo objetivo es ganar dinero. Y esto es una tragedia por innumerables motivos, tanto obvios como sutiles.
+
+En mi opinión, lo que necesitamos es que todo servicio "vital" se pueda usar sin pasar por el control de ninguna gran empresa privada. Si un sistema de mensajería es importante para vivir en sociedad, debe ser interoperable como es (o debería ser) el correo electrónico. Para usar WhatsApp tengo que usar un dispositivo controlado por Google o Apple y ejecutar en este dispositivo una aplicación controlada por Facebook. Con el correo electrónico (con ciertas notas al pie), puedo usar el dispositivo que me dé la gana, con el programa que me dé la gana y escogiendo el proveedor de servicio que me dé la gana. (E incluso, con más notas al pie, me lo puedo guisar todo yo mismo.)
+
+Si tenemos esto, las restricciones de Google me dan bastante igual, porque creo que bajo estas condiciones, no tendré un teléfono controlado por Google como lo tengo hoy en día, o al menos tendré la opción. Y si no tenemos esto, creo que tener que esperar un día para poder instalar aplicaciones de F-Droid quizá sea más bueno que malo.
diff --git a/blog/content/2026/03/this-was-supposed-to-be-the-future.gmi b/blog/content/2026/03/this-was-supposed-to-be-the-future.gmi
new file mode 100644
index 00000000..fae1036e
--- /dev/null
+++ b/blog/content/2026/03/this-was-supposed-to-be-the-future.gmi
@@ -0,0 +1,27 @@
+# 2026-03-04 This was supposed to be the future
+
+(No sé cuán antigua es una camiseta que creo que todavía conservo con este mensaje. Mucho texto ya es ilegible.)
+
+Estaba oyendo hoy otra cantinela sobre las nuevas maravillas de Apple. Nada nuevo bajo el sol; la gente sigue dándole dinero y elogios a dos manos a Apple, y a mí siguen sin gustarme. He pensado en escribir sobre el tema, pero me he puesto a repasar lo que escribí en 2015 sobre el tema:
+
+=> ../../2015/12/por-que-no-uso-productos-apple Por qué no uso productos Apple
+
+Y me ha perturbado que tendría que cambiar muy poco para ponerlo al día. Sí, ya estoy en una edad donde muy probablemente me queda menos por delante que lo que llevo a mis espaldas, y que por tanto, mi capacidad para corregir mis errores está todavía más mermada, pero si estoy equivocado, me parece cuanto menos curioso que esté equivocado de la misma manera durante más de una década.
+
+Esto me ha llevado a caer en que este mundo que en cada momento nos parece que cada vez va más rápido, quizá sólo esté revolucionando muy rápido sin moverse del sitio. Porque hace un año recordé la que quizá fue la gran revolución informática en mi era, hace un cuarto de siglo:
+
+=> ../../2025/01/los-sistemas-operativos-y-un-amanecer-de-internet Los sistemas operativos y un amanecer de Internet
+
+Alrededor del cambio de milenio fuimos acostumbrándonos a que nuestros ordenadores estuviesen siempre conectados a Internet. Unos años más tarde (muchos lo datarían en 2007; yo creo que fue un poco antes), la conexión a Internet constante comenzó a estar con nosotros incluso lejos de la mesa del ordenador.
+
+Tecleo esto en un ordenador comprado en 2017 que no distingo demasiado del pepino que la semana pasada me pusieron en el curro. Mi BlackBerry de 2011 me parece mejor en algunos aspectos a mi Pixel 9A del año pasado.
+
+Pero lo peor de todo es que la parte de las involuciones ya fue objeto de burla en 2010... ¡porque en 2003 llamaban locos a los que lo veían venir!
+
+=> https://www.explainxkcd.com/wiki/index.php/743 Infrastructures
+
+En los últimos años, claro, es difícil resistir al asedio de lo que muchos dicen que es la nueva revolución. Aunque creo que ya tocaría, veo poco positivo y mucho negativo en el tema del lustro, quizá década.
+
+(Quiero clarificar que me refiero estrictamente a lo mío; por supuesto observo grandísimas innovaciones muchísimo más relevantes que lo que podemos hacer todos en vez de coger un libro.)
+
+¿Soy un señor mayor que no entiende los tiempos modernos? ¿Me estoy perdiendo algo? ¿Cuándo podremos celebrar algo como lo que celebrábamos hace un par de décadas?
diff --git a/blog/content/2026/04/breve-e-incompleta-historia-del-desarrollo-web.gmi b/blog/content/2026/04/breve-e-incompleta-historia-del-desarrollo-web.gmi
new file mode 100644
index 00000000..ed19cb36
--- /dev/null
+++ b/blog/content/2026/04/breve-e-incompleta-historia-del-desarrollo-web.gmi
@@ -0,0 +1,93 @@
+# 2026-04-05 Breve e incompleta historia del desarrollo web
+
+El primer navegador y servidor web aparecieron en 1990, pero hasta 1993 la web era mayormente documentos estáticos; los servidores web tiraban de una carpeta con ficheros HTML con los que se construían las primeras páginas web. Cada vez que ibas a una dirección de la web, veías siempre el mismo documento, que podía contener enlaces a otros documentos.
+
+Es decir, nada de teclear un término de búsqueda en un formulario y obtener un listado de sitios web, ni por supuesto nada muchísimo más completo como poder escribir correo o publicar nada en la web usando sólo un navegador.
+
+(¡Esto no es del todo cierto! WorldWideWeb, el primer navegador, incorporaba un editor de páginas web. Pero sólo servía para editar el sitio web hospedado en el mismo ordenador donde ejecutábamos el navegador.)
+
+Últimamente pienso que nos debíamos haber quedado ahí, pero en 1993 apareció el "Common Gateway Interface", unas siglas bastante inescrutables excepto por el "Interface", con lo que lo dejaremos en CGI a secas.
+
+El CGI permite que un servidor web responda a la petición de un navegador no yendo a buscar un documento HTML dentro del ordenador, sino ejecutando un programa que genere la respuesta.
+
+Si os atrevéis con el terminal y tenéis Python instalado, podéis viajar al pasado siguiendo los siguientes pasos:
+
+1. Cread un directorio vacío.
+
+2. Cread un directorio con el nombre cgi-bin dentro del primer directorio.
+
+3. Cread un archivo con el nombre hola dentro del directorio cgi-bin con el siguiente contenido:
+
+```
+#!/bin/sh
+
+echo Content-type: text/html
+echo
+echo Hoy es $(date)
+```
+
+4. Haced que este archivo sea ejecutable con el siguiente comando:
+
+```
+chmod ugo+x cgi-bin/hola
+```
+
+5. Ejecutad un servidor web apropiado:
+
+```
+python3 -m http.server --cgi
+```
+
+6. Visitad http://0.0.0.0:8000/cgi-bin/hola y comprobad el resultado. Recargad la página varias veces y veréis que se actualiza la fecha, con lo que ya tenéis una página dinámica.
+
+Con este invento relativamente sencillo ya prácticamente podemos llegar a tener gran parte de la web hasta 2004 o así.
+
+El CGI es sencillo, pero algo tedioso. Cuando un programador escribe más de dos o tres programas CGI, se da cuenta de que se repiten los mismos patrones una y otra vez. El ejemplo anterior utiliza el lenguaje shell, pero la historia que conservamos parece indicar que el lenguaje de programación Perl fue de los más usados en los albores del CGI pues era de las maneras más convenientes de reutilizar código para implementar sitios web dinámicos mediante CGI.
+
+Seguramente uno de los primeros módulos para escribir CGI en Perl es CGI.pm, del que la versión más antigua que se conserva en el principal repositorio de código Perl es la 2.10 de 1995.
+
+Perl es un lenguaje de programación de propósito general que apareció en 1987, mucho antes que la web y el CGI.
+
+Allá por 1993, un programador comenzó a escribir un lenguaje de programación con el propósito de implementar su página personal. La primera versión oficial salió en 1997, con el nombre PHP.
+
+A diferencia del CGI, hoy en día es muy complejo reproducir la experiencia exacta de desarrollo de las primeras versiones de PHP, pero si tenéis PHP instalado, podéis hacer algo relativamente similar creando un archivo con el nombre index.php y el siguiente contenido:
+
+```
+<form>
+ <label>a: <input name="a" type="number">
+ <label>b: <input name="b" type="number">
+ <input type="submit">
+</form>
+
+<?php
+ if ($_GET['a'] && $_GET['b']) {
+ echo $_GET['a'] + $_GET['b'];
+ }
+?>
+```
+
+Luego, ejecutad el siguiente comando:
+
+```
+php -S 0.0.0.0:8000
+```
+
+Entonces visitad http://0.0.0.0:8000 con vuestro navegador, introducid dos números en los campos de entrada, pulsad el botón y veréis la suma.
+
+Implementar la misma funcionalidad con CGI, incluso reutilizando código como CGI.pm, es bastante más tedioso y requiere más conocimientos que usar PHP. Por eso el ejemplo que os he puesto de CGI es algo tan inútil.
+
+Yo mismo descubrí PHP por el año 2000 y, como muchísima otra gente, quedé hipnotizado por lo que en el momento era una de las mejores maneras de hacer cosas útiles con un ordenador para otra gente.
+
+A diferencia del CGI, mediante el cual nacieron las webs dinámicas, PHP no trae nada nuevo directamente al usuario de la web, sólo intenta simplificar la vida al programador. Pero facilitando la vida al programador, seguramente PHP aceleró el desarrollo web permitiendo a los programadores traer webs más útiles.
+
+Como muchos sabréis, ni PHP ni Perl han sido el final. Hoy en día, prácticamente todos los lenguajes de programación se usan para desarrollo web, con todo tipo de código reutilizable que cada vez nos aleja más del CGI.
+
+Paralelamente al desarrollo de CGI, PHP y las webs dinámicas, en 1995 apareció el primer navegador con JavaScript. A diferencia de los ejemplos anteriores, donde el código que os he puesto se ejecuta en el servidor web, JavaScript se ejecuta en vuestro navegador. Esto permite otro tipo de interacciones que ejemplificaremos con Google Maps lanzado en 2005, que ya nos permitía desplazarnos por el mapa de una manera mucho más interactiva que lo que nos permite ninguna web dinámica sin JavaScript.
+
+Casi tres décadas más tarde, curiosamente el CGI sigue existiendo pero la mayoría del desarrollo web no tiene casi nada que ver con el de 1995 con PHP y JavaScript. En mi opinión, los ejemplos que os he puesto anteriormente omiten algo de tedio, pero son mayormente representativos de esas maneras de desarrollo, mientras que me marea simplemente pensar en poner un ejemplo mínimo de desarrollo web moderno.
+
+El fenómeno que observamos en mi opinión se repite por todo el ámbito del desarrollo del software: cada vez el paso inicial de desarrollo nos lleva más lejos, pero también es más difícil de abarcar.
+
+Lo que me ha llevado a escribir este artículo es que esta mañana he decidido jugar con una idea que tenía desde hace tiempo en la cabeza, y mi prototipo han sido 100 líneas de Python con WSGI, un descendiente directo del CGI. Para otras ideas sin duda me habría ido a algo mucho más moderno y potente, pero para esta en concreto dudo que hubiese encontrado un camino más corto que las maneras más primitivas del desarrollo web. Pero, ¿habría tomado este camino si me hubiese iniciado en la programación web allá por 2013 con la primera versión de React?
+
+Yo creo que no. Y quizá ni lo hubiese intentado.
diff --git a/blog/content/2026/04/el-enemigo-en-casa.gmi b/blog/content/2026/04/el-enemigo-en-casa.gmi
new file mode 100644
index 00000000..36eb9fa3
--- /dev/null
+++ b/blog/content/2026/04/el-enemigo-en-casa.gmi
@@ -0,0 +1,35 @@
+# 2026-04-08 El enemigo en casa
+
+Allá por 2013 cogí una webcam (diría que una de Playstation) y monté un pequeño sistema de videovigilancia para poder echar un ojo a la gata desde fuera de casa. Un programilla que sabía detectar movimiento y unos cuantos scripts hacían que recibiese un email con un vídeo cuando la gata pasaba delante de la cámara. Fue algo bastante práctico aunque dejé de usarlo en algún momento.
+
+Desde luego no fui un pionero, pero creo que poco después el tema de la domótica se puso muy de moda. No sólo entre la gente más acostumbrada a trastear, sino que además se sumó el público más general, en parte gracias a que comenzaron a aparecer muchos aparatos para estos menesteres con costes más bien asequibles que suponían mucha menos complicación que mi chapuza sujeta a base de chicle.
+
+Pero este boom se vio acompañado de mucha gente obsesionándose con aprender a marchas forzadas temas de seguridad informática para proteger su red doméstica por si estos nuevos y convenientes aparatos resultaban ser malignos. Ni trabajando en una empresa con muchos técnicos en redes había oído mencionar tanto el término vLAN.
+
+La verdad que en su momento tanta paranoia me parecía un poco exagerada. Mi razonamiento era más bien que a pesar de unos cuantos incidentes preocupantes, simplemente bastaría con usar productos de marcas más o menos establecidas con cierta necesidad de mantener su reputación. Es decir, no meter en casa un aparato de quién sabe qué empresa que igual desaparece al mes que viene debería bastar para dormir tranquilo.
+
+(En 2024 me hice con un par de aparatos de este tipo que sigo teniendo conectados y con los que realmente no he tomado muchas precauciones. Pero seleccioné cuidadosamente la marca que elegí, entre otros motivos porque me daba bastante confianza.)
+
+Además, incluso aunque nos colasen un dispositivo malicioso, tampoco me parecía una amenaza tan seria.
+
+Creo que en ese momento mi razonamiento ya no era muy acertado, pero además últimamente hay acontecimientos que me hacen replantearme mucho más mi postura y mis recomendaciones.
+
+Los ataques de denegación de servicio no son algo nuevo; desde hace mucho tiempo hay actores malignos que bombardean servicios de Internet con una avalancha de peticiones que pueden incluso tumbar el servicio y causar muchos problemas a su operador. Sin embargo, hasta hace poco estos ataques tenían más bien pocos objetivos y en general se trataba de objetivos que ya tenían que preocuparse de defenderse ante todo tipo de hostilidades, y en la mayoría de casos, podían disponer de recursos para protegerse.
+
+Sin embargo, en tiempos recientes estos ataques se han expandido significativamente. Incluso servicios muy pequeños hospedados por particulares reciben ataques de este tipo constantemente. Incluso yo mismo he recibido cierta carga que por suerte no ha tenido mayores consecuencias que costarme un par de euros mensuales, pero nada en comparación con lo que veo sufrir a otros.
+
+Es especialmente difícil defenderse de estos ataques; es muy complicado identificar y bloquear el tráfico malicioso, pues proviene de muchísimas conexiones a Internet domésticas.
+
+Que es precisamente lo que se conseguiría controlando una buena cantidad de dispositivos de domótica maliciosos.
+
+(Sí es cierto que no es la única manera de conseguirlo. Hay empresas que ofrecen este tipo de "acceso a Internet", en general porque controlan aplicaciones para móviles "dudosas" y que por tanto pueden canalizar tráfico a través de los dispositivos en los que alguien ha instalado estas aplicaciones.)
+
+Lo curioso del caso es que las precauciones que se pusieron de moda para controlar los dispositivos de domótica en general no serán efectivas para prevenir esto, pues estas medidas se centraban en aislar estos dispositivos para que no pudiesen acceder al resto de nuestra red. Pero para usarlos para lanzar un ataque no hace falta que se conecten a otros dispositivos de nuestra red; basta con que puedan conectarse a Internet.
+
+Y la mayoría de estos dispositivos necesitan conectarse a Internet para ofrecer su modo de funcionamiento "fácil" en los que usan la infraestructura del fabricante en vez de requerirnos mantener nuestra propia infraestructura. (Es decir, en el caso de una cámara, por ejemplo, la cámara va enviando el vídeo al servicio del fabricante donde queda almacenado, y a posteriori nosotros nos conectamos al servicio del fabricante para ver las grabaciones.) Y por otras modernidades, a no ser que el fabricante del aparato lo facilite expresamente, no es tan fácil restringir la conexión a Internet de estos aparatos para que sólo se puedan conectar a lo imprescindible para su funcionamiento y no puedan usarse para lanzar ataques de denegación de servicio distribuidos.
+
+Con lo que yo antes hubiese recomendado despreocuparse un poco del tema, pero ahora me veo obligado a recomendar mucha cautela.
+
+Lamentablemente, la única alternativa segura (aparte de no usar estos dispositivos) sería usar sólo aparatos que no necesiten conexión a Internet para funcionar, pero esto necesariamente implica mucho más trabajo por nuestra parte, e incluso en ocasiones no será viable.
+
+Fuera de eso, sólo puedo insistir en mi consejo de limitarse a fabricantes que tengan más que perder que que ganar participando en actividades maliciosas. Pero dentro de esto seguimos teniendo un riesgo real de facilitar estos ataques y no es fácil mitigar este riesgo.
diff --git a/blog/content/gemini.gmi b/blog/content/gemini.gmi
new file mode 100644
index 00000000..b79340d9
--- /dev/null
+++ b/blog/content/gemini.gmi
@@ -0,0 +1,30 @@
+# Gemini
+
+This is my Gemini start page. I was unhappy with not having synchronized bookmarks in my Gemini clients, until I realized I could just publish a start page.
+
+The links below are Gemini links. You need a Gemini client to open them.
+
+## Aggregators
+
+=> gemini://cosmos.skyjake.fi/ Cosmos
+=> gemini://caracolito.mooo.com/deriva/ bot en deriva
+=> gemini://planet-gemini.fr Planet Gemini Francophonie - Agrégateur de capsules francophone
+
+## Search engines
+
+=> gemini://kennedy.gemi.dev/ Kennedy: Search Gemini Space
+=> gemini://tlgs.one/ TLGS - "Totally Legit" Gemini Search
+=> gemini://cdg.thegonz.net/ Collaborative Directory of Geminispace
+
+## Other stuff of interest
+
+The links below are web links, for those who do not have a Gemini client yet.
+
+### Clients
+
+=> https://gmi.skyjake.fi/lagrange/ Lagrange
+=> https://github.com/makew0rld/amfora Amfora
+
+### Other software
+
+=> https://ñix.es/cgit/alex/coppewebite.git/about/ Coppewebite is what I use to generate and serve this capsule
diff --git a/blog/content/laspelis/1041.gmi b/blog/content/laspelis/1041.gmi
index 5370608c..18744875 100644
--- a/blog/content/laspelis/1041.gmi
+++ b/blog/content/laspelis/1041.gmi
@@ -3,10 +3,11 @@ Date: Sun, 31 Dec 2006 13:49:25 -0000
From: "koalillo" <koalillo@...>
Subject: resumen del 2006
-```
Lo podéis leer en mi blog:
-https://alex.corcoles.net/2006/12/365-1/
+=> ../2006/12/365-1
+
+```
o aquí
Uno no es dado a la retrospectiva, pero visto el aburrimiento y sopor
diff --git a/blog/content/laspelis/1061.gmi b/blog/content/laspelis/1061.gmi
index 72825f65..0d88aab5 100644
--- a/blog/content/laspelis/1061.gmi
+++ b/blog/content/laspelis/1061.gmi
@@ -3,9 +3,9 @@ Date: Tue, 25 Dec 2007 17:45:54 -0000
From: "koalillo" <koalillo@...>
Subject: el 2007 va a dejar de existir
-```
-https://alex.corcoles.net/2007/12/los-ultimos-coletazos/
+=> ../2007/12/los-ultimos-coletazos
+```
Por mucho que diga la biblia, 7 películas no son muchas para el 2007,
pero puestos a hacer un resumen de las pelis de estreno del año, sólo
mencionaremos estas- cabe destacar que 4 de ellas las vi en Sitges.
diff --git a/blog/content/notas/comprar-bajo-en-sodio.gmi b/blog/content/notas/comprar-bajo-en-sodio.gmi
new file mode 100644
index 00000000..9af1e1ea
--- /dev/null
+++ b/blog/content/notas/comprar-bajo-en-sodio.gmi
@@ -0,0 +1,176 @@
+# Comprar bajo en sodio
+
+Es complicado comer una dieta baja en sal. Este documento contiene productos que:
+
+* Podríamos pensar que tienen más cantidad de sal, pero en realidad no tienen tanta. (Intento comer cosas con menos de 1g sal/100g, preferiblemente menos de 0,5g.)
+* Cosas que pese a no tener sal, son más sabrosas de lo que uno esperaría.
+
+DISCLAIMER: No soy médico ni nutricionista. Contrastad todo lo que recomiendo aquí, que no son más que consejos y sugerencias sobre mis experiencias, sin ningún rigor médico. El propósito de esta página es compartir ideas, no dar consejo médico/nutricional.
+
+ATENCIÓN: Listo específicamente el producto preciso y la cantidad de sal aplica solamente a ese producto. Dentro de productos simiares, el contenido en sal puede variar muchísimo. Prestad siempre atención al comprar para revisar la cantidad de sal, que puede no coincidir con la descrita aquí. La sal no es la única fuente de sodio, revisad si lo que coméis lleva otras sustancias con sodio como el glutamato monosódico (o MSG).
+
+## Recursos interesantes
+
+=> https://world.openfoodfacts.org Open Food Facts
+Sorprendentemente, contiene la mayoría de productos que he intentado buscar
+
+## Productos
+
+### Quesos
+
+=> https://www.compraonline.alcampo.es/products/auchan-queso-arz%C3%BAa-ulloa-d-o-p-500-g-producto-alcampo/91158 AUCHAN Queso Arzúa Ulloa D.O.P. 500 g.
+Sal: 0,39/100g
+
+Este queso es el motivo principal para crear este documento. Este tipo de quesos parecen en general bajos en sal, y el de Alcampo tiene especialmente poca. Sin embargo, me gusta mucho (y me hace dudar que la información nutricional sea correcta).
+
+Los quesos tipo tetilla también tienen poca sal, pero más que este.
+
+Burratas
+Sal: Mercadona 0,61/100g
+
+Las burratas también tienen poca sal, y pueden ayudar a dar algo de vida a algún plato.
+
+Mascarpone
+Sal: Mercadona 0,11/100g
+
+El mascarpone puede servir para hacer más cremoso algún plato, sin añadir demasiada sal.
+
+Mercadona - Queso untar light de vaca Hacendado
+Sal: 0,75/100g
+
+El queso de untar light de Mercadona tiene bastante más sal que otros quesos apuntados aquí, pero menos que la mayoría de quesos de untar. Puede ser un capricho ocasional.
+
+### Pan
+
+Mercadona - Piquitos bajos en sal Hacendado
+Sal: 0,22/100g
+
+Para su bajo contenido en sal, los picos bajos en sal de Mercadona son muy sabrosos y pueden servir para picar.
+
+Alcampo - Pan Milagros de molde integral sin corteza
+Sal: 0,76/100g
+
+En general el pan de molde suele llevar bastante sal, aunque hay excepciones.
+
+Tortillas de trigo integrales Auchan
+Sal: 0,88/100g
+
+Las tortillas de trigo suelen llevar más sal, no he encontrado con menos que estas.
+
+### Conservas
+
+Hígado de bacalao ahumado
+Sal: Auchan 0,54/100g
+
+El hígado de bacalao es graso, pero sabroso pese a no tener mucha sal. Puede servir para aderezar un plato.
+
+Atún en aceite bajo en sal
+Sal: Calvo 0,16/100g, Mercadona 0,3/100g
+
+Aunque abuso un poco del atún bajo en sal, sirve para dar un poco de vida a muchos platos. Ojo, que la cantidad de sal puede variar mucho.
+
+Lomos de bonito en aceite
+Sal: Miau 0,59/100g
+
+Los lomos de bonito en aceite, generalmente en tarros de cristal, llevan más sal que el atún en aceite bajo en sal, pero algunos no llevan mucho más y me parecen más sabrosos. Ojo, que la cantidad de sal puede variar mucho (por ejemplo el de Mercadona se va a 0,84/100g).
+
+### Platos preparados
+
+Litoral Fabada asturiana -30% sal y grasa
+Sal: 0,6/100g
+
+Tortilla de patata sin cebolla Auchan
+Sal: 0,91/100g
+
+Carrilera en salsa Carretilla
+Sal: 0.68/100g
+
+Pizza cuatro quesos Auchan
+Sal: 0.9/100g
+
+Pizza mozzarella Auchan
+Sal: 0.83/100g
+
+Aunque los platos preparados suelen tener bastante sal, a veces alguno lleva menos de lo que parece.
+
+### Pasta
+
+Pasta rellena
+Sal: Giovanni Rana ravioli costillas a la barbacoa 0,6/100g
+
+Muchas pastas rellenas tienen bastante sal, pero al haber bastante variedad, a veces nos encontramos sorpresas. No es ideal comer pasta rellena sólo hervida, pero de esta manera podemos reducir nuestro consumo de sal.
+
+### Cereales
+
+Weetabix Crispy Minis Choco
+Sal: 0,16/100g
+
+De los mejores cereales con nutri-score A, y con menos sal que otros (e.g. los Choco Krispies de Kellogg's tienen 0,67/100g de sal). (Nota: recientemente pasaron a tener nutri-score B, aunque la información nutricional no cambió.) Si queremos desayunar cereales, estos nos permiten ahorrar un poco de sodio.
+
+### Patatas
+
+Patatas microondas
+Sal: Mercadona 0,015/100g
+
+Las patatas de microondas se preparan rápido y combinadas con otros productos, pueden arreglar una comida rápida. En general, suelen llevar muy poca sal y están buenas sin añadir más, aunque es recomendable aderezarlas con otro producto sin sal.
+
+### Patatas fritas y snacks
+
+Patatas prefritas congeladas
+Sal: Mercadona Patatas prefritas Waffle fries Lambweston ultracongeladas 0,5/100g
+
+Muchas patatas prefritas congeladas no llevan mucha sal y se pueden comer perfectamente solas.
+
+Patatas fritas
+Sal: Mercadona bajas en sal 0,011/100g, Patatas Fritas en Aceite de Oliva "Arte Fritas" 0.5/100g, Patatas sabor picante Alcampo 0,8/100g
+
+Las patatas fritas sin sal están más buenas de lo que a priori cabría esperar, y pueden ser un aperitivo más que adecuado. Y no son frecuentes, pero algunas patatas fritas llevan menos sal que la mayoría.
+
+Preparados de patata
+Sal: Mercadona patatas bravas con allioli y salsa picante 0,37/100g, Mercadona patatas con allioli 0,6/100g
+
+Aunque llevan más sal que otros productos de esta categoría, siguen teniendo no mucha sal y pueden ser otro aperitivo.
+
+Tortitas
+Sal: Ecocesta 0,5/100g
+
+En general, las tortitas (de arroz, maíz, etc.) *no* son bajas en sal. Sin embargo, se pueden encontrar algunas con menos sal. En el Alcampo que uso, hay una sección con tortitas que todas tienen bastante sal, pero en la sección de alimentos dietéticos tienen las tortitas Ecocesta con menos sal.
+
+Tortolines chifles con sal
+Sal: 0,5/100g
+
+Estos chips de plátano tienen algo menos de sal que la mayoría de snacks salados que encontramos en el supermercado.
+
+### Arroces
+
+Arroz cocido basmati Sabroz Brillante
+Sal: 0,35/100g
+
+Los vasitos de arroz pueden variar bastante en sal, pero los Sabroz no llevan muchísima. Se pueden combinar con otros productos para arreglar una comida rápida.
+
+### Salsas
+
+Mayonesa Calvé sabor casero
+Sal: 0,73/100g
+
+La mayoría de mayonesas tienen bastante sal, pero hay alguna excepción.
+
+Patak's Tikka Masala
+Sal: 0,72/100g
+
+Una salsa india con una cantidad de sal moderada que puede aderezar arroz o carne.
+
+Alioli Prima
+Sal: 0,72/100g
+
+El alioli Prima no es particularmente bueno, pero no he encontrado otro allioli que no tenga mucha más sal.
+
+Nacho Cheese Doritos
+Sal: 0,9/100g
+
+Salsa guacamole Old El Paso
+Sal: 0,8/100g
+
+### Especias
+
+Aunque en general no he encontrado especias que compensen comer sin sal, el curry es de lo que se acerca más.
diff --git a/blog/content/notas/ficcion/conmutatividad.gmi b/blog/content/notas/ficcion/conmutatividad.gmi
new file mode 100644
index 00000000..c1cd6671
--- /dev/null
+++ b/blog/content/notas/ficcion/conmutatividad.gmi
@@ -0,0 +1,73 @@
+# Conmutatividad
+
+## 1.
+
+Era tarde y el bar de la planta estaba prácticamente vacío. El barman limpiaba vasos tranquilamente mientras un par de grupillos hablaba distendidamente.
+
+Un tipo corpulento entró de repente con demasiados ánimos para un ambiente tan apaciguado. Buscaba alguien con quien hablar y le tocó a un hombre mayor- según el identificador de su mono, un tal J. SMITH. El otro, R. WAGNER tampoco reparó mucho en detalles; se sentó casi sin mirarle y empezó a hablarle.
+
+Si le hubiese mirado, habría visto una cara cansada; toda personalidad había sido erosionada por el trabajo en la mina. Los ojos daban una inquietante sensación de vacío. Quizá no se hubiera sentado si le hubiese observado detenidamente.
+
+-¿Menuda cosa esta, eh? Picas piedra en la mina un tiempo y te dejan hacer lo que quieras. ¿Quieres meterte lo que sea? Un par de añitos y andando. La leche.
+
+El tratado Koslov. La radioactividad de la maldita luna habia subido tanto y estaban tan alejados de cualquier base que no había otra. A trabajar la mina a destajo y tirar el material radioactivo al espacio o todos con tumores como balones de fútbol en pocos años. Pero claro, nadie quería dejarse la salud y la vida en los túneles.
+
+Primero enrolaron a los presos, pero no había suficientes. Entonces el gobernador Koslov tuvo la brillante idea de que si los condenados podían conmutar sus penas por trabajo en la mina tras el delito... ¿por qué no conmutar antes de delinquir? Quizás habría gente que trabajaría por poder cometer un delito impunemente. Así pues, se retoca un poco el código penal, se endurecen las penas un poco y ya tienes mineros. Un éxito total.
+
+-Tío, cuando cumpla mi tiempo aquí me voy a meter de todo y voy a hacer lo que me dé la gana. ¡Y me darán una palmadita en la espalda!
+
+El viejo miró el cartel detrás de la barra.
+
+ROBO CON VIOLENCIA …................. 3 años
+
+-¿Tú qué vas a hacer, viejo? ¿Follarte a una jovencita?
+
+El viejo le clavo la mirada unos instantes y el otro aparto los ojos un poco de inmediato.
+
+-¿Cuántos años llevas aquí, viejo?- dijo más cuidadosamente
+
+-45 años
+
+Leyó otra línea, se la sabía casi de memoria ya
+
+AGRESIÓN CON DAÑOS CORPORALES GRAVES ….......... 15 años
+
+-Joder- musitó
+
+El hombre grande se giró y leyó lentamente la tabla
+
+HOMICIDIO EN PRIMER GRADO ….............. 45 años
+
+-Joder, ¿qué vas a hacer?
+
+-No lo he pensado
+
+## 2.
+
+-¿Te has enterado de lo del tío que se encontraron muerto anoche en su habitación?
+
+-¿Qué tío?
+
+-¿John Smith, no te suena?
+
+Los dos guardias miraban las cámaras de seguridad mientras charlaban
+
+-Llevaba 45 años picando piedra. Coge, hace el papeleo para conmutar y la palma de viejo esa misma noche. Ataque al corazón, dicen.
+
+-Menudo palo
+
+-Sí, tío. Pero no sabes lo mejor. El tío no quería conmutar para él. Quería sacar a otro de la cárcel.
+
+-¿Y eso?
+
+-Nadie lo sabe. Hasta hizo el papeleo. El otro saldrá, pero ni podrá darle las gracias.
+
+-Joder. Te pasas 45 años ahí abajo, te dejas tu vida ahí... y no puedes ver lo que te has trabajado. Vaya mierda. Al menos el otro saldrá.
+
+## 3.
+
+-El jurado condena a Wolfgang Kauffman a cadena perpetua por el asesinato del pequeño Sebastian Smith, con los agravantes de indefensión y ensañamiento. Cumplirá su condena en el penal de máxima seguridad de Weinholtz.
+
+Jacob Smith no cambió el gesto en ningún momento del juicio. El pequeño Sebastian ya no estaba y para él, su vida estaba rota. Ni siquiera podía tocar a Wolfgang, ni mucho menos tomarse la venganza que tanto deseaba y que le hacía arder las entrañas.
+
+Wolfgang era intocable, al menos de momento, y eso le estaba matando lentamente.
diff --git a/blog/content/notas/ficcion/cuentos-del-triangulo-verde.gmi b/blog/content/notas/ficcion/cuentos-del-triangulo-verde.gmi
new file mode 100644
index 00000000..3d37bfaa
--- /dev/null
+++ b/blog/content/notas/ficcion/cuentos-del-triangulo-verde.gmi
@@ -0,0 +1,133 @@
+# Cuentos del Triángulo Verde
+
+## 1.
+
+Nadie recordaba ya nada de la antigua civilización, pero Grub estaba bastante seguro de que el templo de suministros había sido uno de sus pilares. Entre polvo y escombros, el templo se alzaba majestuoso desafiando al sol y a las tormentas de arena.
+
+Su tribu anhelaba los extraños artefactos que atesoraba, pero muchos de sus guerreros habían sido diezmados intentando asaltarlo o interceptando los convoys fuertemente armados que lo abastecían periódicamente.
+
+Recordaba el salvoconducto que había encontrado su abuelo cuando Grub era apenas un cachorro. El esqueleto se aferraba a su posesión más valiosa, pero apenas un tirón bastó para arrancarle el pequeño rectángulo plastificado. Casi no pudo contener la emoción cuando su abuelo se lo enseñó al guardia y éste les invitó a entrar.
+
+No sabían qué magia iluminaba el lugar, ni qué extraña fuerza impulsaba las vías a las plantas superiores, ni de dónde salía ese frescor que al principio te hacía olvidar el infierno exterior, pero que luego te helaba hasta los huesos.
+
+Pasaron varias horas recogiendo tesoros, que los propios guardias les colocaban en alforjas de plástico simplemente presentando el salvoconducto.
+
+El día acabó cuando un guardia se quedó con el salvoconducto a cambio del último artefacto y les escoltó hacia la puerta, pero fue una jornada gloriosa de la cual seguían hablando cada noche al caer el sol, aunque ni siquiera eran capaces de comprender su botín.
+
+Esos borrosos recuerdos emergían en la mente de Grub mientras se dirigía al templo. Como explorador, le correspondía introducirse e interpretar los auspicios regularmente. Esto era más complicado de lo que parecía e infinitamente más peligroso. Habían descubierto que la actitud exacta, con un preciso equilibrio de interés y desinterés, podía mantener a los guardias a raya. Si no mirabas lo suficiente, te conducían a empujones hasta la entrada. Pero si demostrabas mucho interés por un artefacto, tu destino era mucho peor. El guardia se acercaba y entablaba conversación. Nadie conocía el lenguaje ni las encantaciones apropiadas, sólo arrodillarse y ofrecerles un salvoconducto los apaciguaba. Nunca descubrieron qué hacían con los cadáveres.
+
+Grub deambulaba entre las estanterías. De vez en cuando añadía su toque personal, cogía algo y hacía ver que interpretaba sus escrituras, mientras controlaba al guardia por el rabillo del ojo. Esto parecía satisfacerles.
+
+Las miradas de los guardias eran cada vez más insistentes y cuando Grub estaba a punto de dar por concluida su incursión, lo vio. Cayó de rodillas donde se encontraba. Su padre le había enseñado a interpretar los cuatro auspicios, igual que su padre antes que él, y aquel era el peor de todos.
+
+El árbol de frutos redondos y brillantes, el hombre de rojo y los abrigos de animales.
+
+En dos o tres lunas nuevas, llegaría el frío y la desolación. Su abuelo le había explicado cómo el anterior invierno prácticamente acabó con ellos. Grub escuchó una voz, pero no supo interpretarla. Sus sollozos acabaron de ahogar la locución mística y la tétrica melodía.
+
+«Ya es Navidad en El Corte Inglés.»
+
+## 2.
+
+—No lo queremos.
+
+—¿Cómo?
+
+—Que no lo queremos.
+
+El robot se encogió de hombros. No era algo habitual, pero esto había excedido su programación.
+
+—Tendrán que hablar con mi supervisor.
+
+Eva y Lucas se acomodaron en sus asientos.
+
+—De acuerdo.
+
+El robot se levantó, dio la vuelta, se dirigió al hombre del despacho y le explicó todo. Antes de salir a hablar con ellos, el supervisor convirtió su cara de sorpresa en su mejor sonrisa.
+
+—Buenos días. RA21 me ha comentado su caso y creo que no le he entendido del todo bien.
+
+—Que queremos devolverlo.
+
+—Ya —enterró la vista en los papeles que había en la mesa—. Pero veo que no tiene ningún problema, ningún defecto de fábrica.
+
+—Eso es técnicamente cierto, desde luego —dijo ella.
+
+—Pero queremos devolverlo —dijo él.
+
+—No lo comprendo.
+
+—No forma parte de su… ¿política?
+
+—Sé lo que quieren decir, pero esto es del todo irregular. Cubrimos los defectos de fabricación, pero…
+
+—Pero es que no nos gusta. Es un… pesado.
+
+—Y un cabroncete.
+
+—¿Cómo? —A pesar de su amplia experiencia, no pudo evitar la sorpresa. Se recompuso rápido.
+
+—Mire, al principio éramos comprensivos. No nos dejaba dormir, pero… pensábamos que era normal. Pero iba pasando el tiempo y no mejoraba.
+
+—Lo que mi mujer quiere decir… pues sí, crecía con normalidad, dentro de lo esperado. Pero…
+
+—Es un gamberro. Y no para de tocarnos las narices.
+
+El supervisor, bajo una mueca de atención absoluta, no daba crédito. En un mundo saturado de contaminación, la tecnología que los chicos del supermercado habían inventado no sólo producía unos filetes excelentes, sino que resultó ser la mejor manera de tener hijos sanos y perfectos, completamente libres de la plaga de las mutaciones. Buscando atender todas las necesidades de sus clientes, abrieron el departamento de reproducción asistida hacía apenas seis años.
+
+—Pero todo esto son criterios subjetivos. El niño no presenta ninguna mutación. Su ADN es —Alzó los papeles y les enseñó los marcadores— completamente armonioso. El fenotipo... admitirán que el parecido es notable.
+
+—Sí, pero el crío es un maldito caprichoso e insoportable.
+
+—Debe disculparla, ayer volvieron a expulsarle del centro educativo. Es que no hay manera.
+
+—Mire, nos da igual el dinero. Sólo queremos que… que se lo queden. Ustedes siempre insisten en eso, ¿no?
+
+El supervisor suspiró sonoramente. «La política que ha sobrevivido una guerra nuclear», pensó. Entonó la letanía con resignación.
+
+«Si no quedan satisfechos, les devolvemos su dinero.»
+
+## 3.
+
+Se sentó delante del ordenador. Era un tipo bajito, algo barrigón y bastante calvo. Sudaba.
+
+Abrió el navegador e introdujo la dirección.
+
+«Instalando el plugin Mindterest 3.5 para una perfecta experiencia de compra», decía la pantalla, mientras el hipnótico círculo giraba en su danza infinita.
+
+Golpeteó nerviosamente el ratón.
+
+La página cargó, con el habitual listado de categorías. Vio la muchacha tridimensional en la parte derecha de la pantalla. «Haga clic aquí si desea saber más sobre su nueva experiencia de compra.» Era bastante atractiva, pensó, y le echaba una mirada inquisitiva. Sonrió levemente.
+
+«Me temo que no ofrecemos ese tipo de servicios.» Había desaprobación en ese cuadro de texto.
+
+Enrojeció levemente. Clic, clic, cancelar.
+
+«En nuestra sección de psicología encontrará títulos como ‘Superar el ridículo’ y ‘Conteniendo sus deseos’, haga clic en los títulos para más información.»
+
+Una gota de sudor recorrió su frente. Clic, clic, cancelar.
+
+Se echó una ojeada rápida, avergonzado.
+
+«El departamento de alimentación tiene una amplia selección de comida dietética preparada por nuestros especialistas en nutrición.”
+
+CLIC, CLIC…
+
+«... programas de ejercicios...», los popups emergían más rápido de lo que podía cerrarlos.
+
+¡CANCELAR!
+
+Joder con el plugin, era peor que el Flash de los antepasados. Su vida era una mierda, pero no necesitaba que un avatar impoluto se lo recordase.
+
+«Quizás podrían interesarle nuestros nuevos servicios de psicología, haga clic aquí para obtener detalles.»
+
+Alzó una ceja. En aquel momento tampoco le pareció tan mala idea. Quizás le haría bien.
+
+Clic, clic.
+
+La página cargó lentamente. Sin pensarlo, se desplazó hasta la parte inferior para ver los precios. «Puf, prohibitivos», pensó, y vio su desilusión reflejada en la pantalla.
+
+«En el supermercado encontrará una promoción 3x2 en cuchillas de afeitar. Bueno, en realidad sólo necesitará una…»
+
+Reparó con resignación en el eslogan en el pie de la página y se quedó mirando al infinito.
+
+«Especialistas en ti.»
diff --git a/blog/content/notas/ficcion/el-principe.gmi b/blog/content/notas/ficcion/el-principe.gmi
new file mode 100644
index 00000000..f1db64a9
--- /dev/null
+++ b/blog/content/notas/ficcion/el-principe.gmi
@@ -0,0 +1,65 @@
+# El príncipe, el rey y el verdadero mal
+
+No paraba de darle vueltas en su cabeza. Faltaban tres días y él, del que se decía que tenía recursos para todo, aún no lo había conseguido. Su gato le observaba aburrido desde lo alto del armario, sus ojos brillantes como carbones al rojo. No le quedaba otra, iría mañana mismo y sellaría el trato.
+
+Se despertó por la mañana tras sueños angustiosos. Su gato seguía dormido a sus pies. Tras sus rituales matutinos y enfundarse en sus mejores galas, salió al mundo exterior.
+
+Después de un corto trayecto de metro, salió a la calle. En la distancia, el gigante de cristal y hormigón se alzaba sobre otros edificios de menor importancia. Un poco más de curvatura en esos enormes ventanales y la convección convertiría el interior en una enorme caldera. Deformación profesional, pensó, y una pícara sonrisa se le dibujó en los labios.
+
+Al entrar, la fastuosa decoración marmórea le recordó a sus propias oficinas. En el centro, Laocoonte y sus hijos, una de sus esculturas favoritas. Siempre pensaba en las almas atrapadas para toda la eternidad en la piedra, forcejeando inmóviles sin poder separarse de sus enemigos. De repente, se dio cuenta que la cola había crecido y se apresuró a ponerse al final.
+
+En la cola, los problemas de los mortales eran los de siempre. Desde los romanos y la sal, muchos de ellos se habían vuelto simples guarismos y le aburrían. Otros se ocupaban de torturar a las almas por cifras.
+
+Estos pensamientos entretuvieron su mente hasta que alcanzó la caja. Recorrió con su mirada a la cajera y un escalofrío la recorrió a ella.
+
+—Deseo hablar con Emilio.
+
+—Me temo que no atiende visitas, pero créame, podré atenderle en lo que usted necesite.
+
+Se lo explicó. Se lo explicó de nuevo.
+
+—Sí, espere un momento. Le avisaré y le atenderá enseguida.
+
+Esperó un poco más. Siempre esperar. Ellos, con sus vidas cortas, no parecían entender el drama de las pérdidas de tiempo. Tenía un círculo especial para los impuntuales y demás escoria.
+
+Finalmente, le condujeron a lo largo de infinidad de pasillos hasta las entrañas de la criatura. Entró y allí estaba, diminuto y perdido en su gran silla. Cabe decir que no era un despacho particularmente grande ni ostentoso, pero había pequeñas muestras de poder por todas partes. También había un desorden que le hería en lo más profundo. Él llevaba sus asuntos como un reloj, el caos no tenía lugar en los negocios.
+
+Finalmente el hombrecillo alzó la vista de los papeles.
+
+—Pues mire, cuando mi padre me legó el banco y por extensión esta oficina, se sentó conmigo y me enseñó esos contratos.
+
+Se dirigió a uno de los armarios de su oficina, se subió a un taburete y cogió una carpeta que había encima. La sacudió un poco para quitarle el polvo y la llevó a la mesa.
+
+—Yo pensaba que era una especie de broma, una tradición gótica de banqueros. Cuando mi padre murió los cogí y los volví a leer, pasé una tarde muy amena.
+
+Un cordel deshilachado aprisionaba el papel amarillento. Tuvo ciertas dificultades con el nudo, pero al final los documentos quedaron libres.
+
+—¡Ah! Éste es.
+
+Lo colocó ante él.
+
+—Verá que es un contrato bastante estándar, a pesar de la temática. Las cláusulas son un tanto arcaicas, pero sospecho que no serán problema para usted.
+
+Una pequeña funda rígida cilíndrica dentro de su abrigo contenía sus gafas, que pronto reposaron sobre su nariz aguileña. Las bifocales le hacían parecer mucho más viejo.
+
+—Creo que está todo en orden.
+
+Armado con una pluma ornamentada con sutiles incrustaciones de rubí, se enfrentó al blanco. Bajo el epígrafe “objeto del trueque” rasgó delicadamente “Entradas para el partido Foot-Ball Club Barcelona, Madrid Football Club que se disputará el domingo 14 de abril de 2013 en el estadio Nuevo Chamartín en la Avenida de la Concha Espina 1, Madrid, España”.
+
+—Pues ahora nos quedaría la firma.
+
+Se diría que el cielo ennegreció justo cuando se puso firme en el centro del despacho.
+
+—Yo, Lucifer, Padre de la Mentira, Dios de Este Siglo y Príncipe de las Tinieblas, declaro que, en plena posesión de mis facultades mentales, canjeo mi alma inmortal con Banco Martínez y Asociados, por una entrada a un partido de fútbol, y para que conste, firmo con mi sangre este contrato.
+
+Un abrecartas del escritorio le sirvió para realizar una pequeña punción en su dedo índice. Un par de ágiles movimientos y el líquido rojo oscuro hirvió sobre el papel, dejando escrito su nombre con impecable caligrafía.
+
+El director notó el temblor de su mano al tomar el contrato. Lo examinó cuidadosamente e imprimió su sello. No sin cierta ceremonia, lo archivó como si fuese un bebé en una brillante funda roja carmesí.
+
+—Todo en orden, si viene usted mañana y se identifica con el DNI, cualquiera de nuestros cajeros podrá entregarle las localidades.
+
+--------------
+
+Un jugador del Barça hizo una rápida internada por la banda derecha driblando a un defensa. El líbero acudió a cubrir la marca con velocidad, pero le alcanzó en falta justo en el borde del área. Cien mil voces desgarradas alzaban su voz ante la peor de las injusticias.
+
+Un rostro inexpresivo contemplaba el espectáculo. Sus ojos recorrían ausentes la arena de los gladiadores, ahora incapaces de encontrar lo que buscaban. Finalmente, desistió. Extrajo el estilizadísimo móvil de las profundidades de su abrigo y se dejó hipnotizar por las luces de un jueguecito endiablado.
diff --git a/blog/content/notas/ficcion/en-los-mejores-cines.gmi b/blog/content/notas/ficcion/en-los-mejores-cines.gmi
new file mode 100644
index 00000000..dcb32f3a
--- /dev/null
+++ b/blog/content/notas/ficcion/en-los-mejores-cines.gmi
@@ -0,0 +1,57 @@
+# En los mejores cines
+
+Fred se sentó en la cómoda butaca con sus palomitas. Una ligera brisa le cosquilleaba la nuca mientras se acomodaba y colocaba todo en su sitio. Al poco, se apagaron las luces y una sonrisa apareció en su cara.
+
+POR FAVOR, FIJE LA VISTA EN EL PUNTO BLANCO EN EL CENTRO DE LA PANTALLA
+
+PROCEDEREMOS A BORRAR SUS RECUERDOS DE LA PELÍCULA EN 10 SEGUNDOS PARA QUE LA PUEDA DISFRUTAR DE NUEVO
+
+SI NOTA MAREO O SOMNOLENCIA, POR FAVOR, PULSE EL BOTÓN ROJO EN EL REPOSABRAZOS
+
+Era 2127, y el borrado selectivo de recuerdos había resucitado la industria del cine. Ante la crisis de ideas y la sensación de que todo había sido rodado ya, a un productor se le ocurrió utilizar un curioso avance de neurociencia- inútil para el público en general y para el que sólo se habían encontrado usos oscuros- para permitir que a la gente no le importase la falta de originalidad del cine. Podían ver la misma película repetidamente y cada vez la disfrutaban como la primera vez.
+
+Pese a las reticencias iniciales, el público comprendió rápidamente que era mejor esto que ver la enésima secuela que conservar su cerebelo intacto.
+
+La estrategia tuvo tanto éxito que en breve, cesó la producción de cine nuevo. Años más tarde, incluso, se comprobó que los cines del mundo apenas daban un centenar de películas diferentes- y curiosamente aquellas cuyos derechos de exhibición habían caducado hace tiempo.
+
+Fred se relajó. Los Caballeros de la Mesa Cuadrada. Si no le fallaban las cuentas, ya la había visto 137 veces. Y siempre acababa con dolor en la barriga de tanto reír. Se echó atrás y se dispuso para las carcajadas.
+
+# 2.
+
+Fred estaba perplejo. Tenía una mueca inexpresiva en la cara, mientras la gente alrededor aún reía o, como mínimo, tenía una expresión risueña y felicidad.
+
+Pero él no se había reído.
+
+Nada.
+
+¿Cómo podía ser? Recordaba haberse reído las 136 veces anteriores. Era una de sus favoritas. Era infalible en quitarle sus preocupaciones.
+
+Fred se incorporó. La verdad es que estaba un poco cabreado. Se dirigió a la taquilla mientras la gente comentaba la jugada a su alrededor.
+
+-No me he reído
+
+-Bueno, -respondió la muchacha distraída- no hace reír a todo el mundo, ya...
+
+-¡Pero la he visto muchas veces!- le interrumpió
+
+-¿Cómo?
+
+-Siempre me hace gracia. Es la mejor comedia que hay. La he visto mil veces
+
+La muchacha se le quedó mirando. Parece que esto no entraba en su guión.
+
+-Lo lamento señor, pero no puedo hacer nada
+
+-¡Devuélvame mi dinero!
+
+-No puede ser. Nadie se ha quejado de la proyección, ni del borrado, ni... nada, en realidad
+
+-¡Pero no me ha gustado!
+
+-Me temo que nunca se ha devuelto el precio de una entrada porque la película no ha gustado. Además, a todo el mundo le gustan los Monty Python...
+
+Fred se indigno. Quería decir algo- y abrió la boca para decirlo, pero no supo qué decir.
+
+-Si quiere puede presentar una reclamación
+
+-Da igual. Muchas gracias, señorita.
diff --git a/blog/content/notas/ficcion/invoco-al-diablo.gmi b/blog/content/notas/ficcion/invoco-al-diablo.gmi
new file mode 100644
index 00000000..3427bc57
--- /dev/null
+++ b/blog/content/notas/ficcion/invoco-al-diablo.gmi
@@ -0,0 +1,121 @@
+# Invocó al diablo
+
+## y lo que sucedió a continuación te sorprenderá
+
+--Tía, que no lo veo nada claro
+
+--Que sí, que para qué quieres el alma, eso es algo de boomers
+
+--No me convence, que lo vi en una serie y es algo chungo
+
+--¿Pero tú quieres ir a ver el concierto o no?
+
+--Bueno, ¿pues cómo lo hacemos?
+
+--Busquemos en Youtube
+
+--¿Como ves este? “Los curas lo odian: invoca a Satanás con este extraño truco”
+
+--No sé. A mi me sale “Como vender el alma al Diablo con productos del Mercadona”
+
+--¡Ah! Pues ese, que lo tenemos aquí al lado y aún tardarán en cerrar
+
+------------------------------------------
+
+Miró el móvil. Un formulario AAD-35. No lo había visto nunca. Tuvo que consultar el manual, llevaba pocos siglos allí y no había tenido que tratar con ese nunca. Guardó el móvil, se levantó, se subió los pantalones y tiró de la cadena. Siempre le invocaban cuando estaba en el retrete.
+
+------------------------------------------
+
+--¿Has oído eso? ¿Quién hay en el baño?
+
+--Joer, qué mal rollo. Ve a mirar, anda
+
+--¿Yo? Es tu casa
+
+(Lejano) --Ya voy, paciencia, narices
+
+------------------------------------------
+
+--Bueno, pues ya me tenéis aquí
+
+--¿Usted es el diablo?
+
+--Hombre, pues no. Joer, ¿pensabais que os iba a atender el jefe? Cuando vais a pedir una tarjeta, ¿esperáis que os atienda el Botín?
+
+--Ya, bueno, pero entonces, ¿puedes ocuparte tú?
+
+--Sí, qué pasa, que porque soy joven no puedo asumir responsabilidades
+
+--Bueno, no te pongas así. A ver, ¿cómo va esto?
+
+--Pues nada, ¿qué me ofrecéis?
+
+--¿Que qué te ofrecemos? ¿Será que qué te pedimos, no?
+
+--¿Perdón?
+
+--Queremos unas entradas para el concierto
+
+--¿Qué?
+
+--Unas entradas. Son un trozo de papel, lo das al segurata y te deja entrar
+
+--Creo que os estáis liando. A ver, me ha llegado un AAD-35. Queréis comprarle el alma al diablo. Atípico, pero puede hacerse
+
+--No, no, queríamos *vender* nuestra alma al diablo.
+
+Suspiró
+
+--Déjame adivinar: la loca esa fanática del Deliplus, ¿no? Joer, me lo habían contado los del turno de mañana y no me lo creía. Crédulos humanos, os lo ponen en Youtube y no sabéis salir de ahí
+
+--Oiga, sin faltar, ¿eh?
+
+--Mira bonita, ¿queréis el alma del diablo o qué? ¿Qué dais a cambio?
+
+--Que no queremos eso, ¿pa qué sirve? Eso luego se va a un desván y luego no lo usas para nada
+
+--Malditas millenials… Mira, yo me las piro que tengo cosas que hacer. Agur
+
+------------------------------------------
+
+Tía, no avises al jefe, porfa. Que llevo poco tiempo aquí y no me va mal. Venga, si no le dices nada, te consigo un par de entradas para el concierto de Rosalía, ¿vale?
+
+------------------------------------------
+
+Pulsa el icono de la ruedecita 6 veces. Debería salirte la cabrita. ¿Te sale? Vale, ahora le das 6 vueltas. Muy bien, ahora te salen la parrafada esa, saltas al final y le das a aceptar.
+
+------------------------------------------
+
+Sí, mira, si entras por nuestra página de Facebook te viene un Lucifer más… de padres, ¿vale? Pero por Insta y Snapchat pues nos envían a nosotros.
+
+------------------------------------------
+
+(el diablo becario cogiendo el teléfono) No se moleste, que esto es un móvil de empresa y no puedo cambiarme de operadora. Ah, coño, perdona. Sí, sí, es aquí
+
+------------------------------------------
+
+---A ver, he encontrado unos cuantos yutus del tema.
+
+---Pero pilla uno que vaya con Android, ¿eh?
+
+---¿Qué te parece este? “Los curas lo odian: invoca a Satanás con este truco raro”
+
+---No sé, Rick, parece falso
+
+------------------------------------------
+
+No olvidéis suscribiros a nuestro canal de Youtube y darle al like. ¿Habéis probado nuestros filtros?
+
+------------------------------------------
+
+Oye, ¿nos podemos ir p’adentro? Aquí fuera hace un frío de cojones y yo estoy más acostumbrada a las calderitas hirviendo y todo eso.
+
+------------------------------------------
+
+Bueno, vuélvemelo a explicar. Que me he dormido con la nota de voz de 10 minutos.
+
+------------------------------------------
+
+---¡Que vuelvan las Spice!
+---No me jodas
+---Na, es coña
diff --git a/blog/content/notas/ficcion/lucifer-martinez.gmi b/blog/content/notas/ficcion/lucifer-martinez.gmi
new file mode 100644
index 00000000..d410f065
--- /dev/null
+++ b/blog/content/notas/ficcion/lucifer-martinez.gmi
@@ -0,0 +1,77 @@
+# Lucifer Martínez
+
+Como casi cada tarde, Lucifer Martínez apagó su ordenador a las 18:00, se despidió de sus compañeros de trabajo y caminó el corto trecho hasta la estación de tren de Móstoles.
+
+El tren no estaba exageradamente lleno y pudo coger sitio con ventanilla, su favorito. Apoyo la cabeza en el cristal y dejó que su mente divagase. El negocio iba bien, viento en popa, casi demasiado bien se decía. Había cancelado la campaña de regalar el nuevo iPhone a cambio de tu alma inmortal. Era demasiado fácil, pensaba. En esta época, su trabajo carecía de creatividad, de emoción. Antes los hombres eran de otra manera.
+
+La gente de la oficina le apreciaba. Era un buen jefe. No como Dios. Lucifer no entendía como había llegado tan lejos. Con la coña de que había que dejar que el rebaño se pastorease solo, pasaba de todo. Él había entrevistado personalmente a todos sus empleados y lo sabía todo sobre ellos (deformación profesional). Con el Todopoderoso todo eran cuadros intermedios, burocracia infinita… como todas las grandes empresas, al final nadie daba un palo al agua, pero daba igual, la inercia llevaba a la empresa adelante.
+
+[...]
+
+Dejó el abrigo en el colgador.
+
+-¿Cariño, ya estás aquí? Espera que salgo…
+
+Una mujer espectacular salió del baño. Su larga melena empapada no osaba cubrir sus más que generosos atributos. Cualquier hombre hubiese traicionado a su patria por esas piernas gloriosas.
+
+-¡Mamá! ¿No podrías tener un poco de pudor de cuando en cuando?
+
+-Joder, hijo, siempre igual. Parece mentira que siendo quien eres sigas con estas pamplinas puritanas.
+
+-¡Pero es que no puedes ir en pelotas por casa siempre, por Dios! Las madres normales no van por ahí enseñando las domingas a sus hijos.
+
+-Mira, hablando de eso. Mi profe de Zumba va a venir a casa- miró el reloj- en 10 minutos. ¿No podrías irte a dar una vuelta?
+
+Lucifer frunció el ceño. Siempre igual. Cogió el abrigo muy lentamente y se dirigió a la puerta.
+
+-¡No te pongas así, hombre! Por cierto, te he dejado un tupper en la nevera para mañana, no te olvides de cogerlo.
+
+Refunfuñó algo y cerró la puerta. Al salir del ascensor se topó con el que sospechaba era el profe de Zumba. Era enorme y llevaba una enorme sonrisa de oreja a oreja. Lucifer agachó la cabeza e intentó mantener todas esas imágenes de su madre con ese maromo de la cabeza, sin demasiado éxito.
+
+Se metió en el bar de la esquina. Allí se sentía cómodo, y dados los hábitos de su madre, pasaba allí casi tanto tiempo como en su casa. Sabía que tenía que buscarse otro sitio, pero tal como están los pisos, tampoco podía permitirse muchas maravillas.
+
+-Hombre, Luci… ¿una cervecita?
+
+-Claro que sí, Paco, muchas gracias.
+
+El dueño era un tipo majo. Llevaba ahí cuarenta años y sabía perfectamente cómo tratar a su clientela. En este caso, sabía que no tenía que hablarle de su santa madre.
+
+[...]
+
+Se había tomado un par de cervecitas más de las que tocaba y seguramente hubiese tenido que irse para casa, pero no quería arriesgarse a que el profesor de Zumba siguiese allí. Seguramente les hubiese oído nada más salir del ascensor, pero eso ya era demasiado para él.
+
+Se puso andar. La cerveza le estaba llevando a una fase eufórica y sus pasos tenían cada vez más energía. Sabía que no tenía que ir allí, pero en su alterado estado mental, tenía ganas de juerga.
+
+Era una caminata de lo menos veinte minutos, hacía la zona buena. Al llegar, miró al séptimo piso. Había luz y parecía haber una fiesta. Se puso a gritar.
+
+-¡¡¡Ehhhh, Todopoderoooosooooo!!!
+
+-¡¡Baja a hablar con tu colegaaaaaa!!
+
+Estuvo así un rato, sin obtener resultado alguno.
+
+-¡¡¡Capulloooooo!!! ¡Montando una fiesta de Navidad! ¡¡¡Que crucificaron a tu hijooooooo!!!
+
+Se abrió una ventana. Le pareció ver a alguien encogerse de hombro y volver a meterse. Se sentó en un bordillo.
+
+Al cabo de un rato, bajó y se sentó a su lado.
+
+-Feliz navidad
+
+-Sí tíiio, feliz navidad
+
+-¿Qué te trae por aquí? No me lo digas- se apartó un poco para evitar el hálito alcohólico.
+
+-¿Por qué tío? ¿Por qué eres así?
+
+-A mi qué me cuentas. Yo soy como soy.
+
+-Eres un mierdas. Tú lo arreglas todo siempre así. Este es mi garito y me meo dentro si me apetece. Pues lo tienes hecho una mierda.- se le envidriaron un poco los ojos
+
+-Venga hombre, es Navidad. Súbete. Hay cordero asado.
+
+Le pasó la mano por el hombro. Joder, siempre le funcionaba ese truco. Lucifer le miró a los ojos y rompió a llorar.
+
+-Venga, venga. No pasa nada. Tú también eres como eres. Y no hay nada que te guste más que el cordero asado. Te irá bien.
+
+Le ayudó a levantarse y desaparecieron por el umbral de la puerta.
diff --git a/blog/content/notas/ficcion/maldito-clip.gmi b/blog/content/notas/ficcion/maldito-clip.gmi
new file mode 100644
index 00000000..648ef923
--- /dev/null
+++ b/blog/content/notas/ficcion/maldito-clip.gmi
@@ -0,0 +1,73 @@
+# Maldito clip
+
+En una habitación de joven, a oscuras, EL JOVEN BILL GATES teclea furiosamente. De repente, se detiene y contempla extasiado el monitor.
+
+EL JOVEN BILL GATES
+
+¡Madre! ¡Madre! ¡Venga aquí, lo he inventado!
+
+MADRE DE BILL GATES
+
+¿Qué quieres, hijo? Son las tres de la mañana… ¿Qué has inventado esta vez?
+
+EL JOVEN BILL GATES
+
+¡El corrector perfecto! Madre, usted podrá teclear cualquier frase, con los peores errores de sintaxis y los más graves gazapos y el ordenador le replicará con sus pecados corregidos.
+
+MADRE DE BILL GATES
+
+Pero hijo, ¡eso es una abominación! Las madres estamos para corregir los errores de nuestros hijos. ¿Qué haremos si nos quitas eso?
+
+EL JOVEN BILL GATES
+
+Madre, ¡es el progreso! Todos podrán expresarse sin que el listillo de turno les corrija a cada frase...
+
+MADRE DE BILL GATES
+
+¡Ni progreso ni progresa! A la cama y borra ese programa del demonio.
+
+EL JOVEN BILL GATES
+
+¡Pero madre!
+
+MADRE DE BILL GATES
+
+¡No me repliques! Y a ver si dedicas tu tiempo a cosas de provecho en vez de a esas tonterías.
+
+El joven Bill Gates se dirige refunfuñando a su cama, enojado. Una vez acostado, una explosión de luz y humo inunda su cuarto. Un extraño hombre barbudo con una túnica estampada de ceros y unos se planta en medio de la estancia.
+
+EL JOVEN BILL GATES
+
+¿Quién anda ahí?
+
+EL DIOS DE LA COMPUTACIÓN
+
+¡Bill! ¡Bill! ¡Has osado violar la ley de Turing de lo computable y lo indecidible!
+
+EL JOVEN BILL GATES
+
+¡Pero si yo sólo he escrito un corrector ortográfico! Además, ¿no llega usted un poco tarde?
+
+EL DIOS DE LA COMPUTACIÓN
+
+¡Ni pero ni peras! Además, en esta época los módems van a 300 baudios y ha tardado mucho en llegarme lo tuyo. Te salvas de que te enseñe el futuro desastroso que traería tu creación, que vamos justos de extensión y tu madre te ha dado lo suyo. Además, esto no es Dickens.
+
+EL JOVEN BILL GATES
+
+¡Gracias, oh dios de la computación! Corregiré mi camino y me dedicaré a escribir el buscaminas.
+
+EL DIOS DE LA COMPUTACIÓN
+
+¡No creas que te vas a librar tan fácilmente! ¡Yo te maldigo! Por querer corregir todo error humano y con ello, privarles de la virtud de aprender de sus errores y hacer de las máquinas dioses, yo te castigo. Tus programas serán populares en el mundo entero, pero todos tus usuarios te odiarán por cualquier bug. Cualquier programa tocado por ti frenará el más potente superordenador y Moore no te salvará.
+
+EL JOVEN BILL GATES
+
+¿Pero eso quiere decir que me puedo forrar igual, no?
+
+EL DIOS DE LA COMPUTACIÓN
+
+Por tu insolencia, ¡añado que las mujeres te ignorarán a ti y a los de tu especie!
+
+EL JOVEN BILL GATES
+
+¡NOOOOOOOOOOOOOO!
diff --git a/blog/content/notas/ficcion/mariano-el-programador.gmi b/blog/content/notas/ficcion/mariano-el-programador.gmi
new file mode 100644
index 00000000..f6eff640
--- /dev/null
+++ b/blog/content/notas/ficcion/mariano-el-programador.gmi
@@ -0,0 +1,53 @@
+# Mariano, el programador
+
+Mariano era un programador. No era el mejor, ni tampoco el peor. Había aprendido poco a poco, por su cuenta, hasta que un día descubrió que se podía ganar la vida con ello. Acabó trabajando en un olvidado engranaje del gobierno, programando poco a poco, día a día, tranquilamente.
+
+Mariano era el responsable de un pequeño programa que tomaba decisiones muy simples sobre gastos de un departamento muy pequeño de una subdelegación de un pequeño departamento que no estaba en boca de todos. Una vez al mes, alguien pulsaba un botón en el programa de Mariano y el presupuesto se repartía. No era un reparto particularmente ingenioso o eficiente, pero funcionaba- bueno, de cuando en cuando había algún problema pero Mariano siempre estaba ahí para resolverlo.
+
+Pero era un programa que ahorraba a un subsecretario hacer una hoja de cálculo tediosa, y si bien Mariano no se podía sentir orgulloso al lado de los gigantes de la informática que consiguieron hacernos felices acariciando cristales, sabía que su programa ayudaba a alguien, y eso le hacía feliz.
+
+El programa funcionaba, y un día el subsecretario se lo explicó a otro subsecretario mientras jugaban al pádel. El primer subsecretario concertó una reunión inmediata entre el segundo subsecretario y Mariano, para ver si éste podría ayudarle a automatizar unas cosas de su departamento, que le quitaban mucho tiempo.
+
+Mariano le escuchó y le propuso un par de ideas, y vio como el segundo subsecretario asentía con la mirada perdida. Mariano le preguntó un par de cosas, y el segundo subsecretario le dijo que no lo veía claro, que qué proponía Mariano. Su propuesta le pareció fantástica, y al poco tiempo Mariano recibió una nota de que ampliase su programa para manejar las tareas del segundo subsecretario.
+
+En un par de días, Mariano tenía un prototipo. Se lo enseñó a la ayudante del segundo subsecretario, que le hizo un par de correcciones pero que parecía contenta. Mariano era feliz, por fin su programa hacía más cosas. Estuvo unos días ocupado y al final el programa fue capaz de asumir muchas funciones del segundo subsecretario.
+
+Mariano tenía ahora un poco más de trabajo, pero las funciones del primer programa ya estaban bastante pulidas y se podía dedicar casi plenamente a los problemas de la nueva funcionalidad.
+
+El segundo subsecretario decidió pasarse al golf, donde podía codearse con adjuntos superiores. Estos, sorprendidos por el hecho de que un subsecretario jugase a golf con ellos, no tardaron en interrogarle y descubrir las bondades del programa de Mariano.
+
+Pronto estos iniciaron un proyecto conjunto, con un presupuesto generoso para ampliar el programa de Mariano. Le ayudaron a contratar unos cuantos programadores más para ayudarle y que pudiese asumir más funcionalidades dentro del gobierno.
+
+Mariano titubeó. Él, un simple programador autodidacta, liderando un proyecto para automatizar los trabajos de varios adjuntos superiores. Sin embargo, vio cómo confiaban en él y asumió el reto.
+
+Fue complicado, pero resultó ser que Mariano era especialmente habilidoso entendiendo los problemas y proponiendo soluciones que los adjuntos aceptaban con la mirada perdida, y que luego sus ayudantes le acababan de corregir. Mariano iba interiorizando cómo funcionaba el gobierno, y cada vez le resultaba más simple extender el programa.
+
+Había problemas, sí; los gobiernos no son organismos simples, pero Mariano y sus ayudantes iban encontrando soluciones y haciéndolo funcionar todo.
+
+Pero un día, Mariano se dio cuenta de algo. Tenía un problema con un pequeño módulo que tenía que lidiar en un problema interdepartamental, y no encontraba manera de hacerlo. Preguntó a los viceadjuntos medios, que eran los únicos que quedaban por las oficinas, removiendo sus cafés con la mirada perdida, pero pronto vio que no sabían cómo funcionaba el programa de Mariano y que mucho menos podrían resolverle el problema.
+
+Mariano preguntó y preguntó, pero todo el mundo parecía haber olvidado qué problemas resolvía el programa de Mariano, y mucho menos cómo lo hacía.
+
+Mariano y sus programadores discurrieron durante un par de días y al final hallaron una solución. No les complacía demasiado, pero era la única que tenían. En un par de semanas la tuvieron lista, pero estaban un poco preocupados porque no sabrían si era correcta o si funcionaría bien.
+
+Pensaron que si fallaba, alguien se quejaría, ¿no? Con cierta preocupación, pulsaron el botón que la puso en marcha.
+
+Pasaron semanas, y no sólo nadie se quejó, sino que seguían lloviendo carpetas con más tareas a automatizar. Con cierto orgullo, Mariano y sus programadores- que cada vez eran más- seguían automatizando y automatizando.
+
+Como pequeñas hormiguitas, un día, un submódulo del programa de Mariano emitió un mensaje que el propio Mariano había programado como pequeña broma para sí mismo. Todos los departamentos del gobierno habían sido automatizados. El programa de Mariano había asumido el control.
+
+Las cosas ni iban ni mejor bajo el programa de Mariano. Siento tener que explicar que este cuento no es ni una utopía ni una distopía. El gobierno iba tirando como antes, si acaso, las pistas de pádel y de golf estaban algo más ocupadas.
+
+Hasta que un día, Mariano cayó en algo. Sólo él realmente sabía cómo encajaba todo. Sus programadores conocían algún módulo, pero eran muchos módulos y muchos programadores, algunos de los cuales ni se conocían, pero Mariano les conocía a todos, y podía ver sus líneas de código en sus sueños. ¡Qué funcional bucle el de Javier! ¡Qué adecuada subrutina la de Antonia!
+
+Mariano así, con la ayuda de sus programadores iba retocando el programa. El mundo seguía igual, pero el programa de Mariano exigía sus horas de mantenimiento. Ya hasta los programadores de Mariano comenzaban a tener la mirada un poco perdida, picando teclas con eficiencia, como Mariano les había enseñado; resolviendo las incidencias de los módulos con cariño, como Mariano les había mostrado.
+
+Los programadores de Mariano eran extensiones de Mariano; con peinados y colores de ojo diferentes, pero eran Mariano. El gobierno, así mismo, se había convertido en Mariano, o quizás en el programa de Mariano, y no había nada que se escapase de sus millones de líneas de código, ni especialmente eficientes ni especialmentes elegantes, pero funcionales, como le gustan a Mariano.
+
+Hasta que un día, uno de los programadores de Mariano descubrió un pequeño fallo en el programa de Mariano. Una pequeña subrutina tenía un sutil defecto, que hacía que el conteo de vacaciones no se realizase correctamente. El único afectado, curiosamente, era Mariano. Al corregirlo, el sistema sufrió un pequeño desbordamiento, que pudieron resolver entre un par de programadores. Tras un par de días de impresión, le entregaron a Mariano una pequeña pila de papel continuo con el cálculo exacto de días de vacaciones que tenía pendientes.
+
+Mariano, que había aprendido a confiar en su programa como todo el mundo en el país, miró un segundo al infinito y lo aceptó. Avisó al programa de Mariano que en un par de semanas se cogería vacaciones y así lo hizo.
+
+Llevaba ya un par de años de vacaciones sin sobresaltos, pero con la mirada un poco perdida eso sí, cuando le llegó un telegrama. Miro al cielo, puso el telegrama otra vez en la mesa y pensó para sus adentros:
+
+-Que lo resuelva Mariano, que yo estoy de vacaciones.
diff --git a/blog/content/notas/ficcion/un-paseo-por-el-rio.gmi b/blog/content/notas/ficcion/un-paseo-por-el-rio.gmi
new file mode 100644
index 00000000..611fd599
--- /dev/null
+++ b/blog/content/notas/ficcion/un-paseo-por-el-rio.gmi
@@ -0,0 +1,37 @@
+# Un paseo por el río
+
+Se hallaba como otras tantas veces en frente de la temida página en blanco. No sabía qué escribir. Le daba vueltas, buscando una idea. Eso ya lo había escrito. Eso otro ya lo había escrito mejor otro.
+
+Dejó volar su imaginación. Su alma de juntaletras voló por la estratosfera hacia el norte. Vio a lo lejos las luces, la torre Eiffel. “¡Eso es!”, pensó, “Paris, la ciudad del amor y los poetas”. Descendió a toda velocidad y pronto se encontró en su orilla preferida del Sena.
+
+-¡No empuje!
+
+-¡Sin colarse, eh!
+
+Eran escritores, de eso no le cabía la menor duda. Las gafas, los Macs bajo el brazo y, sobre todo, sus egos les delataban.
+
+-La cola acaba ahí, a esperar como todos.
+
+Se giró y la vió. “Inspiración a orillas del Sena” rezaba el letrero más adelante. Se dirigió al plumilla que tenía más cerca.
+
+-Oye, ¿qué es esto? Vengo muchísimo por aquí y nunca había visto esto.
+
+-Ya, lo pusieron el verano pasado. Venimos tantos que al final es normal. Por mucho que la imaginación sea infinita, al final todos recalamos aquí y han decidido hacer algo con las aglomeraciones.
+
+-Pero este es el pasaje que necesito. No puedo esperar a esa cola. Mis personajes tienen que darse un paseo por aquí para que el lector se ambiente.
+
+-¿Pareja de enamorados?
+
+-Sí.
+
+-Los míos llevan 20 años casados y han venido aquí a encontrarse a sí mismos.
+
+-¡Qué tópico!- saltó uno algo más atrás- Los míos son un vampiro y una humana y él la trae aquí por primera vez para…
+
+Alguien le tiró una piedra y se oyeron unas cuantas carcajadas.
+
+-Oye, en serio, que lo mío es original…
+
+Le interrumpieron más risas.
+
+-¡Sí sí, y lo mío!- tenía en su mirada la pesadez de quien escribe por encargo- Mire, calle un rato y haga la cola. Si no le gusta, flote por ahí hasta encontrar algo más bonito y que enganche a sus lectores.
diff --git a/blog/content/notas/index.gmi b/blog/content/notas/index.gmi
new file mode 100644
index 00000000..c3345f38
--- /dev/null
+++ b/blog/content/notas/index.gmi
@@ -0,0 +1,31 @@
+# Notas
+
+=> comprar-bajo-en-sodio Comprar bajo en sodio
+
+## Lenguaje
+
+=> lenguaje/bugs Bugs en el español
+
+## Ficción
+
+=> ficcion/cuentos-del-triangulo-verde Cuentos del triángulo verde
+=> ficcion/el-principe El príncipe, el rey y el verdadero mal
+=> ficcion/maldito-clip Maldito clip
+
+=> ficcion/lucifer-martinez Lucifer Martínez
+=> ficcion/conmutatividad Conmutatividad
+=> ficcion/mariano-el-programador Mariano, el programador
+=> ficcion/en-los-mejores-cines En los mejores cines
+=> ficcion/un-paseo-por-el-rio Un paseo por el río
+=> ficcion/invoco-al-diablo Invocó al diablo y lo que sucedió a continuación te sorprenderá
+
+## Tele
+
+=> tele/el-estado-de-esta-nacion-grabando El estado de esta nación grabando
+=> tele/teles Teles
+
+## Tecnología
+
+=> tecnologia/quiero-instalar-linux Quiero instalar Linux
+=> tecnologia/problemas Problemas
+=> tecnologia/mama-quiero-ser-programador Mamá, quiero ser programador
diff --git a/blog/content/notas/tecnologia/mama-quiero-ser-programador.gmi b/blog/content/notas/tecnologia/mama-quiero-ser-programador.gmi
new file mode 100644
index 00000000..01388fe2
--- /dev/null
+++ b/blog/content/notas/tecnologia/mama-quiero-ser-programador.gmi
@@ -0,0 +1,115 @@
+# Mamá, quiero ser programador
+
+Nuestro primer ordenador llego a casa cuando yo tenía cuatro años. A mi madre le gusta repetir que aquel día mi padre, mi hermano y yo no comimos. Desde entonces me han fascinado los ordenadores, lo que me ha llevado a la fascinación por programar.
+
+Curiosamente, estudié ingeniería informática un poco por casualidad e incluso cuando acabé la carrera, tenía mis dudas de si sería mi carrera profesional.
+
+Sin embargo, en los últimos tiempos hay mucho interés en los beneficios de trabajar de programador.
+
+Más recientemente, la fiebre del oro de los LLMs ha sembrado dudas sobre el futuro de la profesión.
+
+Este texto intenta recoger mis opiniones sobre estos temas.
+
+## Observaciones sobre el mercado laboral
+
+Los trabajos de programador parecen reflejar que hay mucho trabajo y poca gente capacitada para hacerlo. Hay bastantes trabajos comparativamente bien pagados y con buenas condiciones.
+
+Sin embargo, esto mayormente aplica a los trabajadores con bastante experiencia. Gente con poca experiencia comenta que encontrar un trabajo requiere un esfuerzo desproporcionado, si se consigue encontrar siquiera trabajo.
+
+Propongo que esto se debe a que la mayoría de ofertas son para programadores con experiencia y el atractivo de la profesión ha generado un número de candidatos mucho mayor que las ofertas disponibles, creando la situación inversa que la de los programadores con experiencia.
+
+Además, la profesión de programador tiene la peculiaridad de que muchos profesionales dedican mucho de su tiempo libre a ejercer, más allá del trabajo o los estudios. Como el proceso de obtener un trabajo tiene elementos de competencia con el resto de candidatos a un puesto, entre programadores con poca experiencia se ha popularizado autoformarse para mejorar sus posibilidades. Esta medida sólo es efectiva cuando nos permite destacar sobre otros competidores, con lo que cada vez parece necesitarse más esfuerzo de autoformación para competir.
+
+### La irrupción de los LLMs y la crisis postpandemia
+
+En 2020, diversos factores generaron un crecimiento del sector mayor de lo habitual. Sin embargo, a partir de mediados de 2022, se dispararon los despidos en el sector. layoffs.fyi recoge cifras de despidos que desde el segundo trimestre de 2022 siempre se han mantenido como mínimo bastante por encima del periodo 2020-2021, con un pico de despidos en el tercer trimestre de 2023.
+
+Además, en noviembre de 2022, OpenAI lanzó ChatGPT. Desde entonces, muchos han augurado que los LLMs pueden afectar significativamente al mercado laboral en general y al sector en particular.
+
+Finalmente, muchos interpretan movimientos políticos, económicos y otras inestabilidades como otra crisis mundial en ciernes.
+
+## La incertidumbre sobre el sector
+
+Quienes buscan una carrera laboral y piensen en la programación deberían preguntarse si sigue siendo el sector de la programación tan atractivo como parecía ser hace unos años.
+
+La respuesta es incierta ahora mismo.
+
+Los problemas para entrar en el mercado siguen siendo iguales o peores de lo que llevan siendo en los últimos años.
+
+Además ahora hasta profesionales con experiencia tienen dudas sobre su futuro.
+
+No hay certezas para predecir el futuro, pero podemos observar el pasado.
+
+Apostar por la programación antes parece una buena idea a posteriori, pero mucha gente ha abandonado el sector y no todo el mundo ha tenido trabajos buenos y bien pagados.
+
+=> https://www.experimental-history.com/p/face-it-youre-a-crazy-person Face it: you're a crazy person es un artículo que propone que escoger una profesión debería basarse en lo atractivo que nos resultan *todas* las partes del trabajo, sobre todo las peores.
+
+Ya cuando estudiaba, mucha gente se imaginaba divirtiéndose programando videojuegos.
+
+En mi opinión, algunas de las peores partes de la programación son las prisas; siempre se hace todo con menos tiempo del que querríamos. Eso influye en que lo que hacemos y lo que usamos suele estar mal documentado o no funciona bien, haciendo que la programación sea menos "construir cosas que sirven de algo" y más "reparar con mil chapuzas cosas ligeramente estropeadas".
+
+Además, lo otro es que muy probablemente tendremos que dedicar tiempo no remunerado y fuera de nuestra formación en formarnos, en general haciendo cosas que si bien pueden resultar más gratificantes, en general también serán frustrantes. (Además, de cara a conseguir trabajo, lamentablemente en general también ayudará muchísimo *completar* cosas que podamos poner en nuestro currículum.)
+
+A otro nivel, los trabajos de programación que pudieran resultar más motivadores y edificantes son por general los peor pagados y con peores condiciones, mientras que los buenos suelen ser en general los que despertarán menos vocación en nadie. En mi opinión, es complicado conseguir algo de realización en este sector sin sacrificar la mayoría de beneficios que muchos ven en la profesión.
+
+A corto plazo, mi previsión es que todo esto empeore. El sector muy probablemente seguirá siendo una opción mucho mejor que la mayoría, pero creo que las expectativas laborales deberán rebajarse. El único consejo que se me ocurre es intentar construir cosas similares a las que vemos en el mundo real para ver si nos gusta realmente el trabajo.
+
+## Consiguiendo un trabajo
+
+Los procesos de contratación son una parte proporcionalmente muy pequeña de la vida laboral pero que concentran gran parte de lo que se habla y se protesta en este sector.
+
+Tengo más de dos décadas de experiencia profesional, creo que he tenido muy buenos trabajos y generalmente voy a puestos con menos competencia de lo normal. Pero para encontrar trabajo, en ocasiones he tenido que presentarme a más de un centenar de ofertas y llevarme innumerables rechazos de todo tipo, silenciosos y sonoros.
+
+Hay estudios que parecen demostrar que una parte muy importante de ofertas en el sector incluso son totalmente ficticias. (Esto seguramente afecte a otros sectores, pero parece especialmente popular en este.)
+
+Los procesos de selección de personal tienen una gran parte de competencia porque en general, siempre hay otros candidatos que se esfuerzan como nosotros en ser los elegidos.
+
+### Fuentes de ofertas
+
+Aunque creo que las grandes plataformas de empleo son menos efectivas que otras vías para encontrar trabajo, sí vale la pena examinar las ofertas para saber qué demanda el mercado y de paso apuntarse a todas las ofertas que podamos. Esto último igual hasta nos sirve para entrar en algún proceso y quizá conseguir trabajo, pero también es importante porque los procesos de selección requieren práctica real para mejorar nuestras posibilidades.
+
+Es importante recordar que muy frecuentemente lo que parecen requisitos en estas ofertas de empleo no lo son. Si una empresa pide más conocimientos en una oferta de lo que es razonable, es muy probable que no encuentren a nadie que los cumpla todos y que contraten a alguien que no cumple todos los requisitos.
+
+En general, el mejor lugar para encontrar mejores vacantes son las pequeñas comunidades:
+
+* Los "meetups" son pequeños eventos generalmente periódicos donde se hacen pequeñas ponencias.
+* Muchas ciudades tienen sus comunidades de programadores que suelen tener un canal online (que no suelen excluir a gente de fuera)
+* Así mismo, muchas tecnologías también tienen sus propias comunidades, aunque haya menos específicamente españolas.
+ (En general, conseguir trabajos en el extranjero es bastante más complicado, así que recomiendo centrarse en comunidades españolas.)
+
+Muchas de estas comunidades tienen tablones de anuncios de ofertas de empleo. Muchas de estas ofertas las ponen los miembros de la comunidad y no las empresas, con lo que es más probable que sean reales, y en muchos casos, podremos hablar con la persona que pone el anuncio directamente. Además, en muchos casos los tablones de anuncios de comunidades tienen reglas más estrictas sobre publicación de rangos salariales y claridad en condiciones (como por ejemplo, la modalidad real de remoto).
+
+El volumen es por supuesto muy inferior, pero merece mucho la pena encontrar cuantos más tablones de anuncios de este tipo y centrarse más en sus ofertas. (Aunque raramente tendremos suficiente con estas ofertas para encontrar empleo, con lo que siempre deberemos tirar de las grandes plataformas.)
+
+### El currículum y la presencia online
+
+Este documento no tratará el currículum, pues ya hay mucho material sobre el tema y tampoco es mi especialidad.
+
+Sin embargo, es necesario apuntar que un montón de gente con la que competiremos por puestos tendrá más material del que esperamos en su currículum; si no son trabajos serán proyectos personales, participación en proyectos open source o similares, etc.
+
+Por tanto, lamentablemente dedicar nuestro tiempo libre a aumentar nuestro currículum sea necesario.
+
+### Los procesos de selección
+
+Los procesos de selección intentan encontrar la mejor opción dentro de los candidatos.
+
+Un proceso de selección jamás puede evaluar adecuadamente la capacidad de un candidato de hacer su trabajo, con lo que siempre se basan en aproximaciones, en general no muy buenas, que en general poco tienen que ver con el trabajo que se hará realmente.
+
+Al no ser algo muy exacto, los procesos de selección tienen muchísimo de imitación y modas.
+
+Esto tiene una ventaja; en cualquier momento determinado de tiempo hay como media docena de tipos de entrevista. Además, para cada tipo de prueba de moda, hay bastantes materiales para preparar la prueba.
+
+En mi opinión, hay que aceptar los sinsentidos de los procesos de selección, dedicar una cantidad significativa de tiempo para prepararnos los pocos formatos más populares en ese momento, y quizá consolarnos con que el número de formatos populares no es mucho mayor.
+
+### Escogiendo empleos
+
+=> https://es.wikipedia.org/wiki/Falacia_de_McNamara La falacia de McNamara dice que a la hora de tomar decisiones damos más importancia a lo que es fácil de medir con un número que a lo que no.
+
+El sueldo es de las pocas variables que podemos conocer cuando tenemos una oferta en la mesa, pero no es tan mala métrica.
+
+Pero mi recomendación es que aparte del sueldo, intentemos evaluar "¿cuánto me ayudará este trabajo a que mi próximo trabajo sea mejor?"
+
+Tampoco es que haya muchas maneras de evaluar esto con un mínimo de certeza, pero:
+
+* Plantearse lo que observamos en función de esta métrica nos puede ayudar a enfocar la evaluación.
+* A posteriori, podemos evaluar cuánto nos ha ayudado un empleo en esta métrica e intentar extrapolar señales que nos ayuden a predecirla.
diff --git a/blog/content/notas/tecnologia/problemas.gmi b/blog/content/notas/tecnologia/problemas.gmi
new file mode 100644
index 00000000..da4ee14f
--- /dev/null
+++ b/blog/content/notas/tecnologia/problemas.gmi
@@ -0,0 +1,63 @@
+# Problemas
+
+Este documento es una lista de cosas que me tocan las narices. En el mundo hay infinidad de problemas más graves, pero quiero destacar esta lista.
+
+## La basura telefónica está fuera de control
+
+Recibo frecuentemente tanto llamadas como SMS fraudulentos o de publicidad indeseada. Estoy apuntado en la lista Robinson y simplemente no hay manera de librarse.
+
+No corro un riesgo severo de ser víctima de un fraude, pero imagino que una cantidad importante de gente sí lo corre. (Aunque una vez, la compañía eléctrica de la que era cliente sí me coló un timo.)
+
+Hasta donde yo sé:
+
+* Es trivial falsear la identificación de un SMS para que sea idéntico al que envía una entidad legítima. (E.g.: puedes hacer un SMS que se identifique como "Correos", igual que un SMS legítimo de Correos.)
+* No existe, hasta donde yo sé, todo mecanismo de denuncia requiere que identifiquemos al autor de la llamada. Identificar quién llama sólo es posible si la empresa decide identificarse.
+* No percibo ninguna consecuencia negativa para nadie que participe en la basura telefónica. Esto incluye a quienes realizan estas llamadas y SMS, y a las operadoras telefónicas por las que fluyen.
+
+Los filtros de Google son moderadamente efectivos, pero no están al alcance de todo el mundo. Además, los falsos positivos de los filtros pueden hacer perdernos comunicaciones legítimas importantes.
+
+### Recomendaciones frente a la basura telefónica
+
+A nivel individual, podemos formarnos para hacernos menos vulnerables a los fraudes, pero es prácticamente imposible evitar las molestias.
+
+Mi recomendación para quien tenga un móvil con posibilidad de reportar llamadas de spam, es coger las llamadas que muestren un número y:
+
+* Decir algo. Si no decimos nada, muchas centralitas de spam no conectan a un operador, con lo que no podemos tener 100% la certeza de que sea spam.
+* Esperar a que respondan para asegurarnos de que es spam.
+* Si parece que hay un robot al otro lado de la línea, colgar inmediatamente. Si parece que hay un humano, esperar a que cuelgue. (Con esto, el humano no está libre para hacer otra llamada, con lo que les frenamos un poco. También podemos intentar alargar la llamada, aunque yo personalmente no tengo paciencia.)
+* Marcar la llamada como spam.
+
+Tengo la sensación de que los indicadores de spam de muchos teléfonos se basan en las denuncias que recibe cada número. Así que cuantas más llamadas se cojan y se marquen como spam, antes aparecerán marcadas claramente como spam para otras personas.
+
+(Es importante que los filtros antispam sean precisos.)
+
+### Otras referencias
+
+=> https://www.hiya.com/global-call-threat-report Hiya Global Call Threat Report Q4 2024
+
+## Los protocolos cerrados dan un poder desproporcionado a empresas privadas
+
+Para la mayoría de gente, WhatsApp es prácticamente una necesidad para la vida cotidiana.
+
+Esto hace que Meta controle una parte sustancial de nuestras comunicaciones, queramos o no. Además, esto hace que cualquier problema con WhatsApp (incidencia, carencia, etc.) sea inevitable.
+
+También hay efectos inesperados como que Meta decide qué sistemas operativos móviles son viables y cuáles no. (En un par de ocasiones, me he tenido que cambiar de móvil porque Meta ha decidido dejar de soportarlo. Aunque puedo experimentar con sistemas operativos móviles alternativos, siempre tengo que tener un móvil soportado por WhatsApp.)
+
+La ley de mercados digitales (DMA) en teoría ayudará parcialmente. Esta ley debería obligar a WhatsApp a interoperar, con lo que podríamos comunicarnos con usuarios de WhatsApp sin usar WhatsApp, mitigando algunos problemas. Sin embargo, aunque lleva en vigor desde el 7 de marzo de 2024, esto todavía no es posible y está por ver cuán efectivo será.
+
+Muchos sistemas de comunicación existentes son más abiertos que los protocolos modernos:
+
+* Cualquiera puede montar un servidor de correo y comunicarse con usuarios de correo electrónico de otros proveedores. Pese a que muchos apuntan a que Google y Microsoft tienen un poder desproporcionado de facto, sigue siendo totalmente viable usar otros proveedores. Y aunque se apunta que la interoperabilidad de los correos es causante del spam, muchos otros sistemas cerrados como WhatsApp tienen problemas de spam similares o mayores.
+* Aunque no todo el mundo puede hacer emisiones de DVB-T, cualquiera con una antena puede captar las emisiones y visualizarlas. (Los protocolos con los que se codifican las emisiones de DVB-T están disponibles para cualquiera.) También es posible codificar las emisiones de DVB-T para limitar su uso a usuarios que paguen, pero con libertad de consumir los contenidos con cualquier sistema DVB-T de nuestro agrado.
+
+(Esto en contraste con los servicios de streaming, que sólo podemos usar con dispositivos validados por el servicio de streaming.)
+
+## Los navegadores son excesivamente complejos
+
+Gran parte de los contenidos y procesos que tenemos que realizar hoy en día pasan por un navegador web.
+
+Por diversos motivos, los navegadores cada vez son más sofisticados para permitir mayores funcionalidades. Son tan complejos que Microsoft, una de las mayores empresas tecnológicas del mundo, ha renunciado a desarrollar un navegador propio y reutiliza gran parte de Chrome, un navegador controlado por una empresa con la que compite, Google.
+
+Fuera de Google Chrome y de Safari de Apple, virtualmente no existen navegadores que compitan con ellos. (Hay más navegadores, pero como Edge de Microsoft, usan el motor de Chrome o de Safari. Firefox es cada vez más minoritario e irrelevante [aunque yo lo uso y animo a todo el mundo a que lo use].)
+
+La sofisticación y complejidad de Chrome y Safari adicionalmente hacen que cada vez existan más webs y aplicaciones web que son prácticamente inutilizables en dispositivos de rendimiento modesto. Esto hace que sea virtualmente necesario renovar nuestros dispositivos con más frecuencia de la necesaria, a dispositivos más costosos de lo que necesitaríamos para el resto de nuestros propósitos.
diff --git a/blog/content/notas/tecnologia/quiero-instalar-linux.gmi b/blog/content/notas/tecnologia/quiero-instalar-linux.gmi
new file mode 100644
index 00000000..e8a5e183
--- /dev/null
+++ b/blog/content/notas/tecnologia/quiero-instalar-linux.gmi
@@ -0,0 +1,271 @@
+# Quiero instalar Linux
+
+Si estás leyendo esto, es porque estás pensando en pasar tu ordenador a Linux.
+
+¡Excelente!
+
+En este documento recojo mis consejos para los que estáis en esta situación.
+
+## No es necesario pasarse a Linux
+
+Vaya por delante que aunque llevo usando Linux en mis ordenadores personales desde los inicios de siglo, y laboralmente más de una década. Linux es indudablemente uno de los mejores sistemas operativos que podemos usar en nuestros ordenadores personales, especialmente si creemos que es mejor para nuestros intereses usar software libre.
+
+Sin embargo:
+
+* Usar Linux sigue siendo algo más complicado que usar Windows, macOS, ChromeOS, Android y otros.
+* Todos los fabricantes de ordenadores y componentes dedican un esfuerzo razonable a hacer funcionar sus productos en Windows. Muy pocos fabricantes hacen lo mismo para Linux. Aunque muchas veces los desarrolladores de Linux consiguen hacer funcionar hardware, escoger hardware con buen soporte para Linux es prácticamente indispensable, y esto no garantiza una experiencia libre de problemas.
+
+Aunque uso Linux, he usado Windows, macOS, ChromeOS y Android, y es perfectamente lícito usarlos. Usando Linux seguramente aprendáis cosas nuevas y obtengáis beneficios, pero no siempre es lo mejor que podéis hacer con vuestro tiempo libre.
+
+Sed conscientes que pasaros a Linux requerirá esfuerzo, tiempo e incluso dinero.
+
+## No es necesario pasar nuestro único ordenador a Linux
+
+La mejor manera de instalar Linux en la mayoría de casos es reemplazar el sistema operativo de un ordenador completamente. (Se puede instalar Linux en paralelo a Windows, por ejemplo, y esto tiene ventajas, pero también es una fuente de quebraderos de cabeza.)
+
+Esto quiere decir que hasta que no tengamos Linux funcionando, el ordenador donde estemos jugando seguramente estará inservible. Podemos tener problemas de instalación que nos impidan usar Linux, o incluso una vez instalado, podría no gustarnos.
+
+Para hacer pruebas, recomiendo siempre considerar las siguientes posibilidades:
+
+### Probar Linux en una máquina virtual
+
+La mayoría de ordenadores hoy en día tienen suficientes recursos para crear una máquina virtual. Una máquina virtual es un ordenador dentro de nuestro ordenador donde podemos instalar un sistema operativo distinto.
+
+Instalar Linux en una máquina virtual es más sencillo que instalarlo en hardware real (en general, nunca hay problemas de compatibilidad de hardware). Aunque el rendimiento de Linux será menor al que tendrá instalado directamente en el hardware, nos permite hacernos una idea de lo que implica usar Linux antes de dar el salto.
+
+### Usar un ordenador secundario del que no dependemos
+
+En general, es posible encontrar ordenadores que no están en uso. Recomiendo cualquier ordenador con cuatro gigas de RAM y un SSD para hacer pruebas.
+
+Además, tener un ordenador para hacer pruebas siempre nos servirá para otra cosa, como sustituir temporalmente nuestro ordenador principal averiado u otros.
+
+Si no disponemos de uno, considerar examinar las tiendas de segunda mano. No suele ser complicado encontrar ordenadores de segunda mano usables a un precio asequible, incluso de modelos cuyo fabricante soporta el uso de Linux, como algunos ThinkPads, HP y Dell.
+
+### Probar Linux "live"
+
+La mayoría de distribuciones Linux tienen una versión "live" que permite ejecutar Linux desde un disco USB sin modificar nuestra instalación existente. Esto es más conveniente para probar si un ordenador del que disponemos tiene buen soporte de Linux, pero también nos sirve para hacernos una idea del funcionamiento de Linux.
+
+### Usar discos duros totalmente separados para diferentes sistemas operativos
+
+La mayoría de sistemas permiten añadir un segundo disco duro y escoger cuál usar al arrancar el ordenador. Esto tiene un coste extra, y en muchos casos como la mayoría de los portátiles, añade la inconveniencia de un disco duro externo. Sin embargo, elimina la mayoría de los problemas del arranque dual e incluso los dispositivos separados (y especialmente los externos) nos pueden dar un plus de flexibilidad.
+
+(Es recomendable siempre que los sistemas operativos estén en un disco SSD conectado mediante un interfaz rápido, evitando versiones de USB anteriores a USB 3.)
+
+Para un uso duradero de Linux, en general tampoco recomiendo el arranque dual, por ser una potencial fuente de problemas de fiabilidad difíciles de resolver.
+
+El arranque dual permite que los dos sistemas operativos funcionen directamente sobre el hardware, lo que puede ser necesario para que el software en *ambos* sistemas operativos pueda acceder a todo el hardware al máximo rendimiento. Sin embargo, la mayoría de sistemas operativos no están pensados para el arranque dual y, por ejemplo las actualizaciones pueden estropear el arranque dual.
+
+### Usar máquinas virtuales
+
+Para un uso duradero de Linux, a parte de usar hardware separado, podemos considerar el uso de máquinas virtuales, que adicionalmente pueden evitar problemas de compatibilidad de hardware. (No todo el hardware funciona con Linux, pero Linux casi siempre funciona perfectamente en una máquina virtual.)
+
+Windows además dispone de WSL, que es un mecanismo para integrar una máquina virtual Linux con Windows.
+
+También podemos correr Windows dentro de una máquina virtual en Linux, aunque la licencia que teníamos de Windows en general no es apta para este uso.
+
+Las máquinas virtuales tienen menor rendimiento y desventajas respecto a correr en el hardware directamente, aunque tienen otras ventajas. (Por ejemplo, es muy fácil hacer una copia de respaldo de una máquina virtual, en general podemos mover máquinas virtuales de un sistema a otro, y más.)
+
+### Usar software libre on otros sistemas operativos
+
+La mayoría de software disponible en Linux se puede usar en otros sistemas operativos. Incluso hay proyectos específicos para ofrecer plataformas similares a Linux dentro de otros sistemas operativos.
+
+## Como estar preparados para trastear con Linux
+
+Siempre que uno utiliza un ordenador es importante tener bien controlados nuestros datos. Esto es todavía más importante si queremos experimentar con distintos sistemas operativos como Linux.
+
+Es recomendable que no tengamos ningún dato que solamente resida en un ordenador. En condiciones normales, esto implica que un fallo de disco nos puede hacer perder datos valiosos. Instalando Linux, en general, borraremos el disco o haremos operaciones que pueden hacer que perdamos estos datos temporal o permanentemente.
+
+Es recomendable siempre tener varias copias de nuestros datos importantes, sea en la nube o en medios que tengamos físicamente.
+
+Además, si tenemos varios ordenadores y dispositivos, suele ser muy conveniente poder acceder a nuestros datos desde todos los dispositivos.
+
+Siempre es recomendable tener claro que podemos reinstalar o perder un ordenador sin sufrir por perder ningún dato.
+
+Y en caso de necesidad, siempre es bueno conocer el proceso de reinstalación de Windows.
+
+Muchos fabricantes incluyen una funcionalidad de recuperación de Windows que podemos conservar al instalar Linux (pero hay que prestar atención). También suelen ofrecer descargar el instalador de Windows. (Nunca está de más conocer el proceso de recuperación o instalación de Windows, pues siempre lo podemos necesitar sin ser usuarios de Linux.)
+
+## No todos los ordenadores soportan bien Linux
+
+Aunque Linux tiene una amplísima variedad de soporte de hardware, todavía tenemos muchos números de que el ordenador donde queramos instalar Linux nos dé problemas.
+
+Es recomendable siempre buscar el modelo del ordenador y "Linux" para ver si encontramos otras personas que hayan usado el mismo modelo de ordenador con éxito en Linux.
+
+Obviamente, con la inmensa variedad de ordenadores en el mercado, esto no siempre será posible.
+
+Algunas empresas que trabajan con Linux prueban modelos de ordenador en colaboración algunos fabricantes y publican listas de ordenadores certificados, como por ejemplo:
+
+=> https://ubuntu.com/certified Ubuntu
+=> https://catalog.redhat.com/search?searchType=hardware&type=System&system_types=Desktop%2FWorkstation|Laptop&p=1 Red Hat
+
+Así mismo, algunos fabricantes venden modelos con Linux preinstalados.
+
+Por supuesto, puede ser ventajoso poder reciclar hardware que ya tenemos, pero hoy en día hay bastante hardware con soporte para Linux y suele ser siempre una buena opción.
+
+Como mencionábamos anteriormente, siempre antes de instalar es recomendable probar una versión "live" de Linux para comprobar si el hardware funciona bien en Linux. Es recomendable siempre comprobar:
+
+* Conexión a la red: deberíamos poder acceder a Internet con o sin cable según sea nuestra preferencia
+* Sonido: que funcionen bien las salidas de audio que usemos (tomas de auriculares, altavoces, etc.).
+* Vídeo: nunca está de más comprobar que podemos reproducir vídeo de YouTube a buena calidad a toda pantalla con fluidez.
+* Accesorios: probar otros accesorios que usemos como auriculares bluetooth, impresoras, webcams, etc.
+
+No es raro que funcione todo menos algún detalle, con lo que es mejor ser lo más exhaustivo posible.
+Por ejemplo, hay webcams de portátil que no funcionan en Linux, y es un detalle fácil de pasar por alto.
+
+## ¿Qué Linux usar?
+
+Existe una infinita variedad de "distribuciones" de Linux y la elección es uno de los dilemas más populares entre los usuarios de Linux.
+
+Además, es común que los usuarios de Linux sean entusiastas de ciertas distribuciones.
+
+Siempre es recomendable dejarse asesorar, especialmente por personas que nos puedan ayudar ante ciertas dificultades.
+Será siempre más fácil ayudarnos con una distribución con la que estamos familiarizados.
+
+Sin embargo, hay que considerar que hay diversos grados de dificultad en las distribuciones Linux, y los usuarios avanzados a menudo escogen distribuciones más complejas para aprovechar sus peculiaridades.
+
+Hay una serie de criterios a observar al escoger una distribución:
+
+* Que tenga versión "live" para poder probar nuestro hardware.
+* Que sea muy popular en Internet. Muchos problemas tienen soluciones distintas según la distribución que usemos. Siempre es más fácil seguir instrucciones para la misma distribución.
+
+Diferentes distribuciones tienen políticas distintas sobre distribuir software no libre:
+
+* La distribución distribuye software no libre sin diferenciarlo del software libre.
+* La distribución distribuye software no libre, aunque haya que activarlo o hacer alguna pequeña configuración.
+* La distribución no distribuye software no libre, pero hay entidades que empaquetan software no libre para esta distribución.
+* La distribución no distribuye software no libre, no hay entidades que empaqueten software no libre para esta distribución, o hay cierta hostilidad al uso de software no libre entre la comunidad.
+
+Esto puede no parecer importante, pero es más común de lo que parece que ciertos dispositivos hardware o algunas funcionalidades dependan de software no libre y esto nos suponga un problema en ciertas distribuciones.
+
+Otro criterio importante pero más complejo es la política de versiones de la distribución.
+
+### Distribuciones Linux de soporte prolongado
+
+Hay distribuciones de soporte prolongado, como Ubuntu (LTS), Debian (stable) o Red Hat Enterprise Linux (y derivados) que sacan una versión nueva cada 2-3 años y se comprometen a soportar esa versión durante un periodo largo de tiempo.
+
+Esto quiere decir que el software que llevan puede no estar muy al día y que podemos tener problemas de soporte de hardware, especialmente para hardware muy moderno. Sin embargo, respecto a distribuciones con ciclos de vida más cortos, ofrece la gran ventaja de que las actualizaciones rutinarias son más sencillas y conllevan menos riesgo de problemas.
+
+Si encontramos una distribución Linux con soporte prolongado que soporta bien nuestro hardware, recomiendo comenzar con una distribución así mientras aprendemos Linux.
+
+Cada varios años tendremos que aplicar una actualización grande, pero en general, como estas actualizaciones son poco frecuentes, se prueban más ampliamente.
+
+(Las distribuciones de soporte prolongado también tienen actualizaciones de software, claro, pero intentan sólo sacar actualizaciones de seguridad o corrección de errores, excluyendo actualizaciones que introduzcan grandes cambios.)
+
+### Distribuciones Linux de soporte breve
+
+Otras distribuciones, como Fedora y Ubuntu (no LTS), sacan una versión nueva con mayor cadencia (cada 6 meses, típicamente), y el soporte para versiones no recientes decae rápidamente.
+
+Estas distribuciones tienen software más actualizado, pero por contra, tendremos que aplicar con más frecuencia actualizaciones grandes que pueden ser más problemáticas.
+
+Es cierto que estas distribuciones también prueban mucho las actualizaciones, y que al ser actualizaciones grandes más frecuentes en teoría deberían tener menos riesgo, pero recomiendo sólo usar distribuciones de soporte breve si funcionan en nuestro hardware y las de soporte prolongado no.
+
+### Distribuciones Linux de versionado continuo
+
+Otras distribuciones, como Arch o Debian (testing y otras) no tienen versiones, se actualiza todo su software continuamente, con actualizaciones de seguridad y corrección de errores, pero también grandes cambios.
+
+Las distribuciones de versionado continuo son idóneas si necesitamos el software más actualizado o queremos contribuir probando actualizaciones, pero no las recomiendo a no ser que se sea un usuario experimentado de Linux.
+
+## ¿Cómo instalar Linux?
+
+Por lo general, hoy en día todas las distribuciones Linux contienen instrucciones para descargar el instalador de la distribución y grabarlo en un disco USB.
+
+Estas instrucciones, si no queremos complicarnos la vida, borran el contenido del USB y lo reemplazan completamente, con lo que debemos usar un USB que no contenga datos importantes.
+
+La mayoría de instaladores tienen funcionalidad "live". Es muy recomendable probar todas las funcionalidades que podamos con la versión "live" de la manera más exhaustiva posible antes de hacer la instalación definitiva.
+
+Si el instalador no es "live", normalmente podremos encontrar una versión alternativa para la misma distribución, o en el peor caso, probar con el "live" de otra distribución.
+
+La distribución debería documentar adecuadamente el proceso de instalación, pero casi siempre consiste en:
+
+* Configurar el ordenador para arrancar el instalador en vez del sistema operativo que ya tenemos instalado. Esto en general se hace con lo que se suele llamar "BIOS", a la que accedemos pulsando una tecla específica durante el proceso de arranque. Si nuestro sistema actual es Windows, las versiones modernas tienen funcionalidades de arranque rápido que pueden interferir con la selección de arranque. Es posible que necesitemos consultar instrucciones más específicas para cambiar el arranque.
+* Probar el sistema en el entorno "live" y luego seleccionar una opción para hacer la instalación definitiva.
+* Escoger el nombre del ordenador, de nuestro usuario y otras opciones durante el proceso de instalación.
+* Una opción importante es si queremos que Linux y nuestro sistema operativo existente (típicamente Windows) coexistan o reemplazar el sistema operativo existente completamente con Linux. Anteriormente en este documento se detallan recomendaciones sobre evitar la coexistencia de varios sistemas operativos en un mismo disco duro.
+
+## ¿Qué problemas puede haber?
+
+### Problemas de medios USB
+
+Los discos USB tienen un amplio abanico de calidades.
+
+No es tan raro encontrar USB defectuosos que pueden causar que el proceso de instalación falle.
+
+Además, aunque es poco común, la descarga del instalador puede no funcionar adecuadamente.
+
+Ante problemas extraños, siempre es recomendable:
+
+* Verificar la descarga siguiendo las instrucciones de la distribución.
+* Verificar el disco USB; muchos instaladores permiten hacer una verificación antes de empezar, algunos programas para grabar USB pueden hacer una comprobación después de grabar.
+
+Aunque las verificaciones no encuentren problemas, sigue habiendo margen para el error. Siempre es conveniente tener otro USB para hacer otra prueba, para descartar problemas.
+
+### Problemas de instalación
+
+Incluso con un medio correcto, la instalación puede fallar. Los instaladores pueden tener defectos inesperados o podemos toparnos con problemas temporales de la infraestructura de la distribución que impidan la instalación.
+
+Una vez descartamos problemas de medios, es recomendable probar con otra distribución.
+
+Tampoco es imposible que simplemente el ordenador que estemos usando tenga algún problema de hardware preexistente que sólo se manifieste durante el proceso de instalación, por someter al ordenador a una carga no habitual.
+
+En general, todos los instaladores de Linux dan actualizaciones constantes del avance de la instalación. Puede que el sistema se bloquee o no responda fluidamente, pero nunca más de unos minutos.
+
+Si el sistema no responde durante varios minutos, tendremos que reiniciar el ordenador a la fuerza. Si los problemas se repiten, lo mejor es probar con otro disco USB, verificar la descarga del instalador, o probar con otra distribución.
+
+(Tendremos que volver a seleccionar el arranque del instalador. Este proceso puede ser distinto; si antes lo hicimos desde Windows, una vez reemplazado Windows, tendremos que usar "la BIOS".)
+
+## ¿Y si no me gusta?
+
+Como mencionamos anteriormente, siempre debería ser posible volver a Windows. Si nos hemos asegurado que nuestros datos estén protegidos, podemos reinstalar Windows de nuevo o usar las funcionalidades de recuperación.
+
+## Instalando programas en Linux
+
+Un ordenador y un sistema operativo no son más que medios para usar programas. De hecho, las distribuciones de Linux se llaman distribuciones porque aparte de Linux en sí (que por sí mismo no sirve de mucho), empaquetan una colección de programas para que nuestro ordenador sea útil.
+
+Por tanto, es importante saber qué programas necesitamos y cómo instalarlos en Linux.
+
+Lo más fácil suele ser instalar los programas que empaqueta nuestra distribución. Además, las actualizaciones de los programas instalados desde nuestra distribución están integradas con las actualizaciones del sistema, lo que supone una ventaja interesante respecto a otros sistemas operativos.
+
+Sin embargo, ni la distribución más extensa puede contener todos los programas que pueda necesitar todo el mundo. (Aunque en general, cualquiera puede pasar por un proceso para añadir el programa que quiera a una distribución, aunque en general empaquetar programas para distribuciones es de las maneras más complejas de distribuir software.)
+
+Adicionalmente, las distribuciones (especialmente las de soporte prolongado) no siempre están al día con las últimas versiones del software que empaquetan. (Las distribuciones de soporte prolongado y muchas de soporte breve sólo incorporan actualizaciones de seguridad y corrección de defectos. Aunque esto supone sus ventajas, muchas veces nos impedirá tener acceso a las funcionalidades más nuevas de un programa.)
+
+La mayoría de distribuciones tienen páginas web donde podemos buscar un programa y ver qué versiones están empaquetadas en qué versión de la distribución, como por ejemplo:
+
+=> https://www.debian.org/distrib/packages Debian
+=> https://packages.ubuntu.com/ Ubuntu
+=> https://packages.fedoraproject.org/ Fedora
+
+Nota: los paquetes de una distribución en general sólo se deben usar en la misma distribución *y* versión de la distribución para la que está hecho el paquete. Aunque a veces es posible aprovechar paquetes, no es recomendable si no sabemos bien cómo funciona.
+
+Pero existen más mecanismos para instalar software.
+
+### Sistemas de paquetes genéricos
+
+Principalmente Flatpak y Snap son dos sistemas para instalar software que funcionan en muchas distribuciones. A diferencia de los paquetes de una distribución, que sólo funcionan en esa distribución, un Flatpak o un Snap funcionarán en todas las distribuciones que estén soportadas.
+
+La ventaja indirecta para el usuario es que el autor de un programa (o cualquiera) puede hacer un Flatpak o un Snap e inmediatamente lo pueden usar usuarios de distintas distribuciones, sin tener que hacer el esfuerzo de empaquetarlo para todas las distribuciones. Con esto, hay bastantes programas que están mejor mantenidos como Flatpak o Snap que en las distribuciones.
+
+Sin embargo, mientras que ya confiamos implícitamente en nuestra distribución para tener programas libres de malicia (o al menos, si distribuyen programas maliciosos ya lo sufrimos), al añadir Flatpaks o Snaps debemos ser más cuidadosos, porque los programas pueden quedar desactualizados, el empaquetador no necesariamente es el autor del software, y un largo etcétera.
+
+Flatpak y Snap incorporan mecanismos para aislar los programas de manera que no puedan tener efectos negativos sobre nuestro sistema (como código malicioso, por ejemplo), que pueden ser más avanzados que los mecanismos de protección de la mayoría de distribuciones. Esto nos da cierta tranquilidad, pero puede causar problemas. Tanto el hecho de que los Flatpak y Snaps funcionan bajo varias distribuciones como estos mecanismos de protección pueden causar algunos problemas en algunos programas.
+
+A menudo pero no siempre, los Flatpak y Snap están integrados con las actualizaciones del sistema.
+
+### Empaquetados de terceros
+
+La mayoría de distribuciones dan mecanismos para que cualquiera pueda crear repositorios de paquetes alternativos.
+
+Algunos programas proporcionan repositorios para algunas distribuciones, y hay grupos que se dedican a crear repositorios con programas adicionales para distribuciones específicas.
+
+Usando estos repositorios, casi siempre conservamos que las actualizaciones de programas de estos repositorios se integran en las actualizaciones del sistema, con lo que es sencillo estar actualizado.
+
+Cuando el repositorio está empaquetado por los autores del programa, en general mejora la confiabilidad del paquete. En repositorios alternativos, nos tenemos que fiar más de quién mantiene el repositorio, aunque hay repositorios de terceros con un largo historial de confiabilidad y calidad.
+
+### Distribuciones binarias
+
+Algunos autores distribuyen versiones binarias de su programa, que funcionan de una manera similar a como se distribuye la mayoría de software en Windows o macOS.
+
+Estos binarios suelen ser confiables y de calidad, pero principalmente ofrecen dos problemas:
+
+* Los binarios no siempre funcionan en todas las distribuciones.
+* Si el programa no incorpora un mecanismo de actualizaciones, tendremos que actualizar el programa manualmente.
diff --git a/blog/content/notas/tele/el-estado-de-esta-nacion-grabando.gmi b/blog/content/notas/tele/el-estado-de-esta-nacion-grabando.gmi
new file mode 100644
index 00000000..168b4dbb
--- /dev/null
+++ b/blog/content/notas/tele/el-estado-de-esta-nacion-grabando.gmi
@@ -0,0 +1,60 @@
+# El estado de esta nación grabando
+
+Un familiar estaba encantado con su "vídeo" de hace ya muchos años. El vídeo es un receptor de TDT con disco duro (y DVD-RW) con el que puede grabar programas emitidos por TDT en España. Está acostumbrado a ver la tele y grabar, y hasta muy recientemente no han tenido Internet en casa, por lo que no están acostumbrados a usar plataformas tipo Netflix.
+
+Pero este vídeo sólo soporta SD, y en 2024 se produce el apagón.
+
+## Alternativas "distintas"
+
+El familiar comienza a usar Amazon Prime y alguna otra plataforma, pero no acaba de acostumbrarse y sigue grabando.
+
+* Tivify y similares permiten ver canales tradicionales de TDT como una plataforma de streaming normal y permite reproducir programas de los días anteriores. Es más práctico, ya que no hay que programar grabaciones. Sin embargo, tiene coste y la gente acostumbrada a grabar parece no apañarse.
+
+* Otra opción es HbbTV, conocido en España como LovesTv. Es una "capa" sobre una Smart TV que integra la emisión en TDT con una versión de la web de cada canal. Si estamos viendo TVE1, podemos activar el LovesTv y acceder al listado de programas anteriores del canal y verlos. Sin embargo, como veremos más adelante, le compramos al familiar una de las pocas teles del mercado (Xiaomi, de la que tenía excelentes referencias) que no tiene, pues no conocíamos esta característica.
+
+## Intentar mantener lo mismo
+
+### Dispositivos TDT varios
+
+Lo primero que intentamos fue comprar un receptor de TDT de Amazon con capacidad de grabar. Son bastate comunes, tienen un puerto USB en el que podemos enchufar almacenamiento, y se pueden programar grabaciones.
+
+Sin embargo, el primero que compramos no había manera de hacerlo funcionar. Tiene menús para programar las grabaciones, pero la grabación nunca se llega a hacer; es indiferente si dejamos el aparato en funcionamiento o no, o variando el dispositivo de almacenamiento, no se hace la grabación.
+
+Investigando reseñas en Amazon, esto aparece en la mayoría de dispositivos similares con un número de reseñas alto. A saber si hacemos algo mal, pero parece un problema común.
+
+Quizá poca gente graba y el control de calidad de los dispositivos baratos es nefasto. No parecía una buena idea ir comprando cacharros similares hasta dar con uno que funcione.
+
+### Televisores con grabador
+
+Otra opción que vimos es que hay televisores que también permiten grabar, conectando un dispositivo de almacenamiento por USB también. Esto se implementa poniendo dos sintonizadores en el TV, uno para poder ver la tele y otro para grabar mientras funciona el otro sintonizador.
+
+Sin embargo, esto sólo está disponible en teles de gama alta *y más importante*, a partir de cierto tamaño. El familiar tiene un mueble antiguo donde pone la TV, y es un problema poner un televisor de más de 32". ¡No he sido capaz de encontrar ningún televisor de 32" o menos con esta funcionalidad!
+
+Si no tenéis el problema del espacio y no os importa comprar una tele de gama alta, aunque me da mala espina por la mala experiencia con los dispositivos TDT que no nos han funcionado, confío que los televisores de marcas con reputación podrán grabar.
+
+### Dispositivo Android TV con receptor TDT
+
+Buscando, encontré un dispositivo, con Android TV y un sintonizador. También probé a comprarlo, pero lo devolvimos por lo mismo que el otro dispositivo: se podían programar las grabaciones, pero no había manera de que funcionasen. Una lástima, porque en otros países parece ser que hay dispositivos parecidos que funcionan. Además, el aparato también tiene funciones de Smart TV que van bastante bien, y parecía una buena solución.
+
+## Otras opciones
+
+Hay otros países donde parece que es más común seguir grabando de la TV. En EEUU son populares los HDHomeRun, que tienen funcionalidades bastante majas (a parte de funcionar con el televisor, hacen streaming a otros dispositivos; se pueden controlar por aplicaciones, etc.).
+En Inglaterra he encontrado cosas parecidas.
+
+Sin embargo, se han de comprar al extranjero, y parecen más problemáticos de conseguir aquí, tener garantía, certeza que funcionan en España, etc.
+
+## Primer intento
+
+Desde hace tiempo que tengo una Raspberry Pi con una sintonizadora USB, que utilizo con LibreElec + Kodi + TVHeadend. LibreElec es un sistema operativo fácil de instalar en Raspberry que integra Kodi y TVHeadend. Kodi es un interfaz para televisores con reproductor de medios, que se integra con TVHeadend. TVHeadend es un software para grabar TDT en un ordenador, mediante una sintonizadora.
+
+A mí me funciona de maravilla para grabar de cuando en cuando películas. Además, hay aplicaciones para controlarlo (mucho más cómodo que con un mando de TV). También es fácil hacer streaming y ver grabaciones desde otros dispositivos.
+
+Primero probé con un Raspberry Pi TV HAT y LibreElec + Kodi + TVHeadend sobre Raspbian. No se apañaba mucho.
+
+Luego probé con:
+
+=> https://dreamepg.de/index.php/en/apps/tvheadend/playertv Una aplicación para Android TV que hace de interfaz de Tvheadend.
+
+Es más fácil de usar que Kodi.
+
+Sin embargo el familiar siguió sin apañarse y al final se ha acostumbrado a usar Tivify.
diff --git a/blog/content/notas/tele/teles.gmi b/blog/content/notas/tele/teles.gmi
new file mode 100644
index 00000000..7ebf458f
--- /dev/null
+++ b/blog/content/notas/tele/teles.gmi
@@ -0,0 +1,75 @@
+# Teles
+
+Hoy en día, es casi imposible no comprar una tele que no sea una smart TV *mala* sin gastarse mucho dinero. Las teles baratas son ahora todas smart, con procesadores insuficientes para mover los menús con fluidez. Además, en teoría el precio de estas teles baja porque envían datos sobre su uso (que tienen valor).
+
+## Resumen rápido
+
+Comprar una smart TV, no conectarla a Internet, y comprar un dispositivo de streaming de Google o Amazon que soporte los servicios que consumimos. No es una solución ideal, pero creo que no existe una solución ideal. Y al menos, es una solución barata.
+
+Si queremos reproducir otros vídeos, probar primero a usar Kodi en el dispositivo de streaming. Si no es satisfactorio, el resto del artículo ofrece más alternativas.
+
+## Privacidad y demás
+
+Si tenemos cierta preocupación por que las empresas no exploten nuestros datos de visionado, la solución más simple es no conectarlas nunca a Internet.
+
+Hoy en día sigue siendo posible grabar programas de la televisión para verlos cuando más nos convenga. Sin embargo, antes existían dispositivos grabadores muy potentes que han dejado de fabricarse. Es muy complicado encontrar uno que funcione con los nuevos estándares de televisión digital.
+
+Muchas teles (pero no todas), soportan conectar un disco USB y grabar a este soporte. Sin embargo, estas funcionalidades suelen ser problemáticas. (Y salvo en televisores caros, no podemos grabar un canal mientras vemos otro.) Hablo más de estos temas en:
+
+=> el-estado-de-esta-nacion-grabando El estado de esta nación grabando
+
+## Servicios de streaming
+
+Si usamos servicios de streaming, tenemos la opción de conectar la tele a Internet, si esta soporta los servicios que queremos y no nos importa que se exploten los datos de visionado.
+
+Si la tele no tiene los servicios que deseamos o preferimos algo en teoría menos invasivo, las opciones más populares son:
+
+* Los aparatos de streaming de Google
+* Los aparatos de streaming de Amazon
+* La Nvidia Shield
+* El Apple TV
+* Consolas
+
+Los aparatos de Google y Amazon son los más baratos y en general tienen todos los servicios comunes en España. Sin embargo, son bastante lentos y seguramente tampoco sean completamente privados.
+
+La Nvidia Shield es un dispositivo similar a los aparatos de streaming de Google, pero bastante más cara (sobre los 200€). En teoría tiene más potencia, con lo que el uso de los menus puede ser menos frustrante, aunque hay comentarios en Internet que apuntan a que a veces se engancha un poco.
+
+El Apple TV es algo más barato (sobre 170€), está más pensado para el ecosistema Apple, pero supuestamente también supone una mejor experiencia de fluidez.
+
+Si tenemos una consola para jugar, estas soportan bastantes servicios de streaming y en teoría disponen de más potencia para mover menús que cualquier otro disposito. El mayor inconveniente es que se controlan con un mando de consola y no con el típico mando de televisor (aunque algunas consolas disponen de mandos específicos para este propósito).
+
+### Chromecasting y similares
+
+Una característica interesante de algunos dispositivos es la posibilidad de enviar reproducciones del móvil a la pantalla.
+
+Con los dispositivos de Google (o relacionados, como la Nvidia Shield), esta funcionalidad se denomina Chromecast. Un bonito plus es que al enviar algo con Chromecast a la tele, la tele puede encenderse automáticamente y cambiar automáticamente al contenido.
+
+Los móviles pueden ser más cómodos para localizar el contenido a enviar. Además, si estamos viendo un vídeo en nuestro teléfono, en general podemos enviarlo al televisor de una manera muy conveniente.
+
+(Un engorro es que normalmente manejar las aplicaciones de streaming es un poco incómodo con el teléfono- por ejemplo para poner la pausa, usar una pantalla táctil no es muy ágil.)
+
+El ecosistema Apple dispone de funcionalidades similares (pero seguramente más restringidas a dispositivos Apple).
+
+### Otros dispositivos
+
+Todos los servicios de streaming pueden usarse en ordenadores convencionales. La mayoría de ordenadores disponen de mayor potencia que la mayoría de dispositivos, con lo que podrían proporcionar una mejor experiencia navegando por los menús.
+
+Sin embargo, no hay buenas maneras de usar mandos tradicionales para navegar por los menús, y no es inmediato ponerle a un ordenador un interfaz adecuado para uso como televisor. (La navegación espacial ayudaría, pero sólo he encontrado [el soporte de Vivaldi para ella](https://help.vivaldi.com/desktop/shortcuts/spatial-navigation/), y no parecía funcionar muy bien.)
+
+Existen opciones como teclados con touchpad integrado, o mandos con giroscopio que permiten controlar un ordenador apuntando al televisor, pero son soluciones más inconvenientes que los mandos tradicionales.
+
+## DVDs y demás
+
+Sigue existiendo la opción de comprar películas o series en formato DVD o Bluray. Con estas compras, nos aseguramos que siempre podremos verlo. (Los servicios de streaming van retirando contenido.)
+
+En este caso, un reproductor dedicado puede ser de utilidad, así como consolas que soporten el formato deseado.
+
+## Otras fuentes de vídeo
+
+Si tenemos archivos de vídeo que queremos reproducir (por ejemplo, podemos pasar DVD y Bluray a ficheros), hay varias opciones:
+
+Muchos televisores soportan la reproducción de un disco USB. Aquí tenemos que ser un poco cuidadosos con la elección de formato (no todos los televisores soportan todos los formatos), y especialmente con los subtítulos.
+
+Los dispositivos de streaming suelen soportar la instalación de Kodi, VLC y otros reproductores. Estos reproductores suelen manejar bien casi todos los formatos, e incluso nos ofrecen la posibilidad de reproducir contenido almacenado en otros dispositivos como ordenadores y NAS.
+
+También podemos usar Kodi en PCs o sistemas como las Raspberry Pi. En general, el uso de Kodi en PCs es bastante rápido y agradable si adquirimos un mando a distancia adecuado. La Raspberry Pi ofrece la posibilidad de controlarla con el mando del televisor (mediante el sistema CEC, soportado vario bajos nombres por las distintas marcas de televisores), aunque es algo menos ágil con los menús.
diff --git a/blog/content/notes/cliffs/governable-spaces.gmi b/blog/content/notes/cliffs/governable-spaces.gmi
new file mode 100644
index 00000000..39941093
--- /dev/null
+++ b/blog/content/notes/cliffs/governable-spaces.gmi
@@ -0,0 +1,115 @@
+# Governable spaces
+
+=> https://luminosoa.org/site/books/m/10.1525/luminos.181/
+
+## Introduction: democracy in the wild
+
+* Online communities are different to in-person communities.
+* Online politics in the small reflect in the large.
+* Online communities must explicitly be democratic, self-governance instead of top-down authority => governable spaces.
+* Democratic erosion in the world is influenced by online communities.
+* Users of online communities perceive arbitrary rule enforcement, unaccountability.
+* Online movements have not resulted in lasting gains.
+* The design of online spaces has atrophied everyday democracy skills.
+* Garden club from 1960 with eight pages of bylaws => more successful than most only communities that will not live as long.
+* Fervent US enthusiasm for forming associations observed by Alexis de Tocqueville in 19th century US.
+* Tocqueville: democracy requires education, democracy in education requires political engagement.
+* Tocqueville: associations can serve the social order.
+* Will bad players behave better if they care about mini-democracies?
+* Online spaces are different, more churn, faster, distributed, diverse.
+* Participating in online spaces correlate to political participation.
+* Author unclear about his disagreement with Tocqueville's conclusions, author is more optimistic.
+* Democratic self-governance is harder in online spaces, but possible.
+* Design to achieve self-governance, refuse corporate control.
+* Technical solutions are not sufficient.
+* People do not believe their governments are democratic.
+* People are more willing to change due to technological progress.
+* Governments use technology as an "unavoidable excuse", but it doesn't have to be this way.
+* Introduction of citizen voice happens even authoritarian governments (!)
+* Crypto ledger structures have new power structures, even though it's often antidemocratic, but presents an opportunity.
+* For many, democracy is something that was created for them before they were born, or something they won't have in their lifetime.
+* Online communities are closer to most than their democracy.
+* Designing online communities offers chance to learn how to shape the larger government.
+* No single design can work for all scenarios.
+* Design should be based on accountability.
+* Democracy on a small scale gives hope that it's possible on a bigger scale.
+* From server control to community control.
+* Implicit feudalism: power derives from founders and admins.
+* "Governable stacks", "modular politics" to learn from.
+* Widespread participation => burdensome, elitist, uninformed governance? Overwhelming to participants.
+* Sometimes governable spaces should be highly participative, in others, use representation.
+* Governance designs sensitive to economy of attention.
+
+## Implicit feudalism. The origins of counter-democratic design
+
+* A popular group that called for accountability had a flagship organization with a single board member.
+* Facebook claimed having "the hacker way": open, meritocratic, but Mark Zuckerberg has majority control.
+* Founders solidify.
+* Early social platforms had technical conditions that grant administrators complete control.
+* Use of "feudalism" is not historically precise.
+* "Implicit" because it is not explicit.
+* Sometimes platforms do not even allow transfer of power.
+* Democracy can arise in feudal technologies due to pressure, this democracy can be similar to primitive democracy.
+* But democracy in technology tends to go against the design, the most natural outcome is nondemocratic.
+* Implicit feudalism is not a feature, it is merely seen as a non-intentional lack of features.
+* First step: perceive lack of democratic features.
+* "Exit" vs. "voice"; can only leave, vs. can change things.
+* Exit can have costs => captivity.
+* Refine voice into "Effective voice" vs. "affective voice" => venting vs. being able to make changes.
+* BBS: runs in the sysop house, sysop has absolute power, but also most responsibility and maintenance burden.
+* Users being able to leave makes some accountability.
+* Limitations of real world (sysop responsibility) lead to implicit feudalism.
+* Usenet was bigger scale than BBS, but ultimately "the big 8" ruled (and they named their successors). But Usenet hosted more popular communities than BBSs.
+* Usenet hierarchy is decided by the big 8.
+* Mailing lists follow similar patterns, administrators have all the power.
+* In IRC, iconic channel/network names are a big factor in popularity over performance.
+* IRC pioneered bots to execute authority.
+* BBS, Usenet, mailing lists, IRC's structure follow that of UNIX, with root, etc.
+* Linux and Wikipedia are very productive.
+* Linux has BDFL (feudalism).
+* Git seems to break feudalism with its distributed nature, but Linux uses a mailing list and the BDFL to control.
+* GitHub promotes forks, and user voice in issues, but each project has owners and collaborators.
+* Git/GitHub make "exit" easier, but not effective voice.
+* Linux added a code of conduct, GitHub encourages project to have one.
+* Debian Project Leader is elected, technical barriers of entry.
+* Debian/Apache are outliers, non-profits. (Linux is a non-profit too.)
+* Wikipedia also has self-governance, but also has BDFL.
+* Wikipedia uses MediaWiki for governance (dogfooding).
+* But most MediaWiki sites do not have self-governance.
+* After Wikipedia's BDFL overreaches, BDFL has diminished power.
+* Although software designs can have power vacuums, in the absence of technical software vacuums, "tyrany of structurelessness" often arises.
+* Anyone could participate, but not everyone has the time, knowledge, and incentives.
+* Big corporate platforms could not have the technical limitations of smaller earlier platforms.
+* US Communications Decency Act protects platforms from liability from user behavior.
+* Companies could control the platform, but let communities self-govern.
+* Facebook/Reddit are different (real names vs. pseudonyms) and in theory provide more control to users.
+* Management of communities requires a lot of effort.
+* AOL tried to reduce cost of access to voluntary moderators, but moderators realized they made benefits for AOL without sufficient compensation.
+* To offload moderation to volunteers in a cost-effective manner, they are paid with unchecked power.
+* Author thinks Slashdot moderation worked well and satisfied users, but failed in producing benefit from provocation/engagement.
+* Facebook/Reddit grant "affective voice" through karma, etc.; but not "effective voice". Exit is the most effective voice.
+* Facebook/Reddit provide moderation tools and gamify moderation (reports on groups performance to incentivize admins to maximize usage). This amplifies implicit feudalism.
+* Mark Zuckerberg has power over the Facebook group admins, and engages in democracy theater (2009 referendum on changes to terms of service, required 30% of participation, only 29% achieved, declared "advisory", did what they wanted).
+* 2015 "Reddit revolt", blackouts by making subreddits private. Reddit tightened their rules.
+* Conway law => structure of software reflects the structure of the organization.
+* Facebook/Reddit => the structure of the software shapes the structure of the organization.
+* Facebook tried to go to individuals over communities, mirroring WeChat/TikTok which have no social graphs, only driven by personal habits.
+* Because TikTok etc. do not have communities, there is less politics, but everything is still controlled by the company.
+* Implicit feudalism => control over communities, founder authority, named succession, opaque policies/decisions, supression of user voice, user exit only effective means, only platform owners resolve disputes.
+* Implicit feudalism made some sense with limited resources, but not so much with unlimited resources from large corporations.
+* Implicit feudalism is part of the business model.
+* In contrast, authocratic governments have more democratic "performances" because it resembles legitimate authority.
+* But no major online community offers possibilities of even democratic "performances".
+* Implicit feudalism is not so effective; most Reddits are small, Miecraft servers median lifetime is eight weeks.
+* Exit leads to variety, choice, innovation, but effective voice leads to comitment and stability.
+* Example of BDFL becoming inactive led to subgroups becoming more resilient.
+* Debian does not exist in isolation; sits between Linux and Ubuntu (both with BDFLs).
+* Ubuntu benefits from Debian.
+* Debian/Wikipedia combine elections with meritocratic barriers.
+* Self-governance seems to emerge more in nonprofits or cooperatives, mirroring ownership structures and technical infrastructures.
+* Usenet has some shared governance and autonomy in newsgroups.
+* Combination of different power structures helps self-governance; electoral processes + meritocratic barriers for popular but capable leaders.
+* Multiple governance mechanisms helps prevent one entity from becoming too powerful, but also allows differently-skilled users from having voice.
+* Python had PEPs, when BDFL retired they had some prior art in choosing their new governance, with elections.
+* Disassociation/cancellation => no appeals, how long does it last? Affective, not effective voice. These things come because there is no process to challenge those in power.
+* communityrule.info => online design of community rules and publication/forking. Try to make it easier to create self-governance.
diff --git a/blog/content/notes/cliffs/mythical-man-month.gmi b/blog/content/notes/cliffs/mythical-man-month.gmi
new file mode 100644
index 00000000..81080c62
--- /dev/null
+++ b/blog/content/notes/cliffs/mythical-man-month.gmi
@@ -0,0 +1,19 @@
+# The mythical man-month
+
+## Chapter 1: the tar pit
+
+"Program": complete in itself, ready to be run by the author on the system on which it was developed. What we initially develop and delivers some value is normally a program.
+
+"Programming product": can be run by anybody, in any operating environment, for many sets of data.
+
+* A programming product is thoroughly tested.
+* A programming product is thoroughly documented.
+* A programming product costs three times the cost of the program.
+
+"Component in a programming system": works as a part of a larger product.
+
+* A component in a programming system follows a well-defined interface.
+* A component in a programming system is tested in integration.
+* A component in a programming system costs three times the cost of a program.
+
+"A programming systems product" is a programming product and a component in a programming system. A programming systems product costs nine times the cost of a program.
diff --git a/blog/content/notes/cliffs/peopleware.gmi b/blog/content/notes/cliffs/peopleware.gmi
new file mode 100644
index 00000000..d7dee8de
--- /dev/null
+++ b/blog/content/notes/cliffs/peopleware.gmi
@@ -0,0 +1,272 @@
+# Peopleware
+
+## I. Managing the human resource
+
+People are different from software.
+
+### 1. Somewhere today, a project is failing
+
+* 15% of all projects deliver nothing.
+* 25% for projects >25 work/years
+* Not for technical reasons, "politics" => sociology
+
+### 2. Make a cheeseburger, sell a cheeseburger
+
+* Errors should be encouraged
+* A project objective is to be ended. Therefore, a project is never steady. Therefore, a project is always changing and there is no steady state
+* Need to think more about "why" this task needs to be done rather than how the task must be done
+
+### 3. Vienna waits for you
+
+* Spanish Theory Management: increase productivity by extracting more work for the $
+* Mechanizing development, lowering quality, standardizing procedure reduces enjoyment of work
+
+### 4. Quality-if time permits
+
+* Self-esteem makes people emotional
+* Self-esteem is tied to the quality of our work
+* Deadlines conflict with quality
+* Manager: Market wants time-to-market over quality
+* Builders: want to match their past best achieved quality, more than what the market wants
+* But quality is a means to productivity
+
+### 5. Parkinson's law revisited
+
+* "Work expands to fill the time allocated for it"
+* Parkinson was a humorist
+* Motivated people do not want to work forever in the same task
+* The team can motivate people better than the manager
+* Productivity by task estimator. No estimate > Systems analyst (unbiased expert) > Programmer > Programmer + supervisor > Supervisor
+* Bureaucratic work does expand
+
+### 6. Laetrile
+
+People are desperate to increase productivity, fall to the seven sirens, seven false hopes of software management
+
+* Missed something obvious: no
+* Others are succeeding, you are getting outdated, not using the right programming language, need more automation: technical gains affect just a small part of the total effort
+* Need to get to the bottom of the backlog: bottom of the backlog is worthless
+* Workers need more pressure
+
+## II. The office environment
+
+It's hard to increase productivity, but easy to decrease it
+
+### 7. The Furniture Police
+
+Optimizing for cost, and uniformity is not productive
+
+### 8. You never get anything done around here between 9 and 5
+
+Top performers work in quieter, more private, with less interruption, bigger spaces
+
+### 9. Saving money on space
+
+Cost of workplace is a small past of cost of worker
+
+### Intermezzo. Productivity measurement and unidentified flying objects
+
+* Gilb's Law: Anything you need to quantify can be measured in some way that is superior to not measuring it at all
+* Individual productivity should only be measured by the invidivual
+
+### 10. Brain time versus body time
+
+Interruptions are expensive
+
+### 11. The telephone
+
+Ensure people attend their email with reasonable frequency (3/day) to allow prioritizing non-interrupting communication
+
+### 12. Bring back the door
+
+People work better in quiet environments
+
+### 13. Taking umbrella steps
+
+* Developers should design the working environment
+* Windows
+* Provide outdoor space, public space
+
+## III. The right people
+
+Get the right people, make them happy, let them work
+
+### 14. The Hornblower factor
+
+* Difficult to improve people, choose well
+* Appearances << capabilities
+* Do not hire for uniformity in the company
+* No dress codes
+
+### 15. Hiring a juggler
+
+* Interviews are about performing, not talking
+* Portfolios
+* Aptitude tests are not for hiring, they are for self-assessment
+* Audition on topic related to work selected by the candidate
+
+### 16. Happy to be here
+
+* Turnover is expensive and leads to short term planning => needs quick promotions, leads to inexperienced people doing the building
+* Company moves are the worst
+* Good companies *retrain*
+
+### 17. The self-healing system
+
+* Humans can improvise, automated process cannot
+* Big M Methodologies automate: a) No improvisation, so must grow to cover all cases b) Lots of documents
+* Big M Methodologies take responsibilities away from people into the Methodology
+* Big M Methodologies lead to malicious compliance- follow the Methodology even if it has bad outcomes
+* Convergence of methods is good, easier to onboard, etc.
+* Achieve convergence of methods by training, tooling and peer review, without forcing a Methodology
+* Hawthorne Effect: people perform better when trying new approaches
+* Do new things on every project to benefit from the Hawthorne Effect
+* But have a 10-page max. standard
+
+## IV. Growing productive teams
+
+Teams working as one on a challenge are the objective. Help the team form
+
+### 18. The whole is greater than the sum of the parts
+
+* Jell: a jelled team is more than the sum of its members. Jelled teams enjoy the work
+* Jelled teams have a common objective, low turnover, strong sense of identity, feel elite, join ownership of product, enjoyment
+
+### 19. The black team
+
+* The black team tested other teams code.
+* The black team outlived the original members
+* Identity: dressed in black, some evil mustaches, mystique
+
+### 20. Teamicide
+
+You can't make a team jell, but you can prevent it from jellying:
+
+* Defensive management: preventing people from making mistakes. If the team cannot do the job, they cannot do the job.
+* Bureaucracy
+* Physical separation
+* Fragmentation of people's time: the team must be together most of the time
+* Quality reduction of the product: quality jells a team
+* Phony deadlines
+* Clique control (preventing the team for working together in further projects)
+
+### 21. A spaghetti dinner
+
+* Small successes lead to bigger successes
+* Perform small projects, demos, etc.
+
+### 22. Open kimono
+
+* Trust the team
+* Get them out of the office
+* Let skunkworks projects happen
+* Let people choose their peers and project
+* Natural authority by being competent
+
+### 23. Chemistry for team formation
+
+Some organizations have environments that favor team formation
+
+Managers do not seem busy nor manage a lot, they maintain the chemistry
+
+Chemistry building:
+
+* Cult of quality
+* I told her I loved her when I married her. Provide closure to each task. Small tasks for frequent closure
+* The Elite Team. Allow and grant uniqueness.
+* On not breaking up the yankees.
+* A network model of team behavior. Managers are not part of the team. Occasional leaders inside the team
+* Selections from a Chinese menu. Do not have a uniform team
+
+## V. It's supposed to be fun to work here
+
+### 24. Chaos and order
+
+Constructive reintroduction of small amounts of disorder:
+
+* Pilot projects. All projects as pilots, but limit experimentation
+* War games
+* Brainstorming
+* Provocative training experiences
+* Training, trips, conferences, celebrations, and retreats.
+
+### 25. Free electrons
+
+Some people should be left to work at what they want
+
+### 26. Holgar Dansk
+
+A "sleeping giant" can oppose any bad change
+
+## VI. Son of Peopleware
+
+### 27. Teamicide revisited
+
+* Those damn posters. Motivational posters tell obvious things people already know. It is demeaning
+* Overtime: An unanticipated side effect. If someone is exent of overtime, it is even more damaging
+
+### 28. Competition
+
+Internal competition inhibits jell, Prevents internal coaching. Can come from:
+
+* Annual salary or merit reviews
+* Management by objectives
+* Praise of certain workers for extraordinary accomplishment
+* Awards, prizes, bonuses tied to performance
+* Performance measurement in almost any form
+
+Musical ensembles are better metaphors of good development teams than sport teams. Individual sport teams members can have differing valoration from the rest of the team
+
+### 29. Process improvement programs
+
+* Standardized interfaces are good, standardized processes are not
+* Goal is a good product, not building it efficiently
+* Good products are risky projects, process improvement avoids risky projects
+* Better teams do more complex projects, more risk
+
+### 30. Making change possible
+
+People fear change
+
+Degrees of fear to change:
+
+* Blindly loyal (ask no questions)
+* Believers but questioners: skeptics (show me), passive observers (what's in it for me?), opposed (fear of change), opposed (fear of loss of power), militantly opposed (will undermine and destroy)
+
+Blindly loyal can abandon a change for a newer one. Only Believers but questioners can be allies to a change. Work with them to make change successful
+
+
+elebrate the old system
+
+Phases of change
+
+* Introduce foreign element/catalyst
+* Chaos
+* Transforming idea (finding the "correct training"/correct way to adopt change)
+* Practice & Integration
+* New status quo
+
+People need to feel safe for change, there should be room for some failure
+
+### 31. Human capital
+
+* Money spent of people is only lost if they leave
+* Replacing someone is expensive
+
+### 32. Organizational learning
+
+* Organizations can only learn if people stay for a long time
+* Organizations learn when middle management works together without competition and without reporting to upper management
+
+### 33. The ultimate management sin is...
+
+Wasting people's time:
+
+* Being late for meetings, blocking meetings, inviting people who don't need to be there
+* Status reporting meetings
+* Early overstaffing (and leads to fragmenting time of people)
+
+### 34. The making of community
+
+* Aristotelian politics is building communities, extending ethics to a group
+* Creatin
diff --git a/blog/content/notes/cliffs/the-tyranny-of-structurelessness.gmi b/blog/content/notes/cliffs/the-tyranny-of-structurelessness.gmi
new file mode 100644
index 00000000..3dfc17ea
--- /dev/null
+++ b/blog/content/notes/cliffs/the-tyranny-of-structurelessness.gmi
@@ -0,0 +1,98 @@
+# The tyranny of structurelessness
+
+=> https://www.jofreeman.com/joreen/tyranny.htm A copy of the original article. These Cliff's notes focus on the generic points of the article, not on its original context (the feminist movement).
+
+Leaderless, structureless groups as an organizational form is a reaction to over-structured society in which most of us live that give others control over us.
+
+Structurelessness encourages participation in discussion and personal insight, but it does not achieve more than that.
+
+Structureless groups struggle when they want to achieve something more specific than raising consciousness, because the groups do not want to change structure when they change their tasks, because they think other organizational forms can be anything but oppressive.
+
+## Formal and informal structures
+
+Structureless groups evolve into having tacit structure due to the diversity of the people that form them.
+
+Structurelessness only prevents the formation of formal structures, not informal ones. Decision-making rules are known only by those who make the decisions.
+
+To give everyone the opportunity to participate, structure must be explicit and the rules of decision-making must be open and available to everyone, so they must be formalized.
+
+## The nature of elitism
+
+Elites can only be groups, not individuals.
+
+Elites have power over a larger group without direct responsibility.
+
+A person is an elitist by being a part or advocating the elite, not by being notorious.
+
+Elites are not conspiracies, generally they are groups of friends that happen to participate in some activity together.
+
+Elites are communication networks because they are groups of friends that talk.
+
+Groups might have one or more communication networks and they might overlap. The communication networks do not necessarily have to be an elite. Multiple communication groups might compete and only one might become an elite.
+
+In a structured group, the group competition is public and other members of the group can arbitrate and make demands on the groups.
+
+Elites can be spotted in groups, they listen and don't interrupt other members more than they do with non-members. Approval of the elite is necessary for things to happen.
+
+Membership of the elite tends to have some required characteristic. Common themes are related to the friendship nature of the elite, but not to the effectiveness for the larger group's purpose.
+
+It is easier to form an elite at the beginning of the group, by bringing existing friends in. Otherwise, the elite must be formed through new effort. Elites need to maintain themselves by adding new members. Outsides might find a member of the elite to sponsor them.
+
+Elite forming and maintenance require time, so people with major commitments normally find it impossible to join. A formal structure of decision making helps the overworked (and others) participate in the group.
+
+Elites are not inevitably bad, they are only inevitable. Elites can do useful things. But elites have uncontrolled power within their group.
+
+Two negative consequences: liked people have power independently of their skills, which is bad for doing significant things; elites have no obligation to be responsible. The elite usually tries to be responsible to maintain their influence, but the group cannot compel them to be responsible, this is up to the interests of the elite.
+
+## The "star" system
+
+Society expects groups to make decisions and to select spokespeople. Society does not want to listen to all individuals in a group, they want to know what the group feels. There are only three ways to know group opinion:
+
+* Voting
+* Surveys
+* Spokespeople
+
+The public is conditioned to look for spokespeople.
+
+If there are no official spokespeople, the public might choose notable members of the group, but their opinions might not be representative of the group: "stars".
+
+The stars might not desire to be, and the members of the group might resent the stars.
+
+Stars cannot be removed by the group, because the group did not make them stars, only the press can. The press will listen to stars as long as there are no official spokespeople. Members of the group can attack the stars, who might then leave the group, remaining a star but maybe not aligned with the group.
+
+## Political impotence
+
+Sometimes the informal structure of a group might align with what the group wants to do, this gives the appearance of an effective group. However, this is hard to replicate. Normally these groups have four conditions:
+
+* They are task oriented, they were formed with a narrow and specific function.
+* They are small and homogeneous, so they have good communication reducing conflicts.
+* They have a high degree of communication. This normally limits the group to five people, although 10 to 15 is possible if they have subgroups.
+* They have a low degree of skill specialization, so everything can be done by more than one person, so no one is indispensable. (Not everything needs to be doable by everyone.)
+
+Groups composed of smaller effective groups do not tend to become more effective than their parts. These groups generates much motion and few results. These groups tend to be limited to the initial founders and exclude others, esp. the nongregarious, and elitism becomes institutionalized.
+
+Groups without projects spend their time maintaining the elite.
+
+When people cannot join the group and do things, they might do things on their own, which might lead to individual creativity, but many people cannot do this and does not foster cooperative group effort. Such people might drop out of the interests of the group, or join groups with other interests, maybe with new elites.
+
+The old elites can perceive these new elites as misaligned threats. The old elites can accuse the new elite of attracting specific groups of people from their group.
+
+The old elites can become public and formalize their original power structure as a formal structure. If the informal elite was well structured they might be able to do this, but groups that required structure the most might not be able to do it, because they adhere more to the ideology of structurelessness and they are more vulnerable to a takeover.
+
+Unstructured groups might choose to participate in larger groups with more influence and capabilities, but they can only have little influence in the larger group and their ideas might be diffused, but rarely implemented.
+
+## Principles of democratic structuring
+
+Groups should not blindly accept or ignore traditional forms of organization. These forms might be effective or not. Structure is not inherently bad, only excess of it.
+
+Essential principles:
+
+* Democratic delegation of specific authority to specific individuals. People who show interest or willingness who are selected are committed.
+* Delegates should be responsible to who selected them. This way the group controls the authorities.
+* Distribution of authority over as many people as possible, preventing monopoly of power and requiring consultations. It gives more people the opportunity for responsibility and learning.
+* Rotation of tasks among individuals to prevent responsibilities from being someone's property. But not too much rotation so that it prevents learning and satisfaction.
+* Rational allocation of tasks; by ability, interest and responsibility instead of by standing in the group. Learn through apprenticeship rather than sink or swim. Do not demoralize people by having responsibilities you cannot do well. Do not blacklist people from doing what they can do well.
+* Diffusion of information to everyone as frequently as possible, giving individuals more power.
+* Equal access to resources needed by the group. Resources owned by a member can be controlled by a member. This includes skills and information.
+
+These principles prevent informal elites.
diff --git a/blog/content/notes/greek-task-list.gmi b/blog/content/notes/greek-task-list.gmi
new file mode 100644
index 00000000..841a6a84
--- /dev/null
+++ b/blog/content/notes/greek-task-list.gmi
@@ -0,0 +1,83 @@
+# Greek task list
+
+=> https://apollos-boyfriend.tumblr.com/post/734812687645786112 From:
+
+## Icarian task
+
+When you have a task you know you’re going to fail at anyways, so why not have some fun with it before it all comes crashing down
+
+## Cassandrean task
+
+When you have to deal with people you KNOW won’t listen to you, despite having accurate information, and having to watch them fumble about when you told them the solution from the start (most often witnessed in customer service)
+
+Patroclean task: something that you have a wild misunderstanding of the difficulty involved in accomplishing properly and can only end terribly, but you dive into with your whole heart and the deep faith and conviction that you can accomplish it by sheer force of will.
+
+=> https://www.tumblr.com/bigdickfartsapolka/734815719754170368/achillean-task-something-you-are-absolutely-and From:
+
+## Patroclean task
+
+Something that you have a wild misunderstanding of the difficulty involved in accomplishing properly and can only end terribly, but you dive into with your whole heart and the deep faith and conviction that you can accomplish it by sheer force of will.
+
+=> https://www.tumblr.com/sapphoandvanzetti/791697593363218432/penelopean-task-you-dont-actually-want-the From:
+
+## Penelopean task
+
+You don't actually want the outcome of the task, so you're self-sabotaging in a clever and undetectable way to keep it from ever being completed.
+
+=> https://infosec.exchange/users/masek/statuses/115507451151625748 From:
+
+## Orphean task
+
+When you almost succeed, but lose everything the moment you turn around to check your progress.
+
+## Daedalean task
+
+When you’re forced to design something brilliant and functional… that you yourself will inevitably become trapped inside.
+
+## Medusan task
+
+When your project becomes so horrifying that everyone involved freezes in place rather than deal with it.
+
+## Tantaline task
+
+When success is right there, but bureaucracy or budget cuts keep snatching it away at the last moment, forever.
+
+## Pandoran task
+
+When fixing one small issue unleashes a thousand new ones, but hey — at least there’s still hope somewhere in the ticket backlog.
+
+## Odyssean task
+
+When the assignment technically has an end, but it’s buried under so many side quests that you forget what the original goal was.
+
+## Narcissian task
+
+When the entire effort is about maintaining appearances rather than achieving anything of substance.
+
+## Promethean task
+
+When you give people a powerful new tool that could transform their work — and are punished eternally for doing so.
+
+## Orestian task
+
+When the mess you’re cleaning up is the direct result of the last cleanup you performed.
+
+## Thesean task
+
+When the only way to finish is to disassemble everything piece by piece — until you’re no longer sure if what’s left is the same project you started.
+
+## Achillean task
+
+When your work is flawless except for that one fatal oversight that will, inevitably, destroy you.
+
+## Penelopean task
+
+When you diligently undo by night what you accomplish by day, just to keep the stakeholders pacified.
+
+## Midasean task
+
+When everything you touch turns into paperwork, compliance documents, or gold-plated nonsense nobody actually needs.
+
+## Gordian task
+
+Not intended to be actually done, but violence is the answer.
diff --git a/blog/content/notes/index.gmi b/blog/content/notes/index.gmi
new file mode 100644
index 00000000..807835d6
--- /dev/null
+++ b/blog/content/notes/index.gmi
@@ -0,0 +1,44 @@
+# Notes
+
+=> interesting-articles Interesting articles
+=> greek-task-list Greek task list
+
+## Cliff's notes
+
+Notes about some books and long articles I like:
+
+=> cliffs/mythical-man-month The Mythical Man-Month
+=> cliffs/governable-spaces Governable Spaces
+=> cliffs/peopleware Peopleware
+=> cliffs/the-tyranny-of-structurelessness The tyranny of structurelessness
+## Tech
+
+=> tech/misc-linux-stuff Misc Linux stuff
+=> tech/running-commands-in-linux Running commands in Linux
+=> tech/ssh-for-beginners SSH for beginners
+=> tech/document-formats Document formats
+=> tech/internet-communication-channels Internet communication channels
+=> tech/ledger Ledger
+=> tech/migadu Migadu
+=> tech/ripping Ripping
+=> tech/about-apis About APIs
+=> tech/about-relational-databases About relational databases
+=> tech/containers-might-not-be-the-right-answer Containers might not be the right answer
+=> tech/crud-is-an-important-unsolved-problem CRUD is an important unsolved problem
+=> tech/about-django About Django
+=> tech/git-advice Git advice
+=> tech/github-annoyances GitHub annoyances
+=> tech/prolog-vs-sql Prolog vs. SQL
+=> tech/take-the-less-traveled-road Take the less traveled road
+=> tech/the-tragedy-of-the-geeks The tragedy of the geeks
+=> tech/misc-python-stuff Misc Python stuff
+=> tech/python-modules-primer Python modules primer
+=> tech/so-you-want-to-play-with-functional-programming So you want to play with functional programming
+=> tech/motivating-example-for-logical-replication-for-dynamic-ui Motivating example for logical replication for dynamic UI
+=> tech/about-web-development About web development
+
+### Gadgets
+
+=> tech/gadgets/about-headphones About headphones
+=> tech/gadgets/x12 Lenovo ThinkPad X12 Detachable Gen 1
+=> tech/gadgets/pocket-computers Pocket computers
diff --git a/blog/content/notes/interesting-articles.gmi b/blog/content/notes/interesting-articles.gmi
new file mode 100644
index 00000000..73e8f881
--- /dev/null
+++ b/blog/content/notes/interesting-articles.gmi
@@ -0,0 +1,195 @@
+# Interesting articles
+
+## General
+
+=> https://lukeplant.me.uk/blog/posts/no-one-actually-wants-simplicity/ No one actually wants simplicity
+Simplicity is sacrifice. See also:
+=> https://www.youtube.com/watch?v=SxdOUGdseq4 simple made easy (video)
+=> https://www.seangoedecke.com/wicked-features/ wicked features
+
+=> https://www.geoffreylitt.com/2025/03/03/the-nightmare-bicycle.html Avoid the nightmare bicycle
+Good designs expose systematic structure; they lean on their users’ ability to understand this structure and apply it to new situations.
+
+## Programming
+
+=> https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html The Configuration Complexity Clock
+Programming languages, configuration files, DSLs for configuration
+
+=> https://olano.dev/2023-11-30-code-is-run-more-than-read/ Code is run more than read
+A unified theory of broken software
+
+=> https://www.teamten.com/lawrence/writings/java-for-everything.html Java for Everything
+The advantages of focusing on a single language and how performance and static typing are helpful.
+
+=> https://en.wikipedia.org/wiki/Ostrich_algorithm Ostrich algorithm
+
+=> https://blog.brownplt.org/2024/04/12/behavior-misconceptions.html Finding and Fixing Standard Misconceptions About Program Behavior
+About the Standard Model of Languages (SMoL)
+
+=> https://dannorth.net/best-simple-system-for-now/ Best Simple System for Now
+A view I disagree on about IAGNI and the opposite concepts, but interesting
+
+=> https://mmapped.blog/posts/38-static-types-perfectionism Static types are for perfectionists
+Our programming style is influenced by our personality and life
+
+=> https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/ Making wrong code look wrong
+The history about Hungarian notations
+
+=> https://www.hillelwayne.com/talks/ese/ddd/ What We Know We Don't Know: Empirical Software Engineering
+40-minute video about the power of proper sleep, working schedules and stress levels vs. engineering practices
+
+=> https://www.hillelwayne.com/post/we-are-not-special/ We are not special
+Second of a series of three articles comparing software engineering with traditional engineering. Mostly dispels some myth and lack of knowledge about traditional engineering.
+
+### Testing
+
+=> https://testing.googleblog.com/2014/05/testing-on-toilet-risk-driven-testing.html Testing on the Toilet: Risk-Driven Testing
+"Your tests are a means. The bang is what counts. It’s your job to maximize it."
+
+=> https://testing.googleblog.com/2024/10/smurf-beyond-test-pyramid.html SMURF: Beyond the Test Pyramid
+Test categories and the pyramid are excessively limited models.
+
+### Python
+
+=> https://lukeplant.me.uk/blog/posts/pythons-disappointing-superpowers/ Python’s "Disappointing" Superpowers
+A convincing defense of dynamic typing
+
+### Rust
+
+=> https://www.hezmatt.org/~mpalmer/blog/2024/05/01/the-mediocre-programmers-guide-to-rust.html The Mediocre Programmer's Guide to Rust
+=> https://qouteall.fun/qouteall-blog/2025/How%20to%20Avoid%20Fighting%20Rust%20Borrow%20Checker How to Avoid Fighting Rust Borrow Checker
+
+### Optimization
+
+=> https://docs.oracle.com/cd/E11882_01/server.112/e41573/technique.htm The Oracle Performance Improvement Method
+My favorite text about performance tuning- the good advice is not Oracle-specific. Includes a bit more real-world advice than:
+=> https://users.ece.utexas.edu/~adnan/pike.html Rob Pike's 5 Rules of Programming
+
+=> https://infrequently.org/series/performance-inequality/ The Performance Inequality Gap, 2024
+=> https://danluu.com/slow-device/ How web bloat impacts users with slow devices
+About janky browser applications and websites.
+
+### Git
+
+=> https://blog.gitbutler.com/git-tips-3-really-large-repositories/ Git Tips 3: Really Large Repositories
+
+### Accessibility
+
+=> https://xogium.me/the-text-mode-lie-why-modern-tuis-are-a-nightmare-for-accessibility The text mode lie: why modern TUIs are a nightmare for accessibility
+
+## Systems
+
+=> https://chrisdown.name/2018/01/02/in-defence-of-swap.html In defence of swap: common misconceptions
+
+## Organizations
+
+=> [[https://charity.wtf/2024/07/24/pragmatism-neutrality-and-leadership/ Pragmatism, Neutrality and Leadership
+(The parts about "As a leader, your job is to succeed", "Companies with shitty cultures win all the time".) This article connects with:
+=> https://hbr.org/2007/03/why-i-wrote-the-no-asshole-rule The no asshole rule book
+
+=> https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/ The Engineer/Manager Pendulum
+Why people should multiclass engineering and management
+
+=> https://varoa.net/2024/01/09/how-organisations-cripple-engineering-teams-with-good-intentions.html How organisations cripple engineering teams with good intentions
+Arguments for having coders code
+
+=> https://stackoverflow.blog/2024/06/10/generative-ai-is-not-going-to-build-your-engineering-team-for-you/ Generative AI Is Not Going To Build Your Engineering Team For You
+Bad title; it's about the need for junior coders
+
+=> https://luminousmen.com/post/senior-engineer-fatigue Senior Engineer Fatigue
+
+=> https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/ Things You Should Never Do, Part I
+About rewriting software from scratch
+
+=> https://dl.acm.org/doi/10.1145/1464122.1464146 Some observations concerning large programming efforts
+Someone figured most of it out in 1964.
+
+=> https://www.jofreeman.com/joreen/tyranny.htm The tyranny of structurelessness
+=> cliffs/the-tyranny-of-structurelessness (My Cliff's Notes)
+
+=> https://www.lesswrong.com/posts/tscc3e5eujrsEeFN4/well-kept-gardens-die-by-pacifism Well-Kept Gardens Die By Pacifism
+About moderation in small communities
+
+### Project management
+
+=> https://apenwarr.ca/log/20171213 An epic treatise on scheduling, bug tracking, and triage
+No non-sense opinions on project management I mostly agree with
+
+## News
+
+=> https://www.currentaffairs.org/2020/08/the-truth-is-paywalled-but-the-lies-are-free/ The Truth Is Paywalled But The Lies Are Free
+Excellent title, but the article is so-so
+
+## Society
+
+=> https://locadeldesvan.com/2025/01/09/contra-la-tecnocratizacion-de-la-vida/ Contra la tecnocratización de la vida
+About the pressure of the modern age and the privilege of being mediocre
+
+=> https://www.experimental-history.com/p/face-it-youre-a-crazy-person Face it: you're a crazy person
+Choosing a job because you like the worst parts of it
+
+## Epistemology?
+
+=> https://hermiene.net/essays-trans/relativity_of_wrong.html The Relativity of Wrong by Isaac Asimov
+All physics theories are strictly "false", but they are very true.
+
+## Meta
+
+=> https://www.benkuhn.net/progessays/ Essays on programming I think about a lot
+=> https://www.piglei.com/articles/en-programmer-reading-list-part-one/ A Programmer's Reading List: 100 Articles I Enjoyed (1-50)
+
+## Infrequent but useful terms
+
+=> https://en.wikipedia.org/wiki/Abilene_paradox The Abilene paradox
+A collective fallacy, in which a group of people collectively decide on a course of action that is counter to the preferences of most or all individuals in the group, while each individual believes it to be aligned with the preferences of most of the others.
+
+=> https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect The Dunning–Kruger effect
+A cognitive bias in which people with limited competence in a particular domain overestimate their abilities. Some researchers also include the opposite effect for high performers: their tendency to underestimate their skills. In popular culture, the Dunning–Kruger effect is often misunderstood as a claim about general overconfidence of people with low intelligence instead of specific overconfidence of people unskilled at a particular task.
+=> https://www.frontiersin.org/journals/psychology/articles/10.3389/fpsyg.2022.840180/full A Statistical Explanation of the Dunning–Kruger Effect
+This effect might only be caused by subjects in the bottom quartile can only make optimistic errors placing themselves into a higher quartile, while subjects in the top quartile can only make pessimistic errors placing themselves in a lower quartile.
+
+=> https://en.wikipedia.org/wiki/Gell-Mann_amnesia_effect The Gell-Mann amnesia effect
+A cognitive bias describing the tendency of individuals to critically assess media reports in a domain they are knowledgeable about, yet continue to trust reporting in other areas despite recognizing similar potential inaccuracies.
+
+=> https://en.wikipedia.org/wiki/Goodhart%27s_law Goodhart's law
+An adage that has been stated as, "When a measure becomes a target, it ceases to be a good measure".
+
+=> https://en.wikipedia.org/wiki/McNamara_fallacy The McNamara fallacy
+(Also known as the quantitative fallacy) involves making a decision based solely on quantitative observations (or metrics) and ignoring all others.
+
+=> https://en.wikipedia.org/wiki/Hanlon%27s_razor Hanlon's razor
+An adage, or rule of thumb, that states: Never attribute to malice that which is adequately explained by stupidity.
+
+=> https://en.wikipedia.org/wiki/Hawthorne_effect The Hawthorne effect
+A type of human behavior reactivity in which individuals modify an aspect of their behavior in response to their awareness of being observed.
+
+=> https://en.wikipedia.org/wiki/Novelty_effect Novelty effect
+An effect of introducing new elements on some activity or behavior.
+
+=> https://softwareengineering.stackexchange.com/questions/123627/what-are-the-london-and-chicago-schools-of-tdd What are the London and Chicago schools of TDD?
+
+=> https://en.wikipedia.org/wiki/Sturgeon%27s_law Sturgeon's law
+An adage stating "ninety percent of everything is crap".
+
+=> https://en.wikipedia.org/wiki/Schedule_chicken Schedule chicken
+When two or more parties working towards a common goal all claim to be holding to their original schedules for delivering their part of the work, even after they know those schedules are impossible to meet. Each party hopes the other will be the first to have their failure exposed.
+
+=> https://everything2.com/title/Your+radical+ideas+about+society%252C+individualism%252C+and+religion+have+already+occurred+to+others Your radical ideas about society, individualism, and religion have already occurred to others
+
+=> https://en.wikipedia.org/wiki/Slate_Star_Codex#Lizardman's_Constant Lizardman's constant
+The approximate percentage of responses to a poll, survey, or quiz that are not sincere
+
+See also:
+
+=> greek-task-list Greek task list
+
+Sources:
+
+=> https://en.wikipedia.org/wiki/List_of_paradoxes List of paradoxes
+=> https://en.wikipedia.org/wiki/Unintended_consequences Unintended consequences
+
+## Lost and not found
+
+Some articles I'd like to find here, but haven't been able to find again:
+
+* Enqueuing function calls vs. extending your domain model: This article discussed using traditional queues for handling some actions in your application vs. doing this "declaratively". For example, enqueue "send notification about x to user y" vs. "add column 'needs_x_notification to users table". If I remember correctly, the article contained some insightful arguments for the latter approach I had not thought of.
diff --git a/blog/content/notes/tech/about-apis.gmi b/blog/content/notes/tech/about-apis.gmi
new file mode 100644
index 00000000..f1732cc9
--- /dev/null
+++ b/blog/content/notes/tech/about-apis.gmi
@@ -0,0 +1,26 @@
+# About APIs
+
+=> https://gist.github.com/kislayverma/d48b84db1ac5d737715e8319bd4dd368 The Jeff Bezos' API memo is one of the most talked stories about API programming.
+
+It is, in my opinion, also one of those things which are successful for some environments, but not for all.
+
+## The levels of API accessibility
+
+An "operation" in your application can be in one of the following levels of "API accessibility":
+
+* -oo The operation cannot be invoked in isolation easily. For instance, it is embedded in an MVC controller, mixed with form handling and HTML generation, and thus the best approach to invoke it programatically is to simulate a browser
+* 0 The operation can be invoked, in-process, by calling a function or method, but requiring complex setup or using complex types (e.g. others than lists, maps, numbers and strings)
+* 1 The operation can be invoked, in-process, by calling a function without complex setup and using plain types
+* 2 The operation can be invoked, off-process, by calling a function without complex setup and using plain types
+* 3 The operation can be invoked via a command line tool
+* 4 The operation can be invoked via a network call
+
+Many proponents of APIs propose level 4 as the target. This obviously allows your operations to be integrated in separate processes via network calls, which is the most powerful way of API access. They will also reason that this will force your application to have a clean architecture with separation of concerns.
+
+Note also that doing proper testing will probably force your operations to be tested to be in levels 0-2, as otherwise it will be annoyingly complex to test them.
+
+We propose that the architecture benefits of level 4 are also present in levels 0-3, but achieving these levels requires much less effort than achieving level 4 (where you need to add a network protocol, handle aspects such as authentication/authorization, marshalling/unmarshalling, etc.), so unless you require level 4, you can stay in levels 0-3. Going to level 3 instead of 0 should be easy when creating new operations, so that's the level of API accessibility we recommend new code to adhere to by default.
+
+Note also that level 3 can provide many benefits of level 4, but with less development overhead, so it's a level we recommend considering explicitly, as it is often overlooked.
+
+Level -oo is typical of legacy applications. Note that we consider the distance between level -oo and the rest of levels much bigger than the distance between the rest of levels.
diff --git a/blog/content/notes/tech/about-django.gmi b/blog/content/notes/tech/about-django.gmi
new file mode 100644
index 00000000..15f73600
--- /dev/null
+++ b/blog/content/notes/tech/about-django.gmi
@@ -0,0 +1,115 @@
+# About Django
+
+Without more context, one of the technologies I recommend to everyone is Django.
+
+Django is a Python web framework with "batteries included".
+
+Web frameworks can provide more or less tools to write applications. Typically, frameworks that provide fewer tools are more flexible and give developers more freedom to develop their applications in the best possible way. Similarly, frameworks that provide more tools tend to guide you towards a specific way to writing applications, and typically, require more work if you want to deviate.
+
+In my opinion, many applications you might need to develop are very similar and have similar issues, and solving them ad-hoc for each project is a waste. Therefore, I lean towards using frameworks that provide more batteries in most cases.
+
+(Certainly, there are projects that clearly need special approaches, or which deviate enough from any generic web framework.)
+
+In fact, most of the complaints described in this document are caused by Django having too few batteries, not too many!
+
+=> https://github.com/alexpdp7/django-tws Django training wheels is my project in alpha to address some of those shortcomings.
+
+## The Django admin
+
+Besides including more batteries than most other frameworks, and being in general a well-engineered framework in my opinion, Django includes the admin.
+
+The admin is a declarative way to build administrative sites where some users edit data stored in the application database.
+
+Many similar tools exist, but I have not found any other tool that can do so much.
+
+* The Django admin handles multi-table relationships very well, including picking foreign key targets and editing related table data. For example, if a person entity has a "parent" related foreign key relationship, the Django admin provides a search functionality to pick a person's parent. If the person entity has a list of children, the Django admin provides a way to add and edit children from the person form.
+* The Django admin has a simple, but useful for many scenarios permissions functionality, where editing certain entities is restricted to groups of users.
+
+The Django admin is frequently a big boost during the early development of database-backed applications, and sometimes it can provide value during a big part of the life of an application.
+
+Additionally, traditionally when working with frameworks without an equivalent facility, the friction of adding an interface to edit a piece of data can be large. Developers pressed for time might opt to hardcode the data in the source code of the application, requiring code changes to modify certain behaviors of the application. When the friction to add a user interface to edit such data is low, developers can configure the admin to let those users edit the data directly without going through the developers.
+
+## Django problems
+
+However, there are still many common issues for which batteries could exist, but that Django does not provide.
+
+### Django has no support or documentation about packaging Django projects
+
+Most Django projects have dependencies besides Django. In order to develop and deploy Django applications, you likely must install other dependencies. Django does not include documentation nor support to do this.
+
+Many different approaches and tools exist to manage Python project dependencies. Understandably, endorsing one particular approach in Django could be controversial.
+So Django leaves the choice of approach up to users. Additionally, Django adds a few difficulties in Python project management, and users must figure out how to handle Django projects in their chosen approach.
+
+Several initiatives have tried to tackle this problem, notably:
+
+=> https://github.com/radiac/nanodjango nanodjango
+
+### Django settings are a partial solution
+
+Django provides settings to manage the configuration for a Django project. You implement Django settings by writing a Python module.
+
+For example, the default Django template includes the following snippet to configure the database connection:
+
+```
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+```
+
+Besides assigning a setting directly like in the preceding snippet, you can use Python code to assign settings.
+
+This allows you to tackle many common issues, such as setting up a different database connection for development and production, while keeping the production database credentials away from the source code repository. There are many similar issues that you must tackle in nearly all projects.
+
+Several initiatives tackle some of those issues:
+
+=> https://github.com/jazzband/dj-database-url dj-database-url provides a way to configure the database connection through an environment variable.
+
+### Django does not explain a development database workflow
+
+Django provides migrations to handle schema changes. Migrations work well and are a valid solution to handle schema changes in production.
+
+However, while developing a Django application, you frequently need to make many temporary changes to the data definition until you find the right data definition.
+
+In my opinion, if you follow the Django documentation, then you might end up using migrations for those development schema changes. This is awkward and problematic, and there are procedures to develop database changes that work better.
+
+I would like a command that recreates your database, applying unmigrated model changes. This command could also have hooks to load sample data. (Likely, Python code and not fixtures.)
+
+### Django only tackles database-based, server-side-rendered, non highly interactive web applications
+
+While certainly a huge amount of applications:
+
+* Revolve around data stored in a relational database
+* Are better implemented as server-side rendering applications
+* Do not require very complex or real-time interactions
+
+There are certainly many applications that do not fit this mold.
+
+In my opinion, focusing on database-based applications is a good decision. Many Django features (like the admin) revolve around the database, and a framework oriented to other applications likely should be very different.
+
+However, more and more applications break the limits of server-side rendering, and while you can build such applications with Django, you need a lot of effort or finding additional libraries to use.
+
+For example:
+
+* Django REST framework provides a layer to provide REST APIs on top of the Django ORM.
+* Projects exist to add support for Django for front end frameworks such as htmx or Hotwire. These frameworks are an intermediate step between traditional server-side-rendered applications and JavaScript front ends, enabling most of the benefits of JavaScript front ends within the traditional server-side rendering approach.
+
+Additionally, providing an API is also useful beyond JavaScript front ends. APIs are necessary for other purposes, such as implementing mobile apps to interact with your application, or just providing an API for programmatic access to your application.
+
+### Some common tasks should have more tutorial content
+
+The Django documentation is mostly for reference, covering all Django features, but with little content on how to use Django. The items I list below likely are documented on books, websites, forums, etc. If you know a good source for many of those, even if it is paid, feel free to let me know to add references.
+
+* Restricting users in the admin to a subset of the instances of a model.
+
+For example, users belong to organizations and users should only see instances of some model related to their organization. The FAQ contains "How do I limit admin access so that objects can only be edited by the users who created them?", which is a very similar question and points to the features you need to use to achieve these goals. These requirements are often related to requiring "extending the existing User model".
+
+* Having a search UI for reference fields instead of dropdowns.
+
+Many projects similar to the admin only offer dropdowns for reference fields. This does not work when the referenced objects are more than a couple. Django calls this raw_id_fields, and it is difficult to learn that this feature exists.
+
+## Further reading
+
+=> crud-is-an-important-unsolved-problem CRUD is an important unsolved problem
diff --git a/blog/content/notes/tech/about-relational-databases.gmi b/blog/content/notes/tech/about-relational-databases.gmi
new file mode 100644
index 00000000..d08071ac
--- /dev/null
+++ b/blog/content/notes/tech/about-relational-databases.gmi
@@ -0,0 +1,27 @@
+# About relational databases
+
+## What is a relation?
+
+A common misconception is that the "relations" in a relational database are about relations between database tables.
+
+Actually, the relations in a relational database are the tables.
+
+A relation "relates" a set of values with another set of values.
+
+For example, a relation can relate the name of a person with their birth date and birth place. For example:
+
+(person name) => (birth date, birth place)
+(Alice) => (1979-12-03, Barcelona)
+(Bob) => (1995-03-04, Paris)
+...
+
+Many computer languages have similar concepts:
+
+* Python mapping types such as dict
+* C++ std::map
+* Java java.util.Map
+* C# System.Collections.Generic.Dictionary
+* JavaScript Object
+* PHP arrays
+
+Relations are a natural concept, so although non-relational data systems exist, most data can be stored as relations.
diff --git a/blog/content/notes/tech/about-web-development.gmi b/blog/content/notes/tech/about-web-development.gmi
new file mode 100644
index 00000000..bcc54cb8
--- /dev/null
+++ b/blog/content/notes/tech/about-web-development.gmi
@@ -0,0 +1,5 @@
+# About web development
+
+* Ensure that the website is as functional as possible using limited browsers such as Lynx, ELinks, w3m, or Dillo. (If you use a browser that can display images, ensure that the website is as functional as possible with images disabled too.)
+* Make sure all content in the website has a URL that can be shared conveniently.
+* If website users would benefit from learning about updates to your website, then provide well-visible open ways to follow updates, such as RSS/Atom feeds, email subscriptions, or ActivityPub feeds.
diff --git a/blog/content/notes/tech/containers-might-not-be-the-right-answer.gmi b/blog/content/notes/tech/containers-might-not-be-the-right-answer.gmi
new file mode 100644
index 00000000..de614983
--- /dev/null
+++ b/blog/content/notes/tech/containers-might-not-be-the-right-answer.gmi
@@ -0,0 +1,100 @@
+# Containers might not be the right answer
+
+Containers are everywhere, and I feel today they are the default answer to many problems for many people.
+
+=> https://www.jwz.org/blog/2014/05/so-this-happened/ Although the author of one of the handiest quotes does not want people to use it, I think that quote adequately describes the situation. Definitely, containers are no silver bullet.
+
+Containers are a good example of an “easy but not simple” technique.
+
+=> https://www.youtube.com/watch?v=SxdOUGdseq4 (See the "Simple Made Easy" - Rich Hickey 2011 talk.)
+
+Containers are easy because they automate getting arbitrary "isolated" Linux environments and running processes on them. Additionally, you can find container images for mostly everything on the Internet. For this reason, it is very easy to run much software using containers, often with a single command.
+
+However, containers are easy, but not simple. Containers combine many different techniques to achieve their ease, and thus, frequently you hit problems derived from any of the techniques containers use.
+
+However, Docker popularized many good ideas, both directly related to containerization and general ideas! There are still places where containers are the right answer.
+
+## Reasons not to use containers
+
+### Containers are Linux
+
+The fact that containers are a Linux technology is the most common point of complexity.
+
+One result of this is that using containers on any operating system that is not Linux, such as Windows or macOS, requires a Linux virtual machine.
+
+This has some accidental problems, like increased memory and CPU usage, and derived inconveniences like decreased battery life and fan noise.
+
+But the main issue is that adding this VM makes things more complex, mostly because you are adding networking to the mix, and some container features are not available or work worse, like bind mounts.
+
+Most issues can be worked around, but this requires more effort, or at least, more knowledge overhead of knowing how to avoid these issues.
+
+(On top of that, people who develop processes using Linux are not exposed to these issues, so they are likely to introduce issues without realizing what works on their Linux workstation does not work on macOS or Windows workstations.)
+
+### Container images are big and expensive
+
+Optimizing the size of container images can require significant effort. Popular public images are often optimized for size, but even with optimized images, storing and moving container images frequently requires much more bandwidth and storage than the alternatives.
+
+There are free ways to host private container images, but they are frequently limited in size, bandwidth, or both. You can easily run into Docker Hub limits, GitHub only provides 2gb of storage, etc.
+
+Building container images also can require significant resources.
+
+### Containers require specialized knowledge
+
+Using containers frequently requires learning quite a few things specific about containers.
+
+* Containerfile design is not obvious. Some questions, like ADD and COPY, or CMD and ENTRYPOINT are difficult and not well documented.
+
+* Container design is not obvious. Docker popularized "application containers", a fuzzy concept that is related to "single process containers", 12 factor architecture, and a few other ideas. Solving your problem might require good knowledge of application container design and use.
+
+* Container tools are complex, because containerization is difficult. Likely you need to know some intricate details of how Linux file permissions and users work, for example.
+
+Not using containers can mean avoiding having to think about these things, and being able to use the time you save to actually solve your problem.
+
+### Docker is not so good, targeting multiple container engines is not trivial
+
+Docker was the first popular container engine. Docker was a revolution and invented or popularized many great ideas. However, knowledge about containers was not well established when Docker was invented, and since then, better ways of doing many things have been discovered.
+
+Other tools such as Podman or Fedora Toolbx and adjacent tools such as Distrobox have introduced many improvements respect Docker, while still reusing and being compatible with many Docker concepts.
+
+However, creating processes and tools across these different tools can be difficult, despite their apparent compatibility.
+
+### In some scenarios, containers do not add much
+
+Mainly after the rise of the Go programming language, distributing binaries has become easier. Distributing binaries on Windows and macOS has always been simpler than distributing binaries on Linux.
+
+However, nowadays many programming languages can create binaries that can be downloaded and executed on most Linux distributions.
+
+One of the main benefits of Docker has been ease of distribution of software, but nowadays this is easy to achieve through binaries.
+
+### Beware container images
+
+Much software is distributed nowadays as container images. The abundance of container images means that learning how to use containers helps you run a wide variety of software distributed as a container image.
+
+However, many container images are not of great quality, nor are adequately updated.
+
+In some cases, you can find software that has a container image, but where the container image is not of sufficiently good quality and can cause issues down the road.
+
+## Reasons to use containers
+
+### Containers still provide isolation easily
+
+By default, running a container does not alter the system that runs the container significantly.
+
+This is a huge advantage, and in many cases, more difficult to accomplish without containers.
+
+### Making things work across different operating systems is not trivial either
+
+Some decisions in software, like programming language or dependency choices, influence greatly how easy running the software on different operating systems is.
+
+In many cases, making something run in a specific distribution and packaging as a container can be the most resource-efficient way to distribute software that works across Windows, macOS, and most Linux distributions.
+
+Finding the right combination that makes software portable can require significant effort, or even be unviable.
+
+### Some container-related software has good and unique ideas
+
+For example, the controversial Kubernetes still provides a distributed standardized operating system that can be managed in a declarative way. This is a powerful concept, and still the preferred way to package software for Kubernetes depends on container images.
+
+## What to use instead of container images
+
+* Binaries
+* "Portable-friendly" development tools such as Go, uv, or Cargo.
diff --git a/blog/content/notes/tech/crud-is-an-important-unsolved-problem.gmi b/blog/content/notes/tech/crud-is-an-important-unsolved-problem.gmi
new file mode 100644
index 00000000..c338f785
--- /dev/null
+++ b/blog/content/notes/tech/crud-is-an-important-unsolved-problem.gmi
@@ -0,0 +1,78 @@
+# CRUD is an important unsolved problem
+
+The CRUD (initials of create, replace, update, and delete) term is used to describe the implementation of applications that provide a simple interface to a database.
+
+If you have used a computer for work, then you likely have used a system that allows to manipulate records of customers, orders, products, or any other information related to the business.
+
+Although programmers have been written a huge amount of CRUD systems for decades, my perception is that the costs of implementing CRUD systems is a major problem with important consequences.
+
+There are two major approaches to implementing CRUD systems:
+
+* Traditional programming: combining a relational database and most existing programming languages enables programmers to create CRUD systems.
+* "No code" (or "low code"): many products and services enable non-programmers to describe their data structure and the user interface requiring less technical knowledge than the traditional programming approach.
+
+## About implementing CRUD systems with traditional programming
+
+The Python Django web framework coupled with a relational database requires writing the least code of all the platforms I have used to write CRUD systems.
+
+Most of what you need to do when using Django is to describe what you need, instead of implementing the mechanical parts of a CRUD system.
+
+Out of the box, Django provides:
+
+* List and detail views, including nested views. Many systems provide "flat" details view where you can edit a record, but not associated records. For example, they provide a detail view for customers where you can edit the customer name and other information, but any "multiple" information, such as multiple addresses or phone numbers, must be edited in a different view. This is frequently a huge issue, and it can require writing a significant amount of code in other systems. With Django, you can implement this by describing the associated data.
+* Multi user authentication and role-based authentication. With Django and without programming any code, administrators can create groups, assign users to groups, and limit the kinds of records that each group can view or edit.
+* Primitive change tracking. Out of the box, changes to records are tracked automatically and can be consulted.
+
+For most CRUD implementations, alternative platforms require significantly more effort to implement those features.
+
+Additionally, the entire stack is open source software that does not require paying licenses.
+
+(Surprisingly, in the past there existed even more sophisticated CRUD platforms. But sadly, most have disappeared.)
+
+## About implementing CRUD systems with no code
+
+A huge amount of systems provide similar functionality, in an even more friendly manner.
+
+They typically provide a user interface where you can create tables, add columns, and describe the user interface without programming.
+
+Some of those systems offer features comparable or superior to Django.
+
+However, because those systems focus on no code usage, frequently you hit roadblocks when using them.
+
+When you need a feature that they do not provide, it is either impossible to do it, or it requires programming in an unfriendly environment.
+
+Programming CRUD features can be complex. While traditional programming tools have evolved providing many features such as automated testing and advanced code revision control systems (rolling back bad changes and others), no code CRUD platforms do not reuse the wealth of programming tools that have been developed for traditional programming.
+
+Non-developers frequently face huge challenges going beyond the basics of what the tool provides, and developers struggle and suffer by working in environments that are more limiting compared to others.
+
+## The consequences of the high cost of development of CRUD systems
+
+In these conditions, most CRUD systems are expensive and do not work well.
+
+Organizations often resort to systems such as spreadsheets that can be productive, but have severe reliability concerns.
+
+No code CRUD systems often have significant costs and lock in their customers, because migrating costs can be astronomical.
+
+CRUD systems implemented with traditional programming often are costly to maintain and extend.
+
+In most cases, organizations cannot justify the costs of tailoring the CRUD system entirely to their needs, so they suffer from using CRUD systems that do not meet their needs.
+
+## Possible approaches
+
+### Improving existing traditional programming CRUD platforms
+
+I believe systems such as Django can still see many improvements. Likely, both the amount of technical knowledge to use these systems and the amount of effort to design CRUD systems can be reduced significantly.
+
+### Providing systems to transition from no code approaches to traditional programming
+
+No code approaches are wonderful, because giving end users the ability to describe what they need enables them to experiment and become productive very quickly.
+
+However, no code platforms cannot provide all features needed, and in many cases, end users will struggle past a certain point.
+
+Providing a way to migrate to a traditional programming approach would enable breaking this barrier and scaling systems more effectively.
+
+(Some no code platforms have APIs. With them, programmers can write code to extend the no code CRUD systems using traditional programming approaches. However, implementing functionalities through APIs has limitations and specific problems.)
+
+## Further reading
+
+=> about-django About Django
diff --git a/blog/content/notes/tech/document-formats.gmi b/blog/content/notes/tech/document-formats.gmi
new file mode 100644
index 00000000..385c0c0e
--- /dev/null
+++ b/blog/content/notes/tech/document-formats.gmi
@@ -0,0 +1,97 @@
+# Document formats
+
+Most of the time, when writing a document, I want a document format with the following properties:
+
+* Fast to write using a plain text editor
+* Easy to parse into an AST
+
+An AST is a programming-friendly representation of a document. ASTs reduce the effort required to write tools such as a program that validates links in a document. Ideally, ASTs contain information to track a document element to the position it occupies in the original document. With this information, if you write a tool such as a spell checker, then you can highlight misspelled works precisely in the original document.
+
+On top of that, some features that I don't always need:
+
+* Math support
+* Sophisticated code blocks. For example, being able to highlight arbitrary parts of code blocks (not syntax highlighting).
+* Diagram support
+
+## Existing formats
+
+### Markdown
+
+* Easy to write using a plain text editor
+* Has good AST parsers with position information
+* Has math support
+* Does not support sophisticated code blocks
+* There are many extensions with support for math, diagrams, and many others
+* Is very popular and supported everywhere
+* However, there is a wide variety of variants and quirks
+* Especifically, because Markdown was not designed with parsing in mind, so tools based on different parsers can have differences in behavior
+
+### Djot
+
+=> https://djot.net
+
+It is very similar to Markdown, except:
+
+* It is designed for parsing, so independent parsing implementations are very compatible with each other
+* It is not so popular, so there are less extension and tool support
+
+### AsciiDoc
+
+=> https://asciidoc.org
+
+Compared to Markdown:
+
+* It's more complex to write, but mostly because it's different and more powerful
+* There are attempts to write better parsers, but good parsers with position information are not available yet
+* Supports sophisticated code blocks
+* It has a smaller ecosystem than Markdown, but many good quality tools such as Antora
+
+### Typst
+
+=> https://typst.app
+
+Checks all my boxes, except:
+
+* It is designed for parsing and it has an AST, but it is not easy to access
+* Currently Typst is very oriented towards generating paged documents (e.g. PDF)
+* It includes a full programming language, which is mostly good (very extensible), but this might increase complexity undesirably
+
+Typst is very new and is not yet very popular.
+
+=> https://codeberg.org/haydn/typesetter Typesetter is a desktop application that embeds Typst, so no additional setup is needed. However, Typesetter is only available as a Flatpak.
+
+### Verso
+
+=> https://github.com/leanprover/verso
+
+A Markdown-like closely tied to the Lean programming language.
+
+* Eliminates ambiguous syntax for easier parsing and is stricter (not all text is valid Verso)
+* Has a (Lean) data model
+* Designed for extensibility
+
+### TODO: other formats
+
+=> https://github.com/nota-lang/nota Nota (a document language for the browser)
+=> https://github.com/christianvoigt/argdown Argdown (for argumentation)
+=> https://github.com/podlite/podlite Podlite
+=> https://orgmode.org Org Mode (an Emacs-based tool based on a lightweight markup language)
+=> https://github.com/nvim-neorg Neorg (similar to Org Mode for Neovim)
+=> https://github.com/sile-typesetter/sile Sile (typesetting system)
+
+## Creating your own formats
+
+=> https://github.com/spc476/MOPML Someone created its own lightweight format using Lua and PEGs.
+=> https://tratt.net/laurie/blog/2020/which_parsing_approach.html "Which parsing approach" has information about choosing parsing approaches.
+
+## About gemtext
+
+=> https://geminiprotocol.net/docs/gemtext-specification.gmi
+
+Gemtext is an extremely minimalistic markup language designed for use with the Gemini protocol (an extremely minimalistic protocol similar to HTTP).
+
+The Gemini protocol and gemtext are intentionally designed to limit their power, in my opinion as a comment on the web.
+
+This document is gemtext-native for use in my own minimalistic publishing system.
+
+I also use it as a statement, although the limitations of gemtext can be significant in technical writing. For example, gemtext has no inline links, no inline verbatim code, only three levels of headings, etc.
diff --git a/blog/content/notes/tech/gadgets/about-headphones.gmi b/blog/content/notes/tech/gadgets/about-headphones.gmi
new file mode 100644
index 00000000..99cce0a3
--- /dev/null
+++ b/blog/content/notes/tech/gadgets/about-headphones.gmi
@@ -0,0 +1,152 @@
+# About headphones
+
+There is not a perfect set of headphones.
+
+## Headphones I use
+
+These are a few notes about the headphones I use, with pros/cons.
+
+### Shokz OpenComm / MONODEAL MD08 PRO
+
+These are my favorite headphones for remote work, meaning calls. Shokz are bone conduction, meaning they do not go over your ear, or inside your ear, but rather sit on your temples. They vibrate on near the bones in your ear. This produces a strange sensation, but has many advantages (and disadvantages).
+
+* These are the most comfortable headphones I have ever tested. I can literally wear them for several hours and I do not notice I have them on. They do not warm your ears, or exert pressure, or anything. It's more similar to wearing glasses (and they do not interfere with wearing glasses). They also have a very secure fit, they cannot fall, etc. The only issue with comfort is using them in bed, or when your head is resting on something.
+* The sound quality is good for calls, but probably the quality for music can be criticized.
+* They provide **NO** sound isolation whatsoever. This is good, because you do not have to take them off to interact with people physically. But this is bad, because you will hear any noise around you.
+* However, they have a boom mic, meaning they supposedly avoid most background noise.
+* The controls are minimal, a volume rocker and a call/hang up button. Muting requires pressing volume up and down at the same time, which is not convenient, so normally I use software mute.
+* They look very strange, and I don't feel comfortable wearing them on the street, etc.
+* When I'm not using them, I charge them. I have never run out of battery.
+
+I used them with the Avantree DG80 adapter (see below) with my laptops, which avoids most Bluetooth issues, but still some issues remain. Recently I use them directly on Windows and Linux without much issue.
+
+They cost around 150€.
+
+My major doubt is if other Shokz headphones without a boom mic work well for calls. The OpenComm are more expensive than models without boom mic.
+
+Update: I lost the Shokz and got a MONODEAL MD08 PRO instead, which cost about half. They are fine too.
+
+### Mpow Air 2.4G
+
+This is a cheap clone of the HyperX Cloud Alpha gaming headset. Those are over ear wireless headphones with a wireless USB adapter.
+
+* Using USB does avoid **ALL** problems with USB. They **always** work flawlessly with a computer, and sound quality is great. However, they are impractical to use with a smartphone.
+* They have great sound isolation, so they filter most noise. However, you need to take them off to hear your surroundings, which is sometimes inconvenient.
+* The microphone is very good. However, some other gaming headsets mute the mic automatically when you move it "pointing up". This has a dedicated microphone mute button, and a volume wheel.
+* I find them uncomfortable, and I don't like wearing them for more than 30 minutes or so. They are also bad for use in bed, etc.
+* When I'm not using them, I charge them. I have never run out of battery.
+
+These headphones are great when I need to focus or when my environment is very noisy. I use them mostly for work, esp. when I need to record my voice.
+
+They cost around 75€.
+
+### Jabra Elite 85t
+
+Those are true wireless earbuds.
+
+* Music quality is very good.
+* Microphone is bad. It picks up a lot of wind and noise.
+* They are quite comfortable. Less than the Aftershokz, but I can wear them for long stretches, and I can use them in bed.
+* The controls are a bit difficult to use, although they are physical buttons.
+* They have some sound isolation and passthrough mode.
+* They can play background noise.
+* The battery is decent, but you will have to be more careful with running out of battery. However, they have wireless charging, which is nice. I'm somewhat concerned about battery degradation too.
+* True wireless earbuds can be inconvenient, if you are on the street and you want to remove them, you either need to locate their case and store them in (takes time), put them in a pocket... They don't have a very secure fit, and if they fall of your ear, there is no cable that will prevent them from falling into the floor and breaking (I think this happened to my 65t), or into a toilet, etc.
+
+I like using these to listen to music, or to watch TV.
+
+They cost around 150€.
+
+### Sennheiser HD 458BT
+
+These are over ear Bluetooth headphones.
+
+* Music quality is very good
+* I have not really tested the microphone much. I have done some calls with them, but obviously they pick up noise. They do not have a boom mic.
+* They have good noise isolation, both physical and software.
+* They have lots of controls, and they are quite nice.
+* I have worn them for two hours and a half straight, they become a bit uncomfortable, but usually removing them for a minute is enough.
+* Battery seems to last more than enough.
+* They are a bit bulky, so if you remove them and put them around your neck they are not comfortable.
+
+I like using these for music and TV too, and I normally use them on plane/train trips.
+
+They cost around 150€.
+
+### Cheap wired earbuds with microphone
+
+I have two pairs I bought in a supermarket. They have decent quality, they never run out of battery, and they have no connection issues or require no dongle. They are nice backup, and they are good for calls.
+
+I use them on the go, although one of my phones and my ChromeOS tablet require a USB adapter :( I also use them plugged into my computer monitor, with an extension cable so I can plug/unplug them easily.
+
+Each pair costs 5-10€.
+
+### Sleep headband
+
+I took an acquaintance's unused sleep headband. That's a small Bluetooth control unit and flat speakers embedded in a fabric headband. I cannot find the original model- you can find many variants costing from 15-20€.
+
+They are a bit bizarre because the control buttons are in your forehead.
+
+They solve many problems about using headphones in bed: they are quite comfortable (although my head is slightly too big for those) and they don't fall, although they can slip out of position. Sound quality is not great, but it's decent for music for non-audiophiles.
+
+## Notes
+
+### On form factors
+
+I don't think it's possible for one headset to be good at everything:
+
+* Calls
+* Music
+* Noise isolation vs environment awareness. Headphones isolate or not. Some isolating headphones have passthrough modes, but very few headphones can activate this immediately.
+* Comfort (esp. in bed)
+* Battery life
+* Connection
+* Easy and varied controls (mute, volume, etc.)
+
+Some of those areas are at odds with others.
+
+I use different headphones for different purposes.
+
+I know people who like very much wireless earbuds with a neck band, because they fix many of the convenience issues of true wireless earbuds. (They add more battery, they help if the earbuds fall from your ear, they put the microphone closer to your mouth, etc.) However, I have never used this format.
+
+### On microphones
+
+The closest a microphone is to your mouth, the less noise it will pick up. I do not have any indication that there are headphones whose microphone sits near your ears that do not pick up a lot of noise. (My Jabra Elite 85t and the previous 65t pick up a lot of noise and wind.)
+
+My experiences with headsets with a boom mic are much better in noisy environments.
+
+### On Bluetooth and computers
+
+I have heard many issues with Bluetooth and computers, including Windows, Linux, and macOS. Lately, I have had good succes under Windows and Linux (I have not used macOS lately).
+
+When I had issues with Bluetooth on Linux, I used an Avantree DG80 Bluetooth *sound* adapter. This is not a regular generic adapter to add Bluetooth to computers that do not have Bluetooth. This is a Bluetooth audio device that connects to headphones or other Bluetooth devices and appears in your computer as a USB audio device. Therefore, the Bluetooth implementation in your computer is ignored. The device provides its own codecs.
+
+With this, you avoid most of the issues of Bluetooth on computers, which sometimes works worse than on smartphones.
+
+Also, if you pair a Bluetooth headset with the adapter, you can plug the adapter to multiple devices and the headsets will "follow" the adapter, without requiring pairing.
+
+This does not avoid all problems. Notably, using the microphone requires the adapter to detect that your computer requests microphone use, and switching the Bluetooth mode. This requires a few seconds.
+
+However, the adapter has all the "good codecs", so most sound quality issues are avoided, even on Linux.
+
+### On mute
+
+Unfortunately, few combinations of headphones and software have integrated mute capabilities.
+
+I don't like having separate mute controls:
+
+* On the headset
+* On the operating system
+* On the "software" (like Google Meet, Teams, etc.)
+
+It is inconvenient, because with so many controls it's easier to make mistakes and you are slower.
+
+Software mute is good, because other people will see you are muted. This means, for example, that when you unmute, people might notice that you want to speak, etc.
+
+However, software mute requires interacting with the application, so it's not good for multitasking.
+
+Some headset mutes have a LED light that indicates you are muted, but it's not great.
+
+### On gaming controllers
+
+The XBox controllers **with their USB adapter** and the Playstation controllers **when plugged into a Playstation console** allow you to plug a wired headset. This is very nice, because they work very reliably and you avoid much of the wireless problems (connection, battery, etc.). If you play a lot, it's nice to have controllers with this feature.
diff --git a/blog/content/notes/tech/gadgets/pocket-computers.gmi b/blog/content/notes/tech/gadgets/pocket-computers.gmi
new file mode 100644
index 00000000..e2cd7a2f
--- /dev/null
+++ b/blog/content/notes/tech/gadgets/pocket-computers.gmi
@@ -0,0 +1,38 @@
+# Pocket computers
+
+In 2011, I started using a Blackberry Bold 9780, until 2014. The usable keyboard made me think that a device like this could replace laptops and desktop computers. Together with a functional browser and the trackpad (which allowed using mobile-unfriendly websites), the Bold was a great device for me.
+
+The Blackberry Classic I used 2015-2017 was the pinnacle of this idea, together with a prescient gesture interface and many great UI innovations which have been since lost.
+
+The Blackberry KeyONE I used 2017-2021 was the last device I used that had this greatness.
+
+Since then, I believe the loss of physical keyboard phones means that some uses of the smartphone have disappeared.
+
+## Current devices
+
+=> https://www.clicksphone.com/communicator Clicks Communicator
+=> https://www.clicksphone.com/powerkeyboard Clicks Power Keyboard
+=> https://keyphone.tech Keyphone
+=> https://www.lilygo.cc/products/t-deck T-Deck
+=> https://www.lilygo.cc/products/t-keyboard T-Keyboard
+=> https://beepy.sqfmi.com Beepy
+=> https://shop.m5stack.com/products/m5stack-cardputer-kit-w-m5stamps3 Cardputer
+=> https://mecha.so/comet Mecha Comet
+=> https://www.tindie.com/stores/zitaotech ZitaoTech refurbs keyboards, but they seem to be permanently out of stock.
+=> https://linkapus.com/ The Q25 project is a project to put an Android phone inside a Blackberry Classic shell.
+
+## Recent devices
+
+=> https://www.unihertz.com/products/titan-pocket Titan Pocket (owned)
+
+* The keyboard feels worse than a Blackberry and deteriorates with age (some keys require extra pressure to activate, meaning typing is painful)
+* The keyboard software is insufficient for writing in Spanish and Catalan
+* My battery swelled and I retired it
+
+## Obstacles
+
+### Communication platforms without an open API
+
+The main use of a pocket computer with a physical keyboard would be communication. Unfortunately, many communication platforms I use are closed, so I can only use them with an Android (or similar) device. If this was not the case, using devices with other operating systems would be more feasible.
+
+Although I do not use WhatsApp a lot (I use mostly Telegram), living in Spain it is unavoidable. I hope that the DMA will allow me to send messages to WhatsApp users through something that has an API, the DMA does not seem to be effective as of now.
diff --git a/blog/content/notes/tech/gadgets/x12.gmi b/blog/content/notes/tech/gadgets/x12.gmi
new file mode 100644
index 00000000..05491f37
--- /dev/null
+++ b/blog/content/notes/tech/gadgets/x12.gmi
@@ -0,0 +1,47 @@
+# Lenovo ThinkPad X12 Detachable Gen 1
+
+This is the laptop I used for work from early 2024 to early 2026. The laptop is leased, and was built on late 2021.
+
+## Linux compatibility
+
+Linux has several problems:
+
+* The keyboard is really a USB device (it is detachable), and you can only switch ctrl+fn using a Windows app or:
+
+=> https://github.com/manueljaeckle/thinkpad_x12_fn_switcher
+
+* Apparently, you cannot use the volume control keys in Linux either. However, I do not use those in Windows so I don't care.
+
+## Form factor
+
+One of the main reasons for picking this laptop is that it's very light. The laptop with keyboard weighs 1.1kg.
+
+The keyboard is detachable, which has pros and cons:
+
+* You cannot comfortably use the laptop on your lap.
+* However, detaching the keyboard and using it as a portrait tablet to read documentation is great.
+
+### Keyboard
+
+The keyboard is very good, but slightly inferior to a full ThinkPad keyboard:
+
+* There is no insert key.
+* For me, muscle memory does not work well when switching to a full ThinkPad keyboard.
+
+However, it still is a pleasant keyboard to use.
+
+### Screen
+
+The screen looks good. But because it is glossy, sometimes I have issues with reflections.
+
+### Battery
+
+I have only used the battery when it was three years old already. I can use the laptop for about 4 hours of somewhat intensive usage (some calls, working with compiled languages and LSP).
+
+### Pen
+
+Unfortunately, the leaser did not deliver a pen.
+
+## Others
+
+Besides what's been mentioned, I do not find any other problem with the laptop.
diff --git a/blog/content/notes/tech/git-advice.gmi b/blog/content/notes/tech/git-advice.gmi
new file mode 100644
index 00000000..8ec41105
--- /dev/null
+++ b/blog/content/notes/tech/git-advice.gmi
@@ -0,0 +1,21 @@
+# Git advice
+
+## Never use "git commit -m", use "git commit -v"
+
+Configure your system so that the EDITOR environment variable refers to your preferred editor.
+
+With "git commit -v" you can see your commit diff while writing your commit message. This helps you review that your commit is correct and write a better commit message.
+
+## Use gitignore properly
+
+=> https://git-scm.com/docs/gitignore gitignore
+
+Note that by default, Git defaults to $XDG_CONFIG_HOME/git/ignore or $HOME/.config/git/ignore.
+
+## Use the modern Git commands (or teach them)
+
+Particularly, "git checkout" has many functionalities that now can be handled by more focused commands like "git switch" and "git reset".
+
+If you have too much muscle memory and are used to them, then consider learning them only to teach other people so that they start with the safer commands.
+
+Many Git commands print suggestions that use the newer commands.
diff --git a/blog/content/notes/tech/github-annoyances.gmi b/blog/content/notes/tech/github-annoyances.gmi
new file mode 100644
index 00000000..a36214b9
--- /dev/null
+++ b/blog/content/notes/tech/github-annoyances.gmi
@@ -0,0 +1,7 @@
+# GitHub annoyances
+
+## The repository creation wizard can be confusing initially
+
+When creating a new repo, GitHub offers you to populate the repository with some files (a README, a .gitignore file, a license).
+
+In some situations, you have an existing directory in your computer with files that you want to be the initial contents of the repo. If you create a truly empty repo, then GitHub displays some instructions that can help pushing the contents of your existing directory to the new repo. If you use the GitHub features to populate the repo, then GitHub does not display these instructions and uploading your files requires more knowledge.
diff --git a/blog/content/notes/tech/internet-communication-channels.gmi b/blog/content/notes/tech/internet-communication-channels.gmi
new file mode 100644
index 00000000..efdc18af
--- /dev/null
+++ b/blog/content/notes/tech/internet-communication-channels.gmi
@@ -0,0 +1,131 @@
+# Internet communication channels
+
+If you want to provide a communication channel for a community over the Internet and you are considering options such as:
+
+* Slack
+* Discord
+* Reddit
+* Telegram
+* WhatsApp
+* Facebook
+* Or any other communication channel controlled by a single big company
+
+, then please read this article and consider an alternative.
+
+Because such channels are often convenient, cheap, and easy, they are natural choices.
+
+However, companies are about maximizing their benefits first. Certainly, providing convenient, cheap, and easy services often help companies make money. But I believe we have seen enough examples of companies putting their benefits first in detriment of their users.
+
+Using these alternatives will always require more effort. This text is long, and just reading and processing it might take more time than setting up a channel on the services mentioned above. The alternatives I describe certainly have drawbacks compared to the services I am asking you to avoid. However, in the long run I think making an extra effort to make an informed choice pays off.
+
+## A quick litmus test
+
+If you only thing about a single thing, then think about this: how many independent clients are for this communication channel?
+
+How tightly the people behind the channel control clients is a good indicator of how much they want to maximize profits.
+
+## Alternatives
+
+### IRC
+
+IRC is a real-time chat protocol created in 1988 that is still in use. Many perceive flaws in IRC that seem to make it a bad choice. However, many IRC flaws have been addressed in recent times and I believe it is a good choice in many (but not all) scenarios.
+
+The biggest traditional issue with IRC is channels without history, where you cannot see messages posted while you were offline. (If you suspend or turn off your laptop, you will be offline in IRC. Even if you run your IRC client continuously on your client, if your phone goes out of coverage or your phone suspends your IRC client, you will be offline.) However, nowadays you can create channels with history.
+
+Channels without history are frequently confusing for new users, because most chat systems have history. Heavy IRC users are either used to having no history [this might seem surprising, but for some this is even a benefit] or have means to be permanently connected to IRC. However, users new to IRC might join a channel, post a question and go offline without anyone having a chance to see their message and reply. Then, unless people remember to answer when they are back, or other means are used, answers will not be visible to the person who asked.
+
+The chathistory extension addresses this problem. As far as I know, only the Ergo IRC server and their network support this extension.
+
+Some advantages of IRC are:
+
+* You can use IRC without creating an account. This can be especially useful for providing a general contact mechanism. You can create links that will ask for a nickname, and place you into a channel without any additional steps.
+* IRC is a very simple protocol with more than 30 years of history. This means that many developers have invested significant efforts in creating powerful IRC clients and tools (such as bots). And lately, many easy IRC clients are available. This means that IRC can scale from simple setups that require little effort to use, to powerful setups that can provide interesting features. (If you are used to plain communication clients, you might be surprised at how valuable some features can be.)
+
+Some drawbacks of IRC are:
+
+* IRC does not have end-to-end encryption, and thus IRC administrators can read every conversation. This is not a huge problem for public or semi-public channels, but it limits IRC for many scenarios.
+* IRC requires more effort from administrators to provide a good experience to entry-level users, control spam, and others. (An important point is that although integration with audio/video conferencing is possible, it requires more effort and provides a lesser experience.)
+* IRC is mostly text-based. Although many IRC clients can display images and GIFs, communicating with images and GIFs is harder on IRC. (And IRC also does not have integrated audio/video conferencing.)
+* Push notifications are not common yet. Although it is possible to receive instant notifications when you are mentioned or receive a private message, this is frequently difficult. In general, IRC on mobile phones is not as evolved as on desktop computers.
+
+Interesting projects:
+
+=> https://github.com/ObsidianIRC/ObsidianIRC ObsidianIRC (web client)
+=> https://kiwiirc.com/ Kiwi IRC (web client)
+=> https://codeberg.org/emersion/gamja Gamja (web client)
+=> https://soju.im/ Soju (bouncer)
+=> https://halloy.chat/ Halloy (graphical desktop client)
+=> https://git.sr.ht/~delthas/senpai Senpai (terminal client)
+
+### Delta Chat
+
+Delta Chat is an instant messaging system that tries to be very similar to the most popular instant messaging systems.
+
+However, there are multiple clients and anyone can run a server.
+
+The strangest thing about Delta Chat is that is uses email underneath. However, I would recommend ignoring this fact.
+
+### XMPP
+
+XMPP is younger than IRC, but older than Matrix. Compared to Matrix:
+
+* End-to-end encryption and audio/video conferencing is possible with XMPP, but in practice it can be difficult to access these features.
+* There's more XMPP clients than Matrix clients, but it is also hard to find clients that support all the features you need on different platforms.
+
+For some scenarios, if you find the right combination of XMPP server and clients, XMPP can be a great option.
+
+Historically, XMPP was not well-suited to mobile usage. Nowadays, mobile usage is better, but finding the right clients to use is still a challenge.
+
+### Matrix
+
+Matrix is a more modern chat protocol that addresses some of the drawbacks of IRC:
+
+* Matrix has end-to-end encryption, so conversations between users are private to Matrix administrators.
+* Matrix requires less effort from *channel* administrators. (But running a Matrix server requires significant resources. However, there are public Matrix servers and managed services. Thanks to end-to-end encryption, using a public Matrix server is an interesting option.)
+* Matrix has good support for audio/video conferencing, images and GIFs, reactions, push notifications, and phone usage.
+
+But also some disadvantages compared to IRC:
+
+* Users need to create accounts.
+* Using end-to-end encryption makes some usage harder. (Although end-to-end encryption is optional.)
+* There are fewer clients and tools, and generally they are more complex, more resource intensive, and less featureful. (And not all clients support all features.)
+
+### Other alternatives to consider
+
+Zulip offers instant messaging, but has some characteristics from forums. (For example, Zulip uses threads with subjects.)
+
+Mattermost and Rocketchat are designed for communication within organizations.
+
+And lastly, because all the technologies mentioned in this text allow integrations, there are bridges to join different technologies.
+
+For example, IRC channels can be bridged to Matrix rooms.
+
+Although bridges are not ideal, in some cases you can use them to make one channel available over different technologies, which might address the limitations of specific technologies.
+
+Although my perception is that most communities nowadays communicate over instant messaging, many communities use successfully more asynchronous communication channels. In some cases, providing both instant messaging and an asynchronous channel can also work well.
+
+Mailing lists (and their sibling, newsgroups) are older than IRC. Although mailing lists are far less popular than in the past, many communities still use mailing lists.
+
+Mailing lists have several advantages:
+
+* Having an email address is nearly a necessity for all Internet users. Mailing lists often require no user account other than an existing email address.
+* In a way, email and mailing lists share many similarities with IRC. Although most people are users of just a few mail services and clients, there is a wide variety of services and clients. Email power features are somewhat forgotten, but they still exist and mail clients can have very convenient features.
+* Most mailing list have good ways to browse and search past messages. Email discussions are more naturally searchable, thanks to their slower pace and thread organization.
+
+However, they also have many advantages:
+
+* As people no longer use email to communicate, going back to email can cause significant friction.
+* Finding a good mailing list service is difficult. (And hosting your own is also more difficult than hosting other services.)
+
+In my opinion, mailing lists are good, but they have become foreign to most people.
+
+Forums used to be very popular.
+
+Compared to mailing lists:
+
+* Forums require creating an account.
+* Forums do not have multiple clients, although forum software has also evolved for a long time, and many forums have great features.
+* Forums are also a bit out of style, but they are more popular and familiar to most than mailing lists.
+* Finding a forum service or hosting one is simpler than email.
+
+Social networks tend to be slightly different communication channels than instant messaging or asynchronous messaging. Alternatives to social networks also exist. However, in my opinion, social network-style communication is not optimal for "communities" in most cases. Still, you might want to explore alternatives. The Fediverse (or ActivityPub) has many different varieties of communication channels that might suit your needs.
diff --git a/blog/content/notes/tech/ledger.gmi b/blog/content/notes/tech/ledger.gmi
new file mode 100644
index 00000000..97a0af3f
--- /dev/null
+++ b/blog/content/notes/tech/ledger.gmi
@@ -0,0 +1,58 @@
+# ledger
+
+=> https://ledger-cli.org Ledger is a double-entry accounting system based on a text file format.
+
+=> https://plaintextaccounting.org/ The Plain text accounting website lists more software based on the ideas.
+
+This document contains notes about how I use ledger.
+
+## Configuration
+
+My ~/.ledgerrc just contains:
+
+```
+--file ~/Nextcloud/finances.ledger
+--date-format %Y-%m-%d
+```
+
+I store my ledger file in my Nextcloud instance, so Nextcloud synchronizes across my computers.
+
+Other than that, I just configure the YYYY-MM-DD date format.
+
+## Registering transactions
+
+I try to register most transactions the first moment I'm at my keyboard.
+
+I do so manually without automations.
+
+In 2025, I registered over 800 transactions, and I didn't feel it was tedious.
+
+My main text editor is Emacs, so I use ledger-mode:
+
+* Automatically adds indentation and alignment.
+* Autocompletion of accounts and payees.
+
+To register transactions, I run:
+
+```
+ledger reg bankname:accountname
+```
+
+Then, I correlate with the running total that my bank websites show to find the first missing transaction and go on from there.
+
+I have a monthly calendar reminder to catch up on all accounts. In this session, I also update my pension plan accounts with their current value.
+
+## Tagging
+
+### who
+
+I use the who tag because I want to make reports based on specific beings. For example, I want to query quickly costs associated to the cat.
+
+In 2026, I think I will have some accounts like "Expenses:Supermarket:My Name" too, so I'm experimenting with the following snippet:
+
+```
+= :My Name
+ ; who: myname
+```
+
+This seems to automatically add the tag to related accounts.
diff --git a/blog/content/notes/tech/migadu.gmi b/blog/content/notes/tech/migadu.gmi
new file mode 100644
index 00000000..9fc5a80e
--- /dev/null
+++ b/blog/content/notes/tech/migadu.gmi
@@ -0,0 +1,100 @@
+# Migadu
+
+=> https://migadu.com/
+
+## A strategy to handle email addresses
+
+Email addresses can be "vanity" or "non-vanity".
+Vanity email addresses are meant to be public and memorable, for example firstname@lastname.tld.
+
+Set up any vanity domains that you want, and a non-vanity domain.
+
+### Non-vanity email addresses
+
+In the non-vanity domain, you create the {me}{code}@nonvanity.tld mailbox.
+
+{me} identifies you, you can have multiple users with different {me} identifiers in a single non-vanity domain.
+
+This strategy uses {code} to obfuscate email addresses. When you use {code} in an email address, ideally you should be able to identify if the {code} is valid or not.
+
+For example, you could use a four-digit {code} and store what code you have used for each address. If you use x3452 and store this code, when you receive an email that does not match, such as x3453, you know the code is incorrect.
+
+Alternatively, you can use hashing so that you do not have to store all codes.
+
+No one except you should know about {me}{code}@nonvanity.tld.
+
+Then you create a pattern rewrite from {me}.*@nonvanity.tld to {me}{code}@nonvanity.tld.
+
+When you need a non-vanity email address, you create a new {me}.{entity}{code}@nonvanity.tld, where {entity} is the entity that communicates with this email address and {code} is a new code.
+
+Mails received at {me}@nonvanity.tld are incorrect. Mails received without the correct code are incorrect.
+
+### Vanity email addresses
+
+Create any needed {id}@vanity.tld addresses.
+
+Different from non-vanity email addresses, vanity email addresses can be guessed and you cannot identify invalid email.
+
+=> misc-linux-stuff See "email forwarding via IMAP" for notes about forwarding between different email servers.
+
+### TODO Filing
+
+Because each vanity email address and entity has a different email address, you can file emails automatically into folders if wanted.
+
+## Migrating email from Gmail
+
+```
+imapsync --user1 xxx@gmail.com -passfile1 gmailpass --user2 a@a.com --host2 imap.a.com --passfile2 pass --gmail1
+```
+
+To move mail, add --delete1. But this seems to make `imapsync` much slower! (IIRC, also this didn't remove the emails from GMail!)
+
+### Preventing issues with multiple tags
+
+An email message can have multiple "tags" in Gmail that correspond to IMAP folders. If you have messages with multiple tags, then the migration will duplicate messages in multiple folders or file mails to one folder at "random".
+
+imapsync has features to control this, and avoid problems with the "all mail" and "sent mail" Gmail folders, but for further control, you can refile emails to have a single tag.
+
+I have an mbsync replica of my Gmail account for backup purposes. This replica can be used to find messages with multiple tags:
+
+```
+find . -path './\[Gmail\]/All Mail' -prune -o -not -name index -type f -exec grep -H ^Message-ID: {} \; >index
+```
+
+Produces one file with lines:
+
+```
+/.../cur/f:Message-ID:...
+```
+
+```
+#!/usr/bin/env python3
+
+import pathlib
+ms = pathlib.Path("index").read_text().splitlines()
+
+import collections
+idx = collections.defaultdict(set)
+
+for m in ms:
+ path, _, id = m.rsplit(":", 2)
+ f = "/".join(pathlib.Path(path).parts[:-2])
+ idx[id].add((path, f))
+
+for id, vs in idx.items():
+ fs = sorted(set([f for (_path, f) in vs]))
+ if len(fs) > 1:
+ print(fs)
+```
+
+```
+./idx.py | sort | uniq
+```
+
+Clear up multiple tags in Gmail to prevent duplicates.
+
+
+## Notes
+
+* Aliases do *not* have plus addressing, use a "pattern rewrite" instead.
+* New domains come with 'junk messages with word "SPAM" in subject (case insensitive)' on by default; go to domain, spam filtering, aggresiveness to disable.
diff --git a/blog/content/notes/tech/misc-linux-stuff.gmi b/blog/content/notes/tech/misc-linux-stuff.gmi
new file mode 100644
index 00000000..a5521f1f
--- /dev/null
+++ b/blog/content/notes/tech/misc-linux-stuff.gmi
@@ -0,0 +1,116 @@
+# Misc Linux stuff
+
+## Reverse sshfs
+
+=> https://blog.dhampir.no/content/reverse-sshfs-mounts-fs-push
+
+You need the SFTP server program on your local machine (on Debian, the openssh-server package) and sshfs on the remote machine.
+
+## Find non-Debian packages
+
+```
+aptitude search '~S ~i !~ODebian'
+```
+
+## Memory usage queries
+
+### systemd
+
+```
+systemd-cgtop -m
+```
+
+Drill down with:
+
+```
+systemd-cgtop -m user.slice/user-1000.slice
+```
+
+### smem
+
+```
+sudo smem -P beam.smp -kta
+```
+
+## Quick rerouting of browser traffic through another host
+
+"ssh -D 1234 host" creates a Socks proxy on localhost:1234 that sends traffic through host.
+
+By enabling "allow extension to control proxy settings" in the multi account containers Firefox add-on, you can make containers use specific proxies.
+
+## Email forwarding via IMAP
+
+When you have multiple email addresses, you have multiple options to use them.
+
+Traditionally, people used redirection/forwarding to make email arriving at from@example.com go to to@example.net instead.
+
+If mail from example.com and example.net is handled by different servers, typically you can configure the example.com mail server to resend any message arriving to the from address to to@example.net.
+
+However, nowadays with spam filtering, the example.net mail server can reject these emails as spam, sometimes silently.
+
+For safer redirects, you can:
+
+* Use the same mail server for both accounts. However, this sometimes cannot be done or has extra cost and complexity.
+
+* Configure the destination email server to fetch email from the origin mail server. For example, Gmail can do this, but the fetching period can be as long as 15 minutes. This can be inconvenient when receiving confirmation emails, etc. Additionally, operators of the destination email server now have your credentials.
+
+A third option is to run this fetching process yourself.
+
+=> https://github.com/lefcha/imapfilter IMAPFilter supports connecting to an IMAP account, waiting until messages to arrive, and moving them to another IMAP account.
+
+Benefits:
+
+* IMAPFilter can use IMAP idle to request the IMAP server to notify when messages arriving, so forwarding happens without a polling delay.
+* Because IMAP is used on both sides, no spam filtering happens.
+* IMAPFilter is packaged for many distributions.
+
+Drawbacks:
+
+* Requires additional infrastructure.
+* If IMAPFilter stops working, email stops being forwarded without warning.
+
+=> https://ñix.es/cgit/alex/alexpdp7.git/tree/scripts/p7s/mail/__init__.py?h=master Refer to this Python module for scripts that configure IMAPFilter as a systemd service, with credentials from Bitwarden.
+
+## Using a PCSensor pedal
+
+=> https://github.com/rgerganov/footswitch Install Footswitch
+
+```
+sudo footswitch -1 -m ctrl -2 -S '7F' -3 -m win -k m
+```
+
+Maps:
+
+* Left pedal to be a ctrl key
+* Center pedal to the toggle mute key
+* Right pedal to be Win+M (you can map this in Gnome to toggle mic status)
+
+## Remote networking
+
+If you can create a pipe between two hosts (using SSH, for example), you can use VDE (Virtual Distributed Ethernet) to connect the two hosts over a virtual network.
+
+You need the following programs on both hosts:
+
+* dpipe and vde_plug (on Debian, use the vdeplug package)
+* vde-switch (on Debian, use the vde-switch package)
+
+Run as root on both hosts:
+
+```
+vde_switch -t tap0
+```
+
+This command creates a virtual switch connected to tap0.
+
+Use the dpipe command to connect two instances of the vde_plug command running as root on both hosts.
+
+```
+$ dpipe sudo vde_plug = ssh root@remote vde_plug
+```
+
+Then bring the tap0 interface up and configure IP addresses on both hosts.
+
+```
+# ip link set tap0 up
+# ip addr add $IP/$NETMASK dev tap0
+```
diff --git a/blog/content/notes/tech/misc-python-stuff.gmi b/blog/content/notes/tech/misc-python-stuff.gmi
new file mode 100644
index 00000000..f7cc33e7
--- /dev/null
+++ b/blog/content/notes/tech/misc-python-stuff.gmi
@@ -0,0 +1,62 @@
+# Misc Python stuff
+
+## Tools
+
+* Use uv for your software. It's modern and good.
+* pipx is packaged by many distros and useful for installing Python software. Provide instructions for installing your software using pipx.
+* Use pytest for testing. It's PEP-8 compliant unlike unittest in the standard library. doctest is good too.
+* Use ruff for validation.
+
+## Python versions
+
+Try to support Python versions in popular LTS distros such as RHEL and its clones, and Debian and its derivates (like Ubuntu).
+
+## Writing command line tools
+
+* Use entry points so that when using pipx or uv to install your tool, they install the tool to the user's path.
+
+### Nice Python libraries
+
+* appdirs for using the proper configuration, cache, etc. directories on multiple platforms
+* keyring for cross-platform secret storage
+* tqdm for progress bars
+
+### Writing dependencyless Python
+
+If you can write your program without using dependencies, then it automatically becomes much easier to distribute and run. This is quite possible for many tools! And helps you replace problematic shell scripts.
+
+The standard library still includes a lot of batteries:
+
+* argparse is clunkier that third-party libraries, but it works well enough. The documentation provides a pattern for subcommands under "one particularly effective way of handling sub-commands...". argcomplete is a third party library that adds tab completion for argparse programs. Review the types that argparse provides support for, such as Path, enumerated choices, etc.
+* compression allows working with many archive formats without shelling out to tar or (un)zip.
+* concurrent.futures for executing things in parallel, esp. the map function combined with a ThreadPoolExecutor (for IO-bound tasks) or ProcessPoolExecutor (to avoid the GIL in tasks that use the CPU).
+* getpass to read passwords from the terminal properly. Also to obtain the current user.
+* hashlib to avoid shelling out to commands such as sha256sum.
+* http.server is useful for simple web servers (and also as a quick web server in the command line).
+* json is about the only structured format supported in the standard library.
+* logging to print output with timestamps.
+* pathlib for any kind of path manipulation, esp. the read|write_text|bytes methods that are so convenient. shutil still contains a few functions missing from pathlib, esp. in older Python versions.
+* textwrap.dedent and str.[lr]strip for embedding multiline strings in code.
+* urllib.request is clunkier than third-party libraries, but it's usable.
+
+For very simple stuff, tkinter can implement simple graphical tools and wsgiref can implement simple web apps (that you can even deploy with CGI).
+
+### Subprocess
+
+The main problem of using Python for scripting is that the subprocess functions do not default to check=True and shell=False.
+
+Likely many of your scripts will start with a subprocess wrapper suited to your script.
+
+You can use shlex.join to print commands you execute in a copy-pastable way.
+
+## Writing scrapers
+
+=> https://playwright.dev/python/ Use Playwright
+
+* Playwright automatically sets up headless browsers.
+* Provides convenient abstractions for locating elements in a page (mostly no XPath required. It can match "intelligently" using text).
+* Has a handy UI tool that records your actions in a browser and writes equivalent *readable* Playwright code.
+
+Further reading:
+
+=> https://new.pythonforengineers.com/blog/web-automation-dont-use-selenium-use-playwright/ Web automation: don't use Selenium, use Playwright
diff --git a/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi b/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi
new file mode 100644
index 00000000..01fc5fae
--- /dev/null
+++ b/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi
@@ -0,0 +1,61 @@
+# Motivating example for logical replication with dynamic UI
+
+(I'm almost sure what I write below is a horrible idea that will melt a PostgreSQL server with very few "real-time queries" at the same time. I'm very curious about how much load could PostgreSQL handle efficiently using this schema.)
+
+Suppose the following database schema (pseudo-SQL):
+
+```sql
+create table chat_messages (
+ id serial primary key,
+ posted timestamp not null,
+ channel text not null references chats(id),
+ author text not null references users(id),
+ message text not null
+);
+```
+
+Imagine you could write an UI element that subscribed to the following publication:
+
+```
+create publication foo for table chat_messages where (channel in :list_of_channels_user_is_in and posted > :some_time_ago);
+```
+
+Without writing any additional code, the UI element would get instantly notified not only of all new messages, but also of editions, deletions, or messages moved in or out of the subscribed channels. I believe you could write a real-time UI element with much shorter and safer code than any alternative I can think of that only uses OSS code. (As far as I know, ksqlDB does a similar thing, but has non-OSS bits and seems much harder to deploy than PostgreSQL, besides you would also need to deploy PostgreSQL.)
+
+This has some caveats:
+
+* Publications cannot do "joins", and implementing any live UI element that requires joins would be much more complex. (And I'm not sure it would still be the best way to implement things.)
+* This likely cannot be implemented efficiently without having all working set data in RAM (e.g. all the data involved in all subscriptions).
+
+My idea is writing:
+
+* A daemon that provides an API that can be used as in the following example:
+
+```
+subscription = subscribe("chat_messages", column("channel").in(list_of_channels) and column("posted").gt(some_time_ago))
+while update = subscription.next():
+ for chat_message in sorted(update.all_current_results(), key=lambda chat_message: chat_message.posted):
+ print(chat_message.current_values, chat_messages.previous_values)
+ print(update.deleted_since_last_update_results())
+```
+
+* Libraries for stacks such as "Django + HTMX", "GTK", etc. that allow to build UI elements that use the daemon API underneath, so you could write things like:
+
+```
+<ul class="channels">
+ {% foreach channel in joined_channels %}
+ <li>
+ {{ channel.name }}
+ last message: {{ for chat_message in update_all_current_results() if chat_message.current_values.channel == channel | max(lambda chat_message: chat_message.current_values.posted) }}
+ </li>
+ {% end foreach %}
+</ul>
+
+<ul class="current_chat_messages">
+ {% foreach chat_message in update.all_current_results() if chat_message.current_values.channel == current_channel %}
+ <li>{{ chat_message.current_values.author }} {{ chat_message.current_values.message }}</li>
+ {% end foreach %}
+</ul>
+```
+
+For stacks such as Django/HTMX, in simpler websites you could have websites that degrade gracefully out of the box without JS, just losing real-time updates.
diff --git a/blog/content/notes/tech/prolog-vs-sql.gmi b/blog/content/notes/tech/prolog-vs-sql.gmi
new file mode 100644
index 00000000..181ae7e3
--- /dev/null
+++ b/blog/content/notes/tech/prolog-vs-sql.gmi
@@ -0,0 +1,114 @@
+# Showing the similarities between SQL and Prolog
+
+SQL is a very common programming language, which sometimes is compared to the relatively more obscure Prolog language. Both are examples of declarative languages, where you define some facts, then you can ask questions about those facts, and the system answers the questions without you writing an explicit program.
+
+However, I could not find a good example of their similarities. This text presents the most typical Prolog example, and translates it to SQL.
+
+## A typical Prolog example
+
+"[x]" reads Prolog facts from file "x". We can use the special file "user" to read facts from the REPL, ending the facts with ctrl+d:
+
+
+```
+$ swipl
+?- [user].
+|: father(jim, julian).
+|: father(julian, joe).
+|: father(julian, jerome).
+|: father(pete, perry).
+|: ^D
+true.
+```
+
+You should read "father(X,Y)" as "X is the father of Y". So Jim is the father of Julian, and so on.
+
+We can ask Prolog questions:
+
+```
+?- father(julian, jim).
+false.
+```
+
+Is Julian the father of Jim? There is no known fact about this, so no. But Julian *is* the father of Joe:
+
+```
+?- father(julian, joe).
+true.
+```
+
+More interestingly, you can ask who are Julian's children:
+
+```
+?- father(julian, X).
+X = joe ;
+X = jerome.
+```
+
+(You press ; to get further answers.)
+
+## A simple translation to SQL
+
+You can do pretty much the same with SQL, first define the facts as values in tables:
+
+```
+$ sqlite3
+sqlite> create table fatherhood(father, son);
+sqlite> insert into fatherhood values ('jim', 'julian');
+sqlite> insert into fatherhood values ('julian', 'joe');
+sqlite> insert into fatherhood values ('julian', 'jerome');
+sqlite> insert into fatherhood values ('pete', 'perry');
+```
+
+Then you can get the same answers:
+
+```
+sqlite> select * from fatherhood where father = 'julian' and son = 'jim';
+sqlite> select * from fatherhood where father = 'julian' and son = 'joe';
+julian|joe
+sqlite> select * from fatherhood where father = 'julian';
+julian|joe
+julian|jerome
+```
+
+## The next step in Prolog
+
+The typical example continues with some logic:
+
+```
+?- [user].
+|: grandfather(X,Y) :- father(X, Z), father(Z, Y).
+|: ^D
+true.
+```
+
+X is the grandfather of Y if X is the father of Z and Z is the father of Y. Then you can ask questions, and Prolog knows the answers:
+
+```
+?- grandfather(jim, X).
+X = joe ;
+X = jerome.
+
+?- grandfather(X, jerome).
+X = jim ;
+false.
+```
+
+## Can we do the same in SQL?
+
+You might not guess the answer on the first try, but the answer is not complex: you can do the same thing with SQL views:
+
+```
+sqlite> create view grandfatherhood as
+ ...> select fatherhood_1.father as grandfather, fatherhood_2.son as nephew
+ ...> from fatherhood as fatherhood_1 join fatherhood as fatherhood_2 on (fatherhood_1.son = fatherhood_2.father);
+```
+
+And if you ask the same questions, SQLite gives the same answers:
+
+```
+sqlite> select * from grandfatherhood where grandfather = 'jim';
+jim|jerome
+jim|joe
+sqlite> select * from grandfatherhood where nephew = 'jerome';
+jim|jerome
+```
diff --git a/blog/content/notes/tech/python-modules-primer.gmi b/blog/content/notes/tech/python-modules-primer.gmi
new file mode 100644
index 00000000..67d03e19
--- /dev/null
+++ b/blog/content/notes/tech/python-modules-primer.gmi
@@ -0,0 +1,229 @@
+# Python Modules Primer
+
+## Prerequisites
+
+These instructions assume a Linux environment. A macOS environment is similar, but not identical. A Windows environment is more different.
+
+## Previous knowledge
+
+### A refresher on the PATH variable
+
+If you execute the following command in your terminal:
+
+```
+$ echo hello
+```
+
+, the shell searches for the echo command in the directories listed in your PATH environment variable. You can display your PATH variable by running:
+
+```
+$ echo $PATH
+/home/user/.local/bin:/home/user/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
+```
+
+The contents of the PATH variable depend on your particular environment.
+
+If you run the following command:
+
+```
+$ which echo
+/usr/bin/echo
+```
+
+The which command prints where the shell locates the echo command.
+
+### A refresher on shell scripts
+
+If you create a file named foo.sh with the following contents:
+
+```
+#!/bin/sh
+
+echo hello
+```
+
+, you define a "shell script". The first line indicates that this shell script is executed by using the /bin/sh command. The rest of the file are commands to be executed by the shell command. These commands behave as if you typed them into your terminal, so if you execute this script, the command "echo hello" will be executed, printing hello.
+
+If you try to run foo.sh like you run the echo command, by typing its name, it does not work:
+
+```
+$ foo.sh
+bash: foo.sh: command not found...
+```
+
+, because the shell looks for the foo.sh in the directories listed in the PATH variable. Unless you created the foo.sh file in a directory like /usr/bin, the shell will not find the foo.sh command.
+
+A solution to this problem is to specify the path to the foo.sh file, instead of relying on the PATH variable. However, if you do this, you face a second problem.
+
+```
+$ ./foo.sh
+bash: ./foo.sh: Permission denied
+```
+
+This happens because only files with the executable permission can be executed in this way. To solve this, add the executable permission; then it works:
+
+```
+$ chmod +x foo.sh
+$ ./foo.sh
+hello
+```
+
+## The import statement in Python
+
+### Importing from the Python standard library
+
+Run the following commands by using the Python REPL:
+
+```
+$ python3
+>>> import datetime
+>>> datetime.datetime.now()
+datetime.datetime(2023, 9, 11, 21, 53, 16, 331236)
+```
+
+import works in a similar way to running a command in the shell.
+Python searches a number of directories looking for the datetime module.
+
+To see which directories are searched, run:
+
+```
+$ python3
+>>> import sys
+>>> sys.path
+['', '/usr/lib64/python39.zip', '/usr/lib64/python3.9', '/usr/lib64/python3.9/lib-dynload', '/home/alex/.local/lib/python3.9/site-packages', '/usr/lib64/python3.9/site-packages', '/usr/lib/python3.9/site-packages']
+```
+
+sys.path is a list of the directories that the import command searches.
+The contents of `sys.path` depend on your operating system and Python installation method.
+
+In my system, the /usr/lib64/python3.9 directory contains the datetime.py module.
+
+```
+$ head /usr/lib64/python3.9/datetime.py
+"""Concrete date/time and related types.
+
+See http://www.iana.org/time-zones/repository/tz-link.html for
+time zone and DST data sources.
+"""
+
+__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo",
+ "MINYEAR", "MAXYEAR")
+...
+```
+
+/usr/lib64/python3.9 contains the modules in the Python standard library.
+
+### Importing your Python files
+
+If you create a file with the a.py name:
+
+```
+def f():
+ return 2
+```
+
+, and another with the b.py name:
+
+```
+import a
+
+print(a.f())
+```
+
+, then:
+
+```
+$ python b.py
+2
+```
+
+
+This works, because sys.path contains '', which means "the current directory".
+
+(sys.path is very similar to the PATH variable. However, sys.path contains the current directory by default, whereas PATH does not.)
+
+When "import a" is executed, then Python searches the directories in sys.path for an a.py file; it is found when checking the '' path. When "import datetime" is executed, Python searches in the current directory (because '' comes first in the path), doesn't find it, but then finds it in the following /usr/lib64/python3.9 directory. Python iterates over the sys.path directories, and loads the first matching file.
+
+## Installing libraries
+
+When writing Python software, sometimes it is enough with the modules included in the standard library. However, frequently you want to use other libraries. To use Python libraries, you must install them using the pip program.
+
+The pip program is not part of the python3 package in some Linux distributions, and comes from the python3-pip package.
+
+The pip program can download libraries from pypi.org, the Python package index, and install them. pip installs libraries to a "Python environment".
+
+Old versions of pip defaulted to installing libraries to the "system" Python environment. In a Linux system, the system Python environment is located in a directory such as /usr/lib64/python3.9. By default, normal Linux users cannot write to /usr, so installing a package would fail.
+
+Modern versions of pip detect that they cannot write to the "system" Python environment, and then redirect the install to the "user" Python environment. The "user" Python environment is in a directory such as ~/.local/lib/python3.9.
+
+You could use a command such as "sudo pip install" to grant pip the privileges required to write to /usr. However, this can make a Linux system unusable. Most Linux systems use software that uses the "system" Python environment. Altering the "system" Python environment can break such software. Do not run "sudo pip install" with root privileges unless you know why you need this.
+
+If you use a modern pip (or use the --user option), you can install libraries to the "user" Python environment. However, this is problematic because a Python environment can only contain a single version of a Python library. If you have two different Python programs that different versions of the same library, then these two programs cannot coexist in the "user" Python environment.
+
+In general, Python virtual environments are used to address this problem.
+
+## Creating Python virtual environments
+
+If you run:
+
+```
+$ python3 -m venv <some path>
+```
+
+This will create a directory with the path you specify, with the following contents:
+
+```
+<some path>
+├── bin
+│   ├── activate
+│   ├── pip
+│   ├── python
+├── include
+├── lib
+│   └── python3.9
+```
+
+The python and pip commands are copies of the same commands from the "system" Python environment.
+
+But these commands work differently from the "system" Python environment commands:
+
+```
+$ <some path>/bin/python
+>>> import sys
+>>> sys.path
+['', '/usr/lib64/python39.zip', '/usr/lib64/python3.9', '/usr/lib64/python3.9/lib-dynload', '<some path>/lib64/python3.9/site-packages', '<some path>/lib/python3.9/site-packages']
+```
+
+sys.path uses the lib directories in the virtual environment.
+
+When you use the `pip` program from the virtual environment, it installs the libraries to the virtual environment.
+
+You can create as many virtual environments as you need, and you can install different versions of libraries to each virtual environment.
+
+## Activating Python environments
+
+You can run the python and pip commands by specifying the full path, like we did when executing the foo.sh command earlier.
+
+By default, if you run python, the shell will invoke the python command from the "system" Python environment because it is in a directory included in the PATH variable. If you specify the full path, you override this.
+
+To save typing, the bin directory of a virtual environment contains an activate file. The activate file is a "special" shell script that must be invoked like this:
+
+```
+$ . <some path>/bin/activate
+```
+
+. is a special shell command that the activate script requires to work correctly.
+
+activate alters your path, so that the bin directory in your virtual environment comes first in your path.
+
+```
+$ echo $PATH
+/home/user/.local/bin:/home/user/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
+$ . <some path>/bin/activate
+(some path) $ echo $PATH
+<some path>/bin:/home/user/.local/bin:/home/user/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
+```
+
+, and thus if you run python, <some path>/bin/python will be executed instead of /usr/bin/python.
+
+Besides changing your prompt to indicate the virtual environment is activated, activate only alters your PATH. activate is not mandatory to use a virtual environment. For example, when running the Python command, if you specify the path of the Python executable in a virtual environment, the command will execute as if the virtual environment had been activated. Virtual environment management tools also have commands that can run commands inside a virtual environment without activating it. Activation can save time, but it is also more error-prone than more explicit means of using virtual environments.
diff --git a/blog/content/notes/tech/ripping.gmi b/blog/content/notes/tech/ripping.gmi
new file mode 100644
index 00000000..c2ab2ede
--- /dev/null
+++ b/blog/content/notes/tech/ripping.gmi
@@ -0,0 +1,67 @@
+# Ripping
+
+## Media
+
+=> https://arstechnica.com/civis/threads/ripping-optical-media.1507399/post-43734994 Main source
+
+### Audio CD
+
+About 200-300 MB per album CD when ripped to FLAC.
+
+### DVD
+
+About 4-8 GB per disc, averaging 5.6 GB per movie as ISO.
+
+### Blu-ray
+
+About 20-50 GB per disc, averaging 37 GB per movie as ISO.
+
+## Hardware
+
+### Reader
+
+I got a Verbatim external USB Blu-ray writer for about 120€.
+
+### Storage
+
+=> https://diskprices.com/ See diskprices.com
+
+## Software
+
+### Audio
+
+=> https://abcde.einval.com/wiki/ abcde claims to rip and compress to FLAC and tag automatically.
+
+### DVD
+
+Use dd to rip DVD. However, dd can fail on some disks, perhaps due to damage or copy protection.
+
+=> https://unix.stackexchange.com/a/642790 This post on unix.stackexchange describes a trick that works:
+
+* Start playback of the disc using VLC.
+* Try dd first, if it fails, then run a command like "ddrescue -n -b2048 -K1M /dev/sr0 x.iso x.map".
+* After dd or ddrescue starts running, quit VLC.
+
+For playback, most software (including Kodi and VLC for Android) can play back DVD ISO with full menu support
+
+### Blu-ray
+
+=> http://fvonline-db.bplaced.net/ FindVUK has the keys to play Blu-ray discs ripped with dd.
+
+However, with encrypted Blu-ray discs, you need to configure the keys in each device where you want to play back the content. (And this is not easy or possible in some cases.)
+
+=> https://git.sr.ht/~shironeko/blu-save blu-save can remove the encryption.
+
+Remember to specify the path to the keys when running blu-save.
+
+However, VLC is confused by the AACS and CERTIFICATE directories that blu-save copies to the output. If you remove them, then VLC can play the BDMV directory with menus, etc.
+
+You can repack a Blu-ray extracted with blu-save by running a command like:
+
+```
+mkisofs -allow-limited-size -o .../my.iso .
+```
+
+from the directory that contains *only* the BDMV directory.
+
+VLC for desktop computers can open a repacked Blu-ray ISO and show the menus. Kodi for Android can open a repacked Blu-ray ISO and identify the titles. However, Kodi did not support the menus for the Blu-ray I tested.
diff --git a/blog/content/notes/tech/running-commands-in-linux.gmi b/blog/content/notes/tech/running-commands-in-linux.gmi
new file mode 100644
index 00000000..4fe4a004
--- /dev/null
+++ b/blog/content/notes/tech/running-commands-in-linux.gmi
@@ -0,0 +1,259 @@
+# Running commands in Linux
+
+## Motivating examples
+
+=> https://cwe.mitre.org/data/definitions/1337.html The 2021 CWE Top 25 Most Dangerous Software Weaknesses helps focus on the biggest security issues that developers face.
+
+=> https://cwe.mitre.org/data/definitions/78.html Number 5 on that list is Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
+
+Software developers often write code that invokes other programs. For example, shell scripts tend to be mostly composed of invocations of programs such as find, grep, etc. Even software developed in languages such as Python, C, or Java often invokes other programs.
+
+Python software developers use the subprocess module to perform this task. Other languages provide similar facilities.
+
+Consider the two following Python sessions to execute an equivalent to the bash statement "cat /etc/passwd":
+
+```
+$ python3
+>>> import subprocess
+>>> subprocess.run(["cat", "/etc/passwd"])
+```
+
+```
+$ python3
+>>> import subprocess
+>>> subprocess.run("cat /etc/passwd", shell=True)
+```
+
+Both scripts use the same run function, with different values of the shell parameter (the shell parameter defaults to True). When executing a command with many arguments, shell=True seems to be terser. "a b c d e" is shorter and easier to read than ["a", "b", "c", "d", "e"]. Readable code is easier to maintain, so a software developer could prefer the shell=True version.
+
+However, using shell=True can introduce the "OS Command Injection" weakness easily.
+
+Create a file named "injection.py" with the following contents:
+
+```
+import sys
+import subprocess
+
+subprocess.run(f"cat {sys.argv[1]}", shell=True)
+```
+
+This program uses the cat command to display the contents of a file.
+For example, if you run (using Python 3.6 or higher):
+
+```
+$ python3 injection.py /etc/passwd
+```
+
+The terminal shows the contents of the `/etc/passwd` file.
+
+However, if you run:
+
+```
+$ python3 injection.py '/etc/passwd ; touch injected'
+```
+
+The terminal shows the same file, but a file named `injected` also appears in the current directory.
+
+Create a file named "safe.py" with the following contents:
+
+```
+import sys
+import subprocess
+
+subprocess.run(["cat", sys.argv[1]])
+```
+
+Running "python3 safe.py /etc/passwd" has the same behavior as using injection.py. However, repeating the command that creates a file using safe.py results in:
+
+```
+$ python3 safe.py '/etc/passwd ; touch injected'
+cat: '/etc/passwd ; touch injected': No such file or directory
+```
+
+injection.py is vulnerable to "OS Command Injection" because it uses shell=True, whereas safe.py is not.
+
+If a malicious user can get strings such as "/etc/passwd ; touch injected" to code that uses shell=True, then the user can execute arbitrary code in the system. Code that does not handle user input might not be exposed to such issues, but user input might creep in and introduce unexpected vulnerabilities. Avoiding the use of `shell=True` and similar features can be safer than making sure that user input is correctly handled in all cases.
+
+## Writing shell scripts that handle files with spaces in their names
+
+Create a file called backup.sh with the following contents:
+
+```
+#!/bin/bash
+
+for a in $1/* ; do
+ cp $a $a.bak
+done
+```
+
+Run the following statements in the terminal to create a sample directory with files.
+
+```
+$ mkdir backup_example_1
+$ for a in $(seq 1 9) ; do echo $a >backup_example_1/$a ; done
+```
+
+These statements create the backup_example_1 directory, and files named 1 ... 9.
+
+The backup.sh script creates a copy of each file in a directory. If you run:
+
+```
+$ bash backup.sh backup_example_1/
+```
+
+Then the script will copy 1 to 1.bak, and so on.
+
+However, if you create a new directory with files whose names have spaces:
+
+```
+$ mkdir backup_example_2
+$ for a in $(seq 1 9) ; do echo $a >backup_example_1/"file $a" ; done
+```
+
+Then the backup.sh script does not work correctly:
+
+```
+$ bash backup.sh backup_example_2/
+cp: cannot stat 'backup_example_2//*': No such file or directory
+```
+
+In order to fix the script, change the contents of backup.sh to:
+
+```
+#!/bin/bash
+
+for a in "$1/*" ; do
+ cp "$a" "$a.bak"
+done
+```
+
+## Background
+
+### int main(int argc, char *argv[])
+
+Programs written in C for Linux define a function called main that is the entry point of the program. Documents such as the N2310 draft of the C language standard describe the main function. Page 11, section 5.1.2.2.1, "Program startup", provides a common definition of main:
+
+```
+int main(int argc, char *argv[]) { /* ... */ }
+```
+
+=> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf The N2310 draft of the C language standard
+
+The argc parameter contains the **c**ount of the arguments provided to the program. The argv parameter contains their **v**alues.
+
+Create a file named argv.c with the following contents:
+
+```
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ for(int i=0; i<argc; i++) {
+ printf("Argument %d -%s-\n", i, argv[i]);
+ }
+}
+```
+
+Compile the file running the following command:
+
+```
+$ cc argv.c
+```
+
+This produces an executable file named "a.out". This executable will print the arguments you provide via the command line:
+
+```
+$ ./a.out
+Argument 0 -./a.out-
+```
+
+```
+$ ./a.out arg1 arg2 arg3
+Argument 0 -./a.out-
+Argument 1 -arg1-
+Argument 2 -arg2-
+Argument 3 -arg3-
+```
+
+Note that the first argument is the name of the executable file itself.
+
+Note that when using quoting, the program prints things like:
+
+```
+$ ./a.out "a b" c
+Argument 0 -./a.out-
+Argument 1 -a b-
+Argument 2 -c-
+```
+
+So the first argument is "a b" (without quotes).
+
+### exec(3)
+
+UNIX-like operating systems provide the "exec" family of functions to invoke commands. "man 3 exec" describes the exec family of functions in Linux. Linux provides the execl, execlp, execle, execv, execvp, and execvpe functions. These functions allow us to execute a command from within a C program.
+
+Create a file named execlp.c with the following contents:
+
+```
+#include <stdlib.h>
+#include <unistd.h>
+
+int main() {
+ exit(execlp("cat", "cat", "/etc/passwd", NULL));
+}
+```
+
+Compile the file running the following command:
+
+```
+$ cc execlp.c
+```
+
+This produces an executable file named "a.out".
+Execute it:
+
+```
+$ ./a.out
+```
+
+This is equivalent to running in a shell the statement "cat /etc/passwd".
+
+This article does not describe the intricacies of the exec family of functions. However, let's analyze the call to execlp.
+
+The exec functions whose name contains a "p" look up the command to execute by searching for executables named like the first argument in the directories listed in the PATH environment variable. In the example, execlp looks up the cat executable in directories such as /usr/bin.
+
+The second argument is also the name of the program.
+
+Note that in the preceding argv.c example, the zeroth argument is the name of the program being executed. Some executables in Linux systems are present under different names (using symbolic links). For example, xzcat is a symbolic link to xz. Running xzcat or xz runs the same executable file, but the executable uses the zeroth argument to change its behavior.
+
+This technique is a simple way to "share" code between similar programs. The BusyBox project provides many common utilities, such as ls and cat, in a single executable. By sharing code among all utilities, the BusyBox executable is smaller.
+
+The rest of the parameters to execlp are the arguments for the executable file.
+
+In a way, exec functions "call" the main function of other programs. The parameters to exec are "passed" to the main function.
+
+### Shells
+
+Programs such as bash provide a way to execute other programs. When you type a statement such as "cat /etc/passwd", bash parses the statement into a command to execute and arguments. Then, bash uses an exec function to run the program with arguments.
+
+The simplest bash statements are words separated by spaces, of the form "arg0 arg1 arg2 ... argn".
+
+On such a statement, bash executes something like:
+
+```
+execlp(arg0, arg0, arg1, _..._, argn, NULL)
+```
+
+And the program will receive the string arg0 as the zeroth argument, arg1 as the first argument, and so forth.
+
+However, using cat to view the contents of files, the user might want to view a file whose name contains spaces.
+
+The statement "cat a b" has two arguments: a and b. For each argument, cat prints the file of that name. So the "cat a b" statement prints the contents of the a and b files, not of a file named "a b".
+
+## Further reading
+
+=> http://teaching.idallen.com/cst8177/13w/notes/000_find_and_xargs.html Using find -exec or xargs to process pathnames with other commands
+=> https://infosec.exchange/@david_chisnall/115116683569142801 Early UNIX did glob expansion in the shell not because that’s more sensible than providing a glob and option parsing API in the standard library, but because they didn’t have enough disk space or RAM to duplicate code and they didn’t have shared libraries... For example, on FreeBSD, I often do pkg info foo* to print info about packages that start with some string. If I forget to quote the last argument, this behaves differently depending on whether the current directory contains one or more files that have the prefix that I used. If they do, the shell expands them and pkg info returns nothing because I don’t have any installed packages that match those files. If they don’t, the shell passes the star to the program, which does glob expansion but against a namespace that is not the filesystem namespace. The pkg tool knows that this argument is a set of names of installed packages, not files in the current directory, but it can’t communicate that to the shell and so the shell does the wrong thing. Similarly, on DOS the rename command took a load of source files and a destination file or pattern. You could do rename *.c *.txt and it would expand the first pattern, then do the replacement based on the two patterns. UNIX’s mv can’t do that and I deleted a bunch of files by accident when I started using Linux because it’s not obvious to a user what actually happens when you write mv *.c *.txt. There is a GNU (I think?) rename command and its syntax is far more baroque than the DOS one because it is fighting against the shell doing expansion without any knowledge of the argument structure.
+
+## TODO
+
+=> https://news.ycombinator.com/item?id=36722570 SSH particularities
diff --git a/blog/content/notes/tech/so-you-want-to-play-with-functional-programming.gmi b/blog/content/notes/tech/so-you-want-to-play-with-functional-programming.gmi
new file mode 100644
index 00000000..2e8abec5
--- /dev/null
+++ b/blog/content/notes/tech/so-you-want-to-play-with-functional-programming.gmi
@@ -0,0 +1,201 @@
+# So you want to play with functional programming
+
+If you are a programmer working on popular languages such as Python or Java, you are likely to have read articles about "functional programming". These articles can give you the idea that learning functional programming improves your skills as a programmer. I share this opinion.
+
+This article tries to help people who have read about functional programming figure out how to proceed.
+
+Note that this article expresses personal opinion. Particularly, I am not an expert in this topic:
+
+* I have programmed some Haskell (about 50 Project Euler problems, plus experimentation on and off during the years).
+* I have studies of SML and functional programming.
+* I have some minimal experience with Lisp.
+* I have applied some functional programming techniques while being paid to write in non-functional programming languages.
+* However, I have never been paid to write in any of those languages.
+
+Shortly after writing this, I was shown:
+
+=> https://technomancy.us/194 In which there is no such thing as a functional programming language
+
+I agree with most of that the article explains. I might extend this article with some similar ideas, but for the moment, I recommend reading that carefully before reading the rest of this article.
+
+## The basics of functional programming
+
+=> https://en.wikipedia.org/wiki/Functional_programming The Wikipedia article on functional programming is a great place to get started.
+
+The article describes a few concepts related to functional programming. I consider the following two the pillars of functional programming:
+
+* First-class and higher order functions. In languages with first-class functions, functions are values that you can use like other types such as integers. Higher-order functions are functions that take functions as arguments or return functions.
+* Pure functions. Pure functions always return the same value for a given set of arguments. Pure functions also have no side effects; they do not modify anything in the system they run. For example, a function that creates a file is not pure.
+
+These concepts can be applied in most popular programming languages.
+
+For example, in Python:
+
+```
+def hello():
+ print("hello")
+
+def twice(f):
+ f()
+ f()
+```
+
+twice is a higher order function because it takes a function as an argument. Functions are first-class functions because you can use hello as a value:
+
+```
+>>> twice(hello)
+hello
+hello
+```
+
+Similarly, you can write pure functions in almost any language.
+
+When you have first-class functions, you can define some higher-order functions that generalize some common code. Three very common higher-order functions are:
+
+* Filter applies a function to each element of a list, and returns a list composed of the elements for which the function returned true.
+* Map applies a function to each element of a list, and returns a list of the result of the application of the function to each element.
+* Fold. A fold starts from an initial value, then calls a function with the initial value and the first element of the list. Then it calls the function with the result of the previous call, and the next element of the list. This continues until the list end, returning the last result of the function.
+
+(For example, folding with the sum operator and an initial value of 0, sums the elements of a list.)
+
+Note that you can implement many list manipulations by composing filters, maps, and folds with different functions. (And by adding more higher-order functions, you can implement more list manipulations.)
+
+Also, you can manipulate other data structures with equivalent or other higher-order functions.
+
+Implementing code using higher-order functions and pure functions already has some interesting benefits.
+
+* Impure functions frequently require more mental overhead to understand, because you need to understand state. With pure functions, you do not have to think about state.
+* To understand a program written as a composition of functions, you can start by understanding individual functions and then understand how they fit together. The same program written as a sequence of statements is often more difficult to understand. (However, sometimes the opposite effect occurs.)
+
+You can use these concepts in most popular programming languages. (Most popular languages also provide higher-order functions such as filters, maps, and folds.)
+
+So you can get started with functional programming by using the programming languages you already know:
+
+* Try to write as much code as possible as pure functions.
+* Learn which higher-order functions your programming language provides.
+* Learn how to implement higher-order functions.
+* Write code by composing pure functions with higher-order functions.
+
+## The consequences of first-class functions, higher-order functions, and pure functions
+
+Writing code using these concepts often leads to:
+
+* Writing cumbersome code if the programming language you use lacks certain features.
+* Unlocking additional functional programming techniques.
+
+Therefore, many programming languages provide features that make functional programming more straightforward, or features enabled by functional programming. Languages providing features related to functional programming are commonly named "functional programming languages".
+
+Although you can use functional programming with non-functional programming languages, this can often lead to:
+
+* Extra effort
+* Not being able to use the full spectrum of functional programming features
+
+### The need for powerful type systems and type inference
+
+Higher-order functions often have complex type requirements. For example, to filter a list of a given type, you must pass a function that takes a single argument of that type and returns a boolean. If the arguments do not have the correct types, then the code does not work correctly.
+
+In languages with dynamic types, the program fails at runtime. In languages with static types, you frequently must specify the types, and higher-order functions often require complex types involving different function types.
+
+Functional programming languages frequently:
+
+* Have static types, to prevent frequent runtime failures.
+* Automatically infer types instead of requiring programmers to declare them. (However, automatic type inference can cause issues in some scenarios, so frequently programming languages allow writing explicit types, or even require explicit types in some cases.)
+
+Because functional programs often use more complex types, functional programming languages often have more powerful type systems than non-functional programming languages.
+
+Derived from those properties, functional programming languages result in the "if it compiles, it works *correctly*" phenomenon. This phenomenon helps avoid incorrect programs.
+
+## Functional programming languages
+
+### Haskell
+
+Functional programming practitioners often recommend Haskell as a functional programming language.
+
+According to the Wikipedia, "Haskell is a general-purpose, statically-typed, purely functional programming language with type inference and lazy evaluation". Also, Haskell was designed by a committee whose purpose was "to consolidate existing functional languages into a common one to serve as a basis for future research in functional-language design".
+
+* Haskell is perhaps the language with more built-in functional programming features. As mentioned, Haskell is used for research about functional programming, therefore many new concepts appear in Haskell first.
+* Haskell is also very strict about functional programming, so Haskell drives programmers more strongly towards avoiding non-functional programming.
+* Haskell syntax is designed so Haskell programs can be extremely terse and contain almost no extraneous syntax.
+* Haskell is a very popular language, with a very large ecosystem. You can take advantage of many existing libraries and tools for developing real-world programs faster.
+
+However, Haskell's benefits frequently also are negative for learning.
+
+* Haskell uses "lazy" evaluation, where most programming languages use "eager" evaluation. Haskell does not evaluate expressions until needed (and might not evaluate some expressions). Lazy evaluation can lead to efficiency and clearer programs. However, lazy evaluation can cause unexpected performance problems.
+
+=> https://wiki.haskell.org/Foldr_Foldl_Foldl%27 "Foldr Foldl Foldl'" explains how choosing incorrectly among different implementations of fold can lead to impactful performance problems.
+
+When writing Haskell code for learning, you can likely stumble into issues not present in languages that use eager evaluation.
+
+* Haskell is very strict about purity. To implement programs that have side effects, such as accessing files, you must use specific language features. Many articles try to explain those features, because many people have trouble understanding them.
+
+* Many libraries and tools in the ecosystem take advantage of powerful features enabled by Haskell. However, this might cause that using these libraries and tools require the understanding of the features they are based upon.
+
+Also, Haskell syntax is very terse, which leads to Haskell compilers not providing clear error messages. For example:
+
+```
+$ ghci
+> let sum a b = a + b
+> sum 2 2
+4
+> sum 2 2 2
+
+<interactive>:3:1: error:
+ • Non type-variable argument in the constraint: Num (t1 -> t2)
+ (Use FlexibleContexts to permit this)
+ • When checking the inferred type
+ it :: forall {t1} {t2}. (Num t1, Num (t1 -> t2)) => t2
+```
+
+In complex programs, programmers new to Haskell might have trouble identifying that a function has been called with an extra argument from that error message.
+
+Personally, Haskell is my favorite functional programming language. However, I learned Haskell after learning (with teachers and support from others) other functional programming languages. I think that Haskell is ideal to learn the most powerful concepts in functional programming, but it is not as ideal as a first functional programming language.
+
+(Note that these recommendations come from someone who only has implemented about 50 Project Euler problems in Haskell, and has experimented on and off with the language, but not been paid for it.)
+
+### Lisp
+
+Many programmers like Lisp and languages in the Lisp family, such as Scheme or Clojure. Lisp programmers often recommend Lisp to learn functional programming.
+
+Lisp is a very minimalistic, yet infinitely flexible language. Lisp is extensible, so you can add most programming language features to Lisp, including functional programming features.
+
+Therefore, you can do functional programming in Lisp, and also benefit from all other Lisp features.
+
+However, languages in the Lisp family tend to not have static typing and associated features, thus do not frequently exhibit the "if it compiles, it works *correctly*" phenomenon.
+
+Lisp has one of the simplest syntaxes of any programming language. The simple syntax of Lisp is directly tied to its power. Many favor the Lisp syntax and argue that the syntax makes Lisp better for learning programming. Personally, I find the Lisp syntax hard to read and write, and likely an additional difficulty on top of learning functional programming.
+
+I recommend learning Lisp because it is a unique programming language that can teach you many programming language concepts that are not present in many other languages. However, I do not recommend Lisp for learning functional programming (unless you already know Lisp).
+
+(Note that these recommendations come from someone who has some formal training on Lisp but only uses Lisp infrequently [as a recent Emacs user].)
+
+### The ML family of programming languages
+
+ML is a language that appeared in 1973. Since then, three dialects have become the most popular implementations of ML:
+
+* OCaml
+* Standard ML
+* F# (part of the .NET platform)
+
+Specifically, OCaml and F# have very strong ecosystems (OCaml because it is a popular and mature language, F# because as part of the .NET platform, it can use many .NET libraries and tools).
+
+Haskell is inspired by ML, but many of the Haskell features discussed above are not present in the ML languages:
+
+* MLs have eager evaluation, therefore avoiding the performance pitfalls of Haskell.
+* MLs have simpler syntax, therefore frequently leading to clearer error messages.
+
+For example, compare the following snippet of OCaml to the previous error message example from Haskell:
+
+```
+$ utop # utop is a friendlier OCaml REPL
+# let sum a b = a + b ;;
+val sum : int -> int -> int = <fun>
+# sum 2 2 ;;
+- : int = 4
+# sum 2 2 2 ;;
+Error: This function has type int -> int -> int
+ It is applied to too many arguments; maybe you forgot a `;'.
+```
+
+In my opinion, OCaml and F# are better languages for the initial learning of functional programming than Haskell. After learning an ML, you are likely more prepared to learn Haskell and more sophisticated functional programming.
+
+(Note that those recommendations come from someone who only has experimented with OCaml and F#, and learned SML formally.)
diff --git a/blog/content/notes/tech/ssh-for-beginners.gmi b/blog/content/notes/tech/ssh-for-beginners.gmi
new file mode 100644
index 00000000..0c74b2e4
--- /dev/null
+++ b/blog/content/notes/tech/ssh-for-beginners.gmi
@@ -0,0 +1,88 @@
+# SSH for beginners
+
+Some simple advice for people who are starting to use ssh.
+
+## Use the config
+
+If you create a file "~/.ssh/config", with contents like:
+
+```
+Host xxx
+ HostName yyy
+ Port 1234
+ User zzz
+```
+
+, then if you type "ssh xxx", the result will be like executing "ssh -p 1234 zzz@yyy".
+
+Any ssh command line arguments can be encoded in an SSH client configuration file, so you can access any server by just passing a host to ssh without any additional parameters.
+
+Additionally, most modern systems configure SSH tab completion, so if you type "ssh <tab><tab>", your shell will complete with the hosts in your configuration file.
+
+## Use public key authentication
+
+By default, ssh uses passwords for authentication. If you use a good password, then password authentication is a decent authentication method.
+
+However, you can use other methods, such as public key authentication. With public key authentication, you have a public and private key.
+
+If you are working on system A with your *private* key, and you copy your *public* key to system B, then you can ssh from system A to system B without entering a password.
+
+### Security
+
+Note that if someone obtains your private key, they will be able to log in to systems that trust your key. Knowledge of your private key is similar to knowledge of a password. Take care making your private key truly private.
+
+If you suspect someone else has been able to obtain your private key, then generate a new key and remove the leaked public key from all systems.
+
+Note that you can generate as many keys as you want. Managing multiple keys requires more effort, but in some cases it might be more convenient. For example, if a key is suspected to be leaked, then you might only need to revoke a key and continue using other keys.
+
+### Generating SSH keys
+
+To generate your private and public keys:
+
+```
+$ ssh-keygen
+Generating public/private rsa key pair.
+Enter file in which to save the key (/home/alex/.ssh/id_rsa):
+Created directory '/home/alex/.ssh'.
+Enter passphrase (empty for no passphrase):
+Enter same passphrase again:
+Your identification has been saved in /home/alex/.ssh/id_rsa
+Your public key has been saved in /home/alex/.ssh/id_rsa.pub
+The key fingerprint is:
+SHA256:...
+The key's randomart image is:
++---[RSA 3072]----+
+...
+```
+
+### Key type choice
+
+OpenSSH, the standard ssh client, changed its default type of key generation to Ed25519 in version 9.5 released in late 2023. Previously, ssh-keygen generated RSA keys, as in the example above. Many Linux distributions still use OpenSSH versions earlier than 9.5.
+
+You can find advisories like:
+
+> It is quite possible the RSA algorithm will become practically breakable in the foreseeable future. All SSH clients support this algorithm.
+
+=> https://www.ssh.com/academy/ssh/keygen
+
+Although as of the time of writing this, RSA is considered safe. However, you can consider generating an Ed25519 key instead, following the most recent OpenSSH defaults.
+
+### Passphrases
+
+By default, if you provide an empty passphrase to ssh-keygen, your private key will be stored unprotected. Anyone that can read the private key file can obtain your key.
+
+You can use a passphrase to protect your key. If someone obtains a private key file but they don't know the passphrase, then they cannot use the key.
+
+Using a passphrase means that you need to type the passphrase every time you use the key, or use a system such as ssh-agent. This creates a tradeoff between security and convenience.
+
+(Note that a popular criticism of SSH public key authentication is that it is not easy for systems administrators to enforce the use of SSH passphrases.)
+
+## Further SSH features
+
+Many developers have added many useful features to SSH during many years, such as:
+
+* The scp command to transfer files using SSH
+* Tunnels to establish bidirectional communication between systems without such connectivity. (For example, to connect to your workstation from a remote system.)
+* Jump hosts that expedite the connection to a system that is not directly accessible, by using SSH to establish connection through intermediate systems.
+
+Also, SSH integrates very well with UNIX pipes and tools such as rsync, Git, and many others.
diff --git a/blog/content/notes/tech/take-the-less-traveled-road.gmi b/blog/content/notes/tech/take-the-less-traveled-road.gmi
new file mode 100644
index 00000000..e9107470
--- /dev/null
+++ b/blog/content/notes/tech/take-the-less-traveled-road.gmi
@@ -0,0 +1,29 @@
+# Take the less traveled road
+
+> Two roads diverged in a wood, and I—
+
+> I took the one less traveled by,
+
+> And that has made all the difference.
+
+=> https://www.gutenberg.org/cache/epub/59824/pg59824-images.html#THE_ROAD_NOT_TAKEN Robert Frost, The Road Not Taken
+
+=> https://xkcd.com/743/ Infrastructures, by Randall Munroe
+
+The prisoner's dilemma describes situations where people can choose to act in their own interest or collaborate with others. I believe the prisoner's dilemma is present everywhere in our daily life and can explain many behaviors and situations.
+
+One such scenario is when we choose services to use on the Internet.
+
+Frequently, we choose services that are easy, popular, and even have no cost.
+
+In the past, even non-technical people got shared hosting and ran WordPress to blog, with nearly total control about their communication. Nowadays, mostly everyone uses something like Twitter and cedes control to a company.
+
+Using Twitter is easier than self-hosting WordPress. Twitter is so popular, that your message will likely reach more users on Twitter than on an independent blog. And you can use Twitter for free, whereas shared hosting costs you money and time.
+
+Twitter became dominant and nowadays, many are frustrated by how Twitter has changed.
+
+Dominance implies lack of competition, which is nearly always bad for the consumer.
+
+Which means choosing which services to use frequently is a difficult choice.
+
+We all have limited time and energy, but I propose that whenever you can, you should take the less traveled road. The easy alternative likely benefits you in the short term, but can easily contribute to a monoculture that will damage everyone in the end, including you.
diff --git a/blog/content/notes/tech/the-tragedy-of-the-geeks.gmi b/blog/content/notes/tech/the-tragedy-of-the-geeks.gmi
new file mode 100644
index 00000000..e5ce1b10
--- /dev/null
+++ b/blog/content/notes/tech/the-tragedy-of-the-geeks.gmi
@@ -0,0 +1,65 @@
+# The tragedy of the geeks
+
+Since the first computer entered our home, I was hooked. This happened more than four decades ago, and continuously tinkering with computers has given me a well-paid and comfortable job.
+
+However, getting such jobs seems linked to spending a significant amount of your personal time practicing your skills.
+
+Many people seek careers related to computing because jobs have attractive conditions. However, they might later regret the time and energies spent trying to get into the field when they learn that getting a good job requires unexpected effort.
+
+This document tries to explain to people who want to work with computers this phenomenon, to help them make a better decision.
+
+## Tinkering
+
+Working with computers is the only career I can think of where all of the following are true at the same time:
+
+* You can work on personal projects that are very similar to the projects you would do in a job.
+* There is a reputation of abundant well-paid job offers with good conditions.
+* Working on personal projects sounds fun.
+
+This means that many of us end up spending a significant amount of time working on personal projects. This time investment increases our skills and the things we know.
+
+## Hiring
+
+Hiring is one of the most highly debated topics in this industry.
+
+Many people believe that many candidates cannot do the job. There are many stories about new hires who cannot write simple programs.
+
+Whether this is common or not is not as important as whether people making decisions believe there are large differences between candidates. When people who hire think that their hiring decision is going to have a large effect on them, then they want to make sure that they pick the right person.
+
+My perception is that most of the organizations that offer good job conditions (and many who do not) try to be very selective in hiring people.
+
+## Hiring tinkerers
+
+When you are hiring people, candidates who have spent significant time on personal projects tend to stand out over candidates who have not.
+
+This improved perception during the hiring process does not necessarily relate to improved performance on the job. However, I believe that people who tinker on their spare time tend to land better jobs.
+
+## Handing out advice
+
+Because there are good jobs working with computers, many people think about making a career in the industry.
+
+There are many curriculums and formal education programs, from shorter (typically one year) to longer (four or five years).
+
+Some of them provide advice to land a good job, and students who follow programs who do not, tend to ask for advice. In any case, one of the most frequent pieces of advice on the topic, is tinkering on your own time.
+
+I believe this is actually good advice, as in that it's more likely to be an efficient way to increase your prospects.
+
+However, remember that hiring is roughly a competitive process. An organization evaluates a group of candidates, and tries to pick the best one.
+
+So to stand out, if more candidates tinker (because this is effective advice), the more you need to tinker to stand out.
+
+I cannot estimate how much you need to tinker on your own time to land a good job, but my guess is that it is more than what someone wanting to get into the field expects.
+
+As long as this dynamic continues, the tinkering required to land a good job will increase. Only reduced competition can reduce the tinkering required, and reduced competition can happen by few factors, such as increased demand for workers, or a reduction in job seekers.
+
+## Breaking the cycle
+
+I cannot think of much that we can individually do to break the cycle.
+
+Maybe if people coming into the field are aware of this phenomenon, they will be able to make a better decision about what to do.
+
+If a sufficient amount of people decide that the time investment is not worthwhile, then perhaps the competition will decrease. And if people are well informed and decide to move forward, at least they will be less likely to become frustrated or regret their decision.
+
+## Further reading
+
+=> https://bertrandmeyer.com/2025/04/23/a-paean-to-programming/ A paean to programming, by Bertrand Meyer
diff --git a/blog/post-receive b/blog/post-receive
index 0721ce3b..f69abaf6 100755
--- a/blog/post-receive
+++ b/blog/post-receive
@@ -27,7 +27,9 @@ with tempfile.TemporaryDirectory() as tempdir:
tempdir = pathlib.Path(tempdir)
repo = tempdir / "repo"
subprocess.run(["git", "worktree", "add", repo, pushed_commit], check=True)
- blog = repo / "blog"
- os.chdir(blog)
- os.environ["PATH"] = "/home/alex/.local/bin:" + os.environ["PATH"]
- subprocess.run(["./build.sh", dest], check=True)
+ try:
+ blog = repo / "blog"
+ os.environ["PATH"] = "/home/alex/.local/bin:" + os.environ["PATH"]
+ subprocess.run(["./build.sh", dest], check=True, cwd=blog)
+ finally:
+ subprocess.run(["git", "worktree", "remove", repo], check=True)