Todo funcionó como esperado al seguir el quickstart, pero al cerrar y abrir mi terminal toda su configuración dejo de funcionar.
Fue de usar catppuccin y remover el tab-line a tener su configuración default.

WezTerm con mi configuración activada

WezTerm con su configuración default
Después de pasar una cantidad de tiempo absurda tratando de ver porque no tomaba mi configuración encontré que Claude Code busca la configuración de WezTerm siguiendo su documentación y asume que solo puede estar en el directorio home del usuario:
> /terminal-setup
⎿ Installed WezTerm Shift+Enter key binding
You may need to restart WezTerm for changes to take effect
See /Users/froi/.wezterm.lua
─────────────────────────────────────────────────────────────────────────────────
>
─────────────────────────────────────────────────────────────────────────────────
? for shortcuts Thinking on (tab to toggle)
Este comando lo que intenta añadir es configuración que permita usar SHIFT+Enter para enviar un prompt de multiples lineas, lo cual es util.
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
config.keys = {
{key="Enter", mods="SHIFT", action=wezterm.action{SendString="\x1b\r"}},
}
return config
Por ahora lo único que se puede hacer es mover tu configuración a ~/.wezterm.lua o añadir la entrada a config.keys manualmente. En mi caso eso fue lo que hice.
Ya existe un bug reportando este comportamiento. No me sorprendería si esto no es un tema exclusivo a WezTerm y me pregunto si Anthropic arreglara el problema.
]]>Después de separarme de la compañía en el 2021, he visto como el cambio acelerado la ha llevado de mal en peor. Es una pena que una plataforma tan integral a lo que era ser un developer en el internet se haya convertido en un vehiculo para aumentar el consumo de Azure y ahora AI para Microsoft. Sí, esto lleva mucho tiempo cuajándose, pero la última gota para mi fue cuando el CEO de GitHub renunció y la compañía completa fue integrada al equipo de AI en Microsoft.
Si soy honesto, mi discontento con GitHub lleva tiempo pero me hice de la vista larga. Ignoré y hasta vendí ciertos valores por quedarme en lo conocido. Me enfoqué en lo que me gustaba de la plataforma y me dije “lo que tengo que hacer es no utilizar lo que no me gusta”.
Llevo unos meses probando alternativas para mover la mayoría del código que me pertenece a otras plataformas. Digo la mayoría porque la verdad es que no todo con lo que he trabajado es mio. Todo lo que hice con Code for Puerto Rico se va a quedar en GitHub junto a los forks que hice de proyectos que viven en ahí.
froidotdev era un repositorio en GitHub y la página estaba siendo servida mediante GitHub Pages. Eso cambio al escribir este post.
El contenido de esta página ahora vive en GitLab en un repositorio privado y está servido como un static site app en DigitalOcean.
Siendo una página generada utilizando Hugo hizo el movimiento extremadamente fácil. DigitalOcean tiene un excelente tutorial de como construir y hacer deploy de un Hugo site.
Fuera de cambiar el uso de GitHub, tuve que añadir HUGO_EXTENDED = 1 como variable de ambiente para especificar que versión de Hugo utilizar. Esto se debe al uso de Sass/SCSS en el theme de la página.
Voy a estar experimentando con Codeberg.org, Forgejo y GitLab.
Me gusta mucho Forgejo, me recuerda un poco a lo que era GitHub en el pasado. Es una plataforma que se hace fácil hacer self hosting y quiero ver si es algo que me conviene hacer.
Por esto, todo lo que es FOSS donde soy el dueño lo estaré moviendo a Codeberg.org/froi. Codeberg.org es una entidad sin fines de lucro operando en Berlín que maneja una instancia de Forgejo. Su misión y la estructura bajo la que operan me llama mucho la atención. Cubre todo lo que considero importante para mí dentro de FOSS, todo lo que ignoré por mucho años. Todo lo que estoy trabajando fuera del ambito de FOSS lo estaré moviendo a GitLab.
Codeberg.org está 100% dedicado al apoyo a FOSS. Dentro de sus terminos de uso especifica que no apoya repositorios privados (con excepciones) u organizaciones con fines de lucro que trabajen con código propietario. Quiero respetar esto. Por ende, todo proyecto con fin de lucro o que no sea 100% abierto lo estaré trabajando desde GitLab. Es importante que protejamos los recursos como Codeberg para que estén disponibles para comunidad y evitar la tragedia de los bienes comunales (tragedy of the commons).
GitLab también provee mucha conveniencia al ser una plataforma completa. De esta manera colaborar con mi equipo remoto se agiliza. Muchas de las preguntas sobre DevOps ya están contestadas y manejadas por la plataforma. Aunque me tome “mucho” acostumbrarme a GitLab (no soy muy fanático de como está estructurado), creo que es la opción correcta y más pragmática.
Pues no sé. Por ahora creo que este arreglo va a funcionar bien. En los próximos meses intentaré seguir removiendo mi dependencia de servicios y productos de “big tech” y de compañías que sean de los EEUU, algo de lo que escribiré en otro post.
Si tienen ideas que compartir tirenme un toot a mastodon.social/@froi.
]]>While I’m still of the opinion that these comments are troublesome when going stale, I’ve changed my perspective a bit by looking at them as tags that can help me navigate a code base. These tags are hints for me or my team to take a look and action on a part of the code we’ve marked as “of interest”.
After some time accepting and working with these “tags” I started to look for tooling I could use in NVIM that would enhance my experience. I wanted these tags to be visually distinctive and I wanted my IDE/code editor to help me find them. Turns out that a few awesome folks have wanted and built this tooling, and it’s not just for big IDEs.
Let’s start by looking at the tags before we go into the tooling.
You can jump to the example configuration for VS Code / Codium if that’s all you need.
There’s a ton of tags that we could use but to keep it “short” I’ve been using some version of
The “classic” comment that can be found in many a code base.
Used to warn the reader that something is off but can’t be easily identified as a bug or hack.
Tag to indicate something is off and we should come back to fix. I also add an issue link if one exists. It’s important to note that this tag should be removed. I think it’s a big smell if a “fixme” comment is there for a long period of time. At that point, do you really need to fix it?
Tag to indicate that a piece of code might be working well but has some sort of smell or is not optimal
Tag to provide a call out for some insight around the use or structure of a piece of code. Used more to draw attention of the reader than to properly document.
Sometimes I want to add some addition context to a piece of code. I treat this tag like a “general” code comment.
I rarely use this tag, but once in a while I find I want to call out the structure of a code block as being optimize or needing optimization. I find this helps with code that might not look “normal” or following common patterns but isn’t a HACK (at least in my eyes).
Used to mark a section of code that’s meant to be a test. Imagine having a utility function that you just don’t know if you want to keep
Tooling has always been a rabbit hole for me. I was “lucky” that Lazyvim has todo-comments.nvim already packaged in the distribution.
todo-comments.nvim is another fantastic plugin by folke that
is a lua plugin for Neovim >= 0.8.0 to highlight and search for todo comments like TODO, HACK, BUG in your code base.
This plugin uses other excellent plugins like trouble.nvim, telescope, and fzflua to provide an IDE like experience.

Having the TODOS, WARNINGS, and other tags searchable and show up in trouble.nvim makes using them to navigate the code base incredibly simple. Over the last couple of weeks it’s helped me find code blocks that needed attention. While some of these comments were definitely out of date, I still found them useful. At a minimum I had a really easy time identifying where to do some clean up.
I found the default configuration for todo-comments to be exactly what I needed.
While I was perfectly happy in my Lazyvim bubble, for the rest of my team VSCode / VSCodium is the editor of choice. I found two really great extensions that make working with these tags a joy, Todo Tree and Better Comments Next.
Todo Tree will provide a similar experience to trouble and telescope, making the comments searchable and letting you navigate to them with a click.

Better Comments Next provides the color and highlighting for the comments.
To get these extensions to work similar to my NVIM plugins I added some configuration in the .vscode/settings.json file.
You will want to define a minimum set of tags that are shared in all of your IDEs and code editors. It’s fine if one is a superset of the other, but a minimum overlap will help you and your team have the same experience.
To configure Todo Tree I added two sections
todo-tree.general.tags: a list of all the tags I wanted to add/support
"todo-tree.general.tags": [
"BUG",
"HACK",
"FIX",
"FIXIT",
"FIX-IT",
"FIXME",
"FIX-ME",
"IMPORTANT",
...
],
todo-tree.general.tagGroups: an object that defines how to group the tags into categories. The keys of the objects are the categories while the values can be simple string or arrays of strings.
"todo-tree.general.tagGroups": {
"INFO": ["NOTE"],
"TODO": ["TO-DO", "[ ]", "[X]"],
"BUG": ["FIX", "FIXIT", "FIX-IT", "FIXME", "FIX-ME"],
"WARN": ["WARNING", "WAT", "XXX"],
"HACK": ["IMPORTANT", "TIP"],
"PERF": ["OPTIM", "PERFORMANCE", "OPTIMIZE"],
"TEST": ["TESTING"]
}
[Better Comments Next][better-commments-next] required a bit more configuration. Just like with Todo Tree, I needed to add a section to the configuration.
better-comments.tags: a list of objects that configure the styles of a tag
"better-comments.tags": [
{
"tag": ["todo", "to-do", "[ ]", "[X]"],
"color": "#2563EB",
"strikethrough": false,
"underline": false,
"backgroundColor": "#39579748",
"bold": false,
"italic": false,
"multiline": true
},
{
"tag": ["note", "info"],
"color": "#14D1F3FF",
"strikethrough": false,
"underline": false,
"backgroundColor": "#18879B61",
"bold": false,
"italic": false,
"multiline": true
},
...
]
Here’s a complete example showing the current configuration I use in VS Condium. For a breakdown on the extensions that I’m using take a look at VS Code and VS Codium.
{
"workbench.iconTheme": "material-icon-theme",
"workbench.sideBar.location": "right",
"editor.minimap.enabled": false,
"editor.fontSize": 18,
"better-comments.tags": [
{
"tag": "#",
"color": "#18b566",
"strikethrough": false,
"underline": false,
"backgroundColor": "transparent",
"bold": true,
"italic": false
},
{
"tag": "!",
"color": "#FF2D00",
"strikethrough": false,
"underline": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "?",
"color": "#3498DB",
"strikethrough": false,
"underline": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "//",
"color": "#474747",
"strikethrough": true,
"underline": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": ["todo", "to-do", "[ ]", "[X]"],
"color": "#2563EB",
"strikethrough": false,
"underline": false,
"backgroundColor": "#39579748",
"bold": false,
"italic": false,
"multiline": true
},
{
"tag": ["note", "info"],
"color": "#14D1F3FF",
"strikethrough": false,
"underline": false,
"backgroundColor": "#18879B61",
"bold": false,
"italic": false,
"multiline": true
},
{
"tag": "*",
"color": "#98C379",
"strikethrough": false,
"underline": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": ["hack", "important"],
"color": "#9B59B6",
"strikethrough": false,
"underline": false,
"backgroundColor": "#9C59B62B",
"bold": false,
"italic": false,
"multiline": true
},
{
"tag": ["bug", "fixme", "fix-me", "fix", "fixit", "fix-it", "issue"],
"color": "#DC2626",
"strikethrough": false,
"underline": false,
"backgroundColor": "#B95E5E47",
"bold": true,
"italic": false,
"multiline": true
},
{
"tag": ["perf", "optim", "performance", "optimize"],
"color": "#FD79A8",
"strikethrough": false,
"underline": false,
"backgroundColor": "#FD79A731",
"bold": false,
"italic": false,
"multiline": true
},
{
"tag": ["warn", "warning", "wat", "xxx"],
"color": "#FBBF24",
"strikethrough": false,
"underline": false,
"backgroundColor": "#90773860",
"bold": true,
"italic": false,
"multiline": true
},
{
"tag": ["test", "testing"],
"color": "#FF00FF",
"strikethrough": false,
"underline": false,
"backgroundColor": "#983B9871",
"bold": false,
"italic": false,
"multiline": true
}
],
"todo-tree.general.tags": [
"BUG",
"HACK",
"FIX",
"FIXIT",
"FIX-IT",
"FIXME",
"FIX-ME",
"IMPORTANT",
"INFO",
"ISSUE",
"NOTE",
"PERF",
"OPTIM",
"PERFORMANCE",
"OPTIMIZE",
"TEST",
"TESTING",
"TIP",
"TODO",
"TO-DO",
"WARN",
"WARNING",
"WAT",
"XXX",
"[ ]",
"[x]"
],
"todo-tree.general.tagGroups": {
"INFO": ["NOTE"],
"TODO": ["TO-DO", "[ ]", "[X]"],
"BUG": ["FIX", "FIXIT", "FIX-IT", "FIXME", "FIX-ME"],
"WARN": ["WARNING", "WAT", "XXX"],
"HACK": ["IMPORTANT", "TIP"],
"PERF": ["OPTIM", "PERFORMANCE", "OPTIMIZE"],
"TEST": ["TESTING"]
}
}
Starting a Celery worker with celery -A jobs worker -l INFO will look for
jobs:app or jobs:celeryjobs.celery:appIf you aren’t following these patterns you need to specify where the Celery app is. For a jobs package with a tasks submodule and a Celery app declared as celery_app the command should be:
celery --app jobs.tasks:celery_app worker -l INFO
Not using a piece of tech for a while can present relearning headaches that make you ask youself “why didn’t I just write this down somewhere the first time?”. That’s what this TIL is.
Before we start though, Celery is a distributed task queue system written in Python. It can be compared to other queue systems like
Throughout the documentation you’ll find that starting a Celery working is a simple as executing
celery -A tasks worker --loglevel INFO
When strictly following the getting started you should have no problems and thing will work as expected. Beyond this
simple use though you will want to understand hwo the -A or --app works. Especially when adding a Celery application
to a new package in an existing project.
Since I’m refreshing my Celery knowledge after years of not using it, I decided to keep it simple and as close to what is found in the Celery documentation. The only difference was that I needed to call the Celery task from a FastAPI endpoint.
I’m starting off with this project layout (very similar to what you see in the docs)
❯ tree src/jobs
src/jobs
├── __init__.py
├── steps.py
└── tasks.py
1 directory, 3 files
The tasks.py file is where I’m configuring my Clery app and where I’m also defining my initial task send_data.
steps.py is currently empty.
from celery import Celery
from app.config import config
# from .steps import get_usage_spans
celery_app = Celery("jobs", broker=config.REDIS_URI)
@celery_app.task
def send_data(data: dict[str, Any]):
... 2 ```sh
return "Send data request received: "
Starting my worker presented no issues, but the tasks was called during a request sent to the API I got this error message:
[2024-09-22 18:14:45,756: ERROR/MainProcess] Received unregistered task of type 'jobs.tasks.send_data'.
The message has been ignored and discarded.
Did you remember to import the module containing this task?
Or maybe you're using relative imports?
Please see
https://docs.celeryq.dev/en/latest/internals/protocol.html
for more information.
The full contents of the message body was:
b'[["field1", "field2", "field3", "field4"], {}, {"callbacks": null, "errbacks": null, "chain": null, "chord": null}]' (123b)
The full contents of the message headers:
{'lang': 'py', 'task': 'jobs.tasks.send_data', 'id': 'b301e3bc-9ab9-48f6-b4c9-3158e1437a85', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'group_index': None, 'retries': 0, 'timelimit': [None, None], 'root_id': 'b301e3bc-9ab9-48f6-b4c9-3158e1437a85', 'parent_id': None, 'argsrepr': "('tenant', 'account', 'service_point', 'device')", 'kwargsrepr': '{}', 'origin': '[email protected]', 'ignore_result': False, 'replaced_task_nesting': 0, 'stamped_headers': None, 'stamps': {}}
The delivery info for this task is:
{'exchange': '', 'routing_key': 'celery'}
Traceback (most recent call last):
File "/Users/froi/Library/Caches/pypoetry/virtualenvs/data-integrations-iehcu-zB-py3.11/lib/python3.11/site-packages/celery/worker/consumer/consumer.py", line 659, in on_task_received
strategy = strategies[type_]
~~~~~~~~~~^^^^^^^
KeyError: 'jobs.tasks.send_data'
Thus the moral of this story.
Starting a worker is simple
celery -A workers worker -l INFO
The -A or –app is used to specify the Celery application instance to use. What I didn’t remember was that this follows a module.path:attribute pattern. I also didn’t remember the defaults it follows.
I was starting my workers with
celery -A jobs worker -l INFO
This meant that Celery will look for the configured application by
celery -A jobs:app worker -l INFOcelery -A jobs.celery:app worker -l INFOSince didn’t declare any of my resources in this way I needed to start my worker with
celery -A jobs.tasks:celery_app worker -l INFO
Once I finally understood this again, like magic, my code worked. Hope this helps somebody not have to scream at their monitor.
]]>Utilizando Telescope, busca el texto que se quiere cambiar, en este ejemplo voy a buscar buen:
Cuando obtengas el listado de la busqueda en Telescope, abre el “quickfix list” utilizando C-Q (combinación por defecto):
Ahora utilizando el comando cdo junto a update se puede cambiar todas las instancias a la vez y resguardar los cambios
:cdo s/texto_para_cambiar/texto_nuevo/ | update
Si no quieres resguardar los archivos automaticamente, elimina el comando de update
:cdo s/texto_para_cambiar/texto_nuevo/
Con esto una funcionalidad que me faltaba de editores como VS Code esta cubierta.
]]>Esta serie de posts van a ser tipo dev log para ir documentando lo que hago e ir creando costumbre.
La pregunta entonces es ¿Qué quiero?.
Con estos criterios y el hecho que estoy tirándome a aprender Go, decidí usa Hugo.
Ahora el tema de portabilidad y costo. Por ahora estoy entre Digital Ocean y GitHub Pages. Estoy moviendo mucho de lo que hago de otros clouds a Digital Ocean, incluyendo manejo del DNS de froi.dev y una instancia de Beluga1, esto lo hace conveniente. GitHub Pages es la opción más sencilla, el contenido ya va a estar en un repositorio en GitHub, publicar aquí dejaría todo en un solo lugar.
Probaré con ambos y veré cual me gusta más, pero comenzaré con GitHub Pages ya que es algo que conozco más. Para esta prueba usare gh-tmp.froi.dev para no romper lo que ya esta corriendo.
Como muchos, yo tengo mis opiniones sobre todo esto, pero lo que realmente me volvió a traer a la mente fue “yo debo de controlar más donde vive mi contenido y que contenido consumo”.
Este blog vive en la plataforma Ghost. Aunque es un servicio excelente, quiero moverme a algo mas sencillo, algo que yo controle, algo más portable.
Lo que quiero es una serie de archivos de texto que se puedan leer por el internet.
Estaré moviendo todo este contenido a un hogar nuevo y a comenzar a utilizar Hugo como generador del contenido. Quiero además expandir froi.dev a ser algo mas que un blog. Estaré cambiando el formato, la estructura y el diseño a algo mas sencillo.
Las próximas entradas serán sobre el proceso y la experiencia.
]]>Cada vez que intentaba instalar estos paquetes me encontraba con un el siguiente error de compilación
error: no member named 'nullptr_t' in the global namespace
Presiona aquí si quieres ver el log en su totalidad.
Esto solo sucedía utilizando MacOS, que en mi caso estaba en version Ventura 13.3.1.
Después de una buena búsqueda y lectura de issues en GitHub, encontré que el problema estaba con la version del SKD de MacOS y clang.
Aparenta que en un cambio de versiones de varias librerías fueron movidas o eliminadas. Esto aparenta no ser el caso en versiones de Debian o Ubuntu Linux ya que la misma compilación funcionaba al correrla en un contenedor de Docker.
Las versiones que estaban causando problemas para mi fueron
La solución esta en actualizar Xcode a la versión mas reciente, version 14.3 (14E222b) al escribir este post. Esta actualización a la vez actualiza la version de Clang a Apple clang version 14.0.3 (clang-1403.0.22.14.1).
Espero que esto ayude a alguien que este buscando solución en vano.
]]>Here’s my attempt in keeping a list of resources, many of which are Python focused … at least for now.
By far my favorite medium to learn. Over the years I’ve gravitated more towards books about the craft of software engineering over books on a specific technology. That said, I’ve been very happy with the O’Reilly learning platform, what used to be Safari Books Online. I’ve used this platform to follow learning path on specific technologies like Go, Kubernetes, and data engineering.
There are a ton of excellent websites with a universe of content. These are just a few that I find helpful and enjoyable.
After books, this is my favorite way to consume tech topics and news. There’s way to many excellent podcasts to mention here, but these are my recent go to list
While YouTube content can be all over the place I find these to have great content and I consistently come back to them
There are many learning platforms out there. While many are excellent I keep going back to and enjoying O’Reilly.com. This platform is what used to be Safari Books Online. They’ve expanded from just offering a book subscription to providing learning paths that take from their extensive catalog of books, videos, courses, and talks. I’ve found that the subscription, while not the cheapest, is worth the value I get from it.
And there we are. There are definitely some excellent resources that I’m missing with this list. This is not meant to be an extensive list but a good starting point for software developers that are starting their career or are looking for resources to enhance their journey in this craft.
]]>
A mucho les encanta gritar “practicamos Agile developmenten” y se adhieren a los rituales diversos rituales para asegurarse que así sea. Sin embargo sprint tras sprint, milestone tras milestone, volvemos a dialogar de los mismo problemas que teníamos con otras metodologías,scope creep, requerimientos no documentados, expectativas que cambian, entre otros. Además, seguimos con la misma falta de documentación.
En los pasados meses, mi equipo se ha dado la tarea de escribir engineering specs para enfocar la conversación en lo que conocemos y lo que no sobre un problema. Me gustaría compartir lo que he aprendido sobre la practica.
Una búsqueda rápida por el internet les darán un sinnúmero de excelente artículos enumerando los beneficios de escribir un engineering spec (ver enlances al final del articulo). Por esto, prefiero entrar en las lecciones que he aprendido en los pasados meses de estar escribiendo estos documentos con mucha frecuencia.
Escribir este tipo de documento puede intimidar. Mucho tiempo se puede ir pensando cómo mejor estructurarlo, que partes incluir y que es importante. La creación de un template es de infinita ayuda para reducir estas incertidumbres y ayudar a concentrar en el contenido.
Pueden ver el template que estoy utilizando. Una gran parte viene del articulo A practical guide to writing technical specs por Zara Cooper. Les recomiendo que vean el Markdown crudo ya que tiene comentarios dando una breve explicación de cada sección.
La función de la plantilla es ayudarte a escribir. Esta perfectamente bien remover secciones que no hacen falta o añadir secciones que te ayuden a escribir un mejor spec.
Un buen ejemplo son las secciones de prior art y current solution en el template que compartí. Proyectos nuevos pueden no tener estos ejemplos o la necesidad de mencionarlos. Es mejor tener un documento que su estructura demuestre finalidad que tener a un lector preguntarse si esta incompleto.
Durante los pasados meses mi equipo se ha dado la tarea de validar que nuestro template realmente es útil para nosotros. Iteramos sobre él, lo compartimos con el resto de la organización de ingeniería y pedimos retroalimentación. Esto a creado una aceptación del mismo y otros equipo lo han adoptado para sus necesidades.
Esto es más importante de lo que uno se imagina.
Un propósito de un engineering spec es de proponer soluciones a un problema y de retar asunciones que podamos tener de dichas soluciones. Encuentro que el tener un documento escrito que exponga estas asunciones ayuda en la construcción de prototipos que puedan sostener o desaprobar las mismas.
Una vez el spec esta aceptado también sirve de documentación durante las etapas de planificación y desarrollo. Esto ayuda a mantener todo dentro del alcance (scope) del proyecto y a evitar scope creep
De todas las lecciones creo que esta fue las más obvia que no vimos hasta después de escribir varios specs.
Es de suma importancia que mantengan el proceso de escribir un spec activo. Estos documentos pueden volverse complicados y extensos. Existe el potencial de dejarlos sin terminar para atender otros asuntos de “mayor importancia”. Esto puede paralizar el proceso y llevar al equipo a brincar directamente a una etapa de implementación.
El mantener un limite de tiempo no solo ayuda a imponer un termino para completar el documento, sino que puede ayudar a identificar si el scope del problema es muy extenso. Esto presenta una excelente oportunidad para revaluar el problema y quizás dividirlo en tamaños más manejable.
Escribir un spec conlleva tiempo y esfuerzo. Se debería considerar igual de importante que la implementación de código. Incluye esta tarea como cualquier otra en tu sesiones de planificación, ya sea agile, scrum, sprints, no importa. El trabajo se debería representar correctamente y ayuda al equipo ir aprendiendo cuánto realmente toma definir, investigar y escribir un spec.
Mi equipo esta incluyendo estos documentos como parte de los spikes en nuestro sprint. Nos ayuda a mantener el proceso del spec corriendo, nos permite comunicar a las otras partes de la organización donde estamos con entregables y nos da un artefacto de entrega al final del sprint que nos sirve para demos.
Un spec realmente no esta terminado del todo. Durante el proceso de desarrollo los requerimientos pueden cambiar, el equipo aprende más sobre el tema o se prueba que la solución no es la correcta. Tu spec debería reflejar esto.
La actualización de un spec deberían formar parte de tu proceso de desarrollo, tal como actualizas la documentación del proyecto. Esto puede ser parte de las tareas del desarrollador al someter cambios al código, de un desarrollador senior o un tech lead, hasta de un product owner.
Para ayudarnos, mi equipo incluye preguntas en nuestro pull request template donde el desarrollador puede indicar si hace falta algún cambio en documentación.
Esto no resuelve el problema del todo, pero sí nos mantiene pensando en estas tareas.
El valor de crear especificaciones técnicas es bien alto tanto para el desarrollador como para su equipo y organización. Escribir estos documentos nos permite pensar sobre soluciones alejados de los detalles de implementación, abre las puertas a colaboración de otros equipos y personas en tu equipo y puede ahorrar tiempo de implementación. Dicho todo esto, esto no es una solución mágica para crear buen software, sino parte del proceso.
Toma el tiempo para evaluar si esta practica funciona para tus proyectos y equipos. Como toda disciplina toma tiempo sentirse cómod@ en su practica. Existen varios artículos que te pueden ayudar a comenzar. Estos son algunos que me ayudaron a mí:
Gracias por leer y nos vemos en la próxima.
]]>El SEC es una agencia independiente del gobierno federal de los EEUU que se encarga de regular y esforzar las leyes contra la manipulación de los mercados. La misma fue creado como una respuesta al colapso de los mercados de Wall Street en el 1929, que llevo a la Gran Depresión de la década de 1930.
Para lograr su mandato el SEC esfuerza requerimientos a compañías publicas y reguladas de radicar informes trimestrales, anuales y otros periodos durante el año. Estos reportes con cruciales para inversionistas, analistas de mercado y el publico en general.
Para hacer esta información accesible de una manera equitativa para todos, el SEC mantiene un sistema llamado EDGAR (the Electronic Data Gathering, Analysis, and Retrieval system). El mismo funciona como un sistema de búsqueda e inventario para los informes suministrados por compañías. La búsqueda es una típica que uno puede encontrar alrededor del internet.
Muchos de nosotros esperaríamos que los esfuerzos del SEC se queden ahi, una búsqueda y que todos nosotros nos resolvamos con eso. Sin embargo, el SEC a construido recursos para desarrolladores.
Para entender esto tenemos que entender como se utiliza esta data. Las declaraciones financieras de estas “public companies” (empresas de capital abierto) son utilizadas por inversionistas para evaluar estas compañías y planificar sus inversiones. Muchos inversionistas dependen de servicios que toman estos informes y los convierten en data accionable. De estos servicios quizás el mas famoso es el Bloomberg terminal. Estos servicios son esenciales para inversionistas.
Tradicionalmente, la distribución de esto informes no era muy accesible. Aunque siempre estaban en el dominio publico, su acceso no era programática. Es esto lo que hace los recursos para desarrolladores del SEC un avance grande. El acceso programático que es posible con su API crea oportunidades para que desarrolladores y compañías creen servicios competitivos con los establecidos. También les permiten a los inversionistas que tengan mayor conocimiento técnico a construir sus propias herramientas. Esto abre muchas posibilidades.
Esto no solo ayuda a los inversionistas. Esta data también es utilizada por reporteros, entidades fiscalizadoras y el propio gobiernos. Abrir esta data de esta manera crea oportunidades a estos a poder hacer su trabajo de una manera mas eficiente, tanto en costo como en tiempo.
Tener esta data es solo una parte de la ecuación. Al final del día lo más importante es como la utilizamos y que podemos aprender de ella. Hable con Axel Rivera, que ademas de ser unos de los mejores iOS developers que he conocido, lleva años dedicando su tiempo libre a entender los mercados. Dos usos claves para él son el poder ver como las compras y ventas de “fund managers” como Warren Buffet y machine learning (es).
Como mucho en la vida, el tener ejemplos a emular ayuda cuando se comienza en un campo o practica. El poder ver esta data permite poder emular las practicas que estos profesionales de inversion ejecutan, así ayudándote a comprender mercados y planificar tus propias compras y ventas.
Machine learning (ML) es un tema extremadamente abarcador y al igual que sus usos. Esta data podría ser utilizada para crear modelos que nos ayude entender patrones económicos y pronosticar eventos. También podría abrir oportunidades de desarrollo económico, fiscalización y proyecciones de mercados.
De seguro habra otros usos e ideas al tener esta data disponible. Data no es necesariamente buena o mala y su uso esta en nuestras manos. Dicho esto el acceso a la misma es de suma importancia. Tener entidades en nuestro gobierno abriendo este acceso nos puede ayudar a no solo fiscalizarlo, pero también crear oportunidades para nuestro crecimiento.
Sí les interesa el tema del uso de data abierta y de gobierno para impacto social y oportunidades económicas, denle un vistazo a The Opportunity Project de la Oficina del Censo de los EEUU.
Gracias a Axel Rivera por la edición y apuntarme en la dirección correcta.
Gracias por la lectura ❤️
]]>This was originally posted on April 21, 2018 on Medium.
What really is a “senior developer”? How does one get this honorific? Is it based on years? Projects worked on? Knowledge? Dumb luck? Achievement?

What am I?
I’m going to go out on limb and say that you can only really get to call yourself a “senior” developer when you mentor another. When you impart your knowledge for the benefit of another in a way that is understandable and useful. Now this doesn’t mean hand holding, although it could. Sometimes being a mentor is imparting harsh truths. Until you do that you’re just a developer.
To clarify my “just a developer” isn’t meant to be derogatory. You can “just be a developer” and be amazing. You could have incredible knowledge and build wonders the world has never seen. You just aren’t a senior developer in my eyes. The same way you can’t call yourself a teacher or professor until you teach.
So what, you might ask? Why should we even care?
Mentorship is the bedrock from where professions are constructed. The more people we have the better the whole is, the more ideas we can consume, we are just better for it.
My professional software developer career spans 13 years. I’ve been a tech lead, team lead, a senior developer, a junior developer, just a developer. Other descriptions that have been given to me include the guy that broke the build, the guy that deleted the database, and other very colorful but deserved ones. Out of all of these I never really thought I deserved the “senior” label. It just never felt right, like I didn’t deserve it.
That started to change one day though. The catalyst? I explained how functions work to a kid who wanted to learn.
I believe I learned more here that what I could have explained. Now that in and of itself is not the big deal. What really hit me was that I did so without a script. It wasn’t that I prepared an intro or had slides. I just had a small whiteboard and somebody that looked to me to explain what something was.
The look on his face as he went from “huh?” to “ooohhhh!” was incredibly satisfying. He then went on to explain to me how he would do some basic math exercises using the little Python I taught him. I knew at that point that helping people was the only way that a community or a profession could sustain itself. His uncle, who was himself a developer finishing up his studies at the University of Puerto Rico, told me he later got “a thousand” questions from his nephew and that he continued to be interested in development.
That simple experience helped me realize that to earn the “senior honorific”, I had to help others as much as I could. I started volunteering at workshops, Startup Weekends, created meetups, and invited other colleagues to do the same. I started to get other people asking for advice about not only their code but their professional career. Questions like “what technologies should I learn”, “is there a better way to do this”, “how should I build one thing or another”. Then one day it happened, somebody introduced me as one of their mentors. I was instantly in a “position of authority” in the best possible way. I felt I could now help developers that were starting their careers. Give back the help that I got when I started.
Nobody does anything by themselves. Somewhere in your life there’s somebody that took the time to help you, even if it was an uncomfortable conversation. If you really want to feel like you have gotten to a “senior” level in your career I invite you to take some time and mentor somebody that needs it. It doesn’t have to be much, it doesn’t have to mean hand holding, just help until you can’t anymore. I’m certain that both of you will be better for it.
]]>Los video juegos han sido una constante en mi vida. Desde el Atari 2600 al PlayStation 4 que tengo ahora siempre he tenido alguna consola en mi casa. Durante este tiempo la industria de los video juegos a crecido a una de alcance mundial con ingresos que superan a los de las industrias de cine y música combinadas . Este crecimiento también a cambiado la demografía que consume estos juegos. La audiencia se ha expandido con los dispositivos móviles y la creación de juegos como Angry Birds, Candy Crunch y el porte de Fortnite.
Más interesante aun es el cambio en la relación de los estudios y casas publicadoras con los jugadores y las comunidades que crean. Las redes sociales han creado la oportunidad de un dialogo directo entre las comunidades de estos juegos y los desarrolladores. La apertura de APIs (interfaces aplicativas que permiten la interacción con un servicio) por algunas compañías han llevado esta relación a un nivel más aya que meramente uno de consumo. Este es el aspecto en el que me quiero enfocar con el juego Destiny 2 y la compañía que lo desarrolla, Bungie.
Durante el 2020 me encontré pasando mucho tiempo con este juego. Destiny 2 es un first person shooter, massive multiplayer online role playing game. Esto lo que significa es que como jugador uno comparte este mundo digital simultáneamente con jugadores de alrededor del mundo. Crear este tipo de mundo requiere un esfuerzo continuo que incluye actualizaciones constantes. El mantener a la comunidad de jugadores interesados y activos requiere un ciclo constante de dialogo e iteración. El objetivo es que estas comunidades se sientan parte del proceso y que se sientan dueñas del mundo. Para la compañía esto representa una audiencia cautiva con la cual devenga sus ingresos. Una excelente manera de lograr esto es de permitir acceso al juego y su plataforma mediante APIs. Esto es precisamente lo que Bungie ha hecho.
Como mencione, este año pasado le he dedicado mucho tiempo a este juego, y como todo, me he topado con elementos que se convierten en labores tediosa mientras más interactúas con ellas. La decisión de Bungie de abrir su API a permitido que la comunidad desarrolle herramientas que alivian y hasta mejoran la experiencia creada por Bungie. Un ejemplo de una de estas aplicaciones hechas por la comunidad lo es el Destiny Item Manager. Con esta herramienta jugadores pueden manejar el uso de sus recursos en el juego afuera del mismo con cualquier dispositivo. Por consiguiente, mi tiempo dentro del juego ha sido mejor utilizado para los eventos y el entretenimiento que busco. Suena gracioso pero me ha hecho más “productivo”.

Documentación para el API de Bungie en https://bungie-net.github.io/
Bungie creó y abrió su plataforma para sus usuarios y comunidades. No solo esta disponible al publico en GitHub, pero también dedican recursos para atender preguntas de la comunidad. No solo es algo que publican porque pueden, sino es una parte integral de su producto. Con esto creo una plataforma de innovación y creación para sus jugadores.
Llevemos este pensar a nuestras interacciones con nuestro gobierno, sus agencia y las tareas que realizamos con ellas. En esta narrativa Bungie no es distinto a un gobierno. Al igual que un gobierno no es común que la comunidad de usuarios, en este caso la ciudadanía, pueda crear o aportar a la experiencia de usuario con un servicio. La mayoría de los constituyentes somos consumidores. No tenemos el acceso para crear herramientas o interacciones que los publicadores (el gob. y sus contratista) no hayan pensado. Esto, en mi opinión, alimenta las frustraciones y lleva a una relación antagónica.
Imaginemos entonces que aprendamos de los ejemplos de compañías publicadoras de video juegos como Bungie. Que nuestros gobiernos y sus agencias se transformen en proveedores de servicios y plataformas. Donde los servicios y paginas oficiales ofrezcan un API abierto y accesible, con el que las comunidades de civic-tech puedan aumentar los servicios existentes con productos complementarios. Imaginen el potencial de tener un API que exponga los procesos legislativos que sea abierto y que la comunidad pueda utilizarlo para crear servicios para explicar las medidas en un lenguaje accesible.
Imaginen que podamos crear servicios que mantengan a la ciudadanía invertida en los procesos que mantiene a nuestra sociedad corriendo. Donde la apatía se convierta en retroalimentación, donde la falta de acceso se convierta en esfuerzos comunitarios para mejorar nuestras comunidades.
Existen ejemplos claros tanto en la industria privada, como en gobiernos de alrededor del mundo. Esto, aunque en concepto es sencillo, no es fácil. Conlleva cambios en contratación, cultura y visión. No obstante, estos cambios pueden lograrse con incrementos pequeños. En futuras publicaciones adentrare en ideas y ejemplos que puedo ver desde afuera del gobierno y basados en mi experiencia desde adentro del mismo.
Si les interesa esta conversación acompáñenme en los hack nights de Code for Puerto Rico, subscribiese a este blog o contáctenme directamente. Juntos podemos traer ideas para mejorar nuestro país y nuestras comunidades.
]]>78 municipios. Estos son los gobiernos que mas afectan el día a día a la ciudadanía. Son la primera parada para ayudas durante desastres, emergencias de salud y festividades locales. Los servicios que ofrecen los municipios son vitales, desde el recogido de escombros, hasta el manejo de seguridad.
Con tanta importancia que estas instituciones tienen como es que se comunican con los ciudadanos?
En el 2020 y después de mucho intentos de modernización, uno se esperaría que la presencia digital de los municipios este, en lo mínimo, organizada. Que como ciudadano, uno pueda encontrar un lugar donde se pueda acceder información de importancia del lugar en donde se vive. Una pagina de internet, con una dirección fácil de acordarse y la información relevante es lo mas básico que un municipio necesita para crear esta confianza a sus ciudadanos.
En el mundo del internet esto se puede lograr de varias maneras. Para entidades de gobierno en EEUU y sus territorios se puede utilizar el sufijo .gov para indicar que es oficial. En el caso de Puerto Rico se puede ver este intento con pr.gov.
Confianza, es así de sencillo.
El internet es una plataforma donde cualquiera puede comprar un dominio que este disponible y apuntarlo a una pagina. Los sufijos como .com, .org, .net, entre otros, nos permiten tener un pedacito del internet para nuestras compañías, organización no gubernamentales y cualquier otro propósito que queramos. Existen sufijos que están controlados por entidades y que velan su uso. El .gov es uno de estos sufijos. Este sufijo esta controlado por el gobierno federal de los EEUU y solo se le da acceso entidades gubernamentales dentro del territorio del mismo. Gracias a esto uno puede estar seguro que pr.gov es el portal oficial del gobierno de Puerto Rico y no https://www.pr.com/.
Con todo lo que ha pasado en los pasados años en Puerto Rico, en Code4PR queríamos ver cuál era la huella digital de los municipios. Queríamos ver cuan fácil se nos podia hacer encontrar información relevante de un municipio que pudiese asistir a sus constituyentes.
Se nos ocurrió comenzar por el portal de pr.gov. Decidimos esto por varias razones:
Los resultados no fueron los mas alentadores,lo que se encontró fue un sin numero de data sin actualizar desde el 2017 y otra simplemente errónea.
Nos dimos la tarea de analizar qué exactamente estaba mal en el directorio. Pueden ver los resultados aquí.
Lo que encontramos se puede agrupar en lo siguiente:
Para este análisis estamos definiendo falta de información como:
Recursos digitales de un municipio que no están incluidos en la entrada del municipio en el directorio de pr.gov.
En el documento adjunto se pueden contar alrededor de 29 dominios que no aparecen en pr.gov. Hay algunos de estos 29 que son dominios que ya no son validos. Esto se puede deber a que no los renovaron o simplemente ya no están en uso.
¿Qué es peor que no tener data? Tener data errónea.
Existen entradas en pr.gov que están erróneas. Lo que vimos se puede agrupar en:
Para que el directorio de municipios sea util para ciudadanos buscando ayuda esto se tiene que arreglar.
Encontramos un numero de paginas municipales que aparentan estar abandonadas. Alguna paginas parecían que no se actualizaban con información relevante. Otras se encontraban en un estado perpetuo de construcción. Al final del día, y totalmente nuestra opinion, el ciudadano no podia depender de estas herramientas para obtener información de su municipio.
Esto no se debe de confundir con dominios que hayan caducado. Esto es otro problema del cual hablaremos.
¿Por qué es importante esto?
Volvemos al tema principal, confianza ciudadana.
Cuando uno entra a un edificio que esta bien mantenido, limpio y ordenado, uno se siente bien. Es un sentimiento de “aquí las cosas están bien”. El edificio no tiene qué ser super moderno, aunque eso también ayuda, solo bien cuidado. Una pagina de internet es igual. Para una marca, entidad o comunidad su pagina de internet es su casa, su tarjeta de presentación. Esto debe de ser igual para entidades de gobierno, sin importar en qué rama se encuentra.
¿Perdida de dominios? En pocas palabras, el municipio dejo caducar el dominio. Los dominios en el internet se pagan por un periodo de tiempo. Se puede comparar con un alquiler de una propiedad que se paga anualmente. Este “alquiler” puede hacerse por periodos mas extensos que un año, por ejemplo se puede pagar por el uso del dominio por un periodo diez años. Al final de este periodo, el que sea, se tiene que volver a pagar por su uso.
Al final del día no le vemos problema dejar caducar un dominio que el municipio no vaya a utilizar o si no tiene el presupuesto para mantenerlo. De pasar esto el municipio debe de tener un proceso para alejarse del dominio y de actualizar la información en pr.gov para dejar claro que ya no lo esta utilizando. El no hacer esto abre el camino para el uso nefasto del mismo y la perdida de confianza del ciudadano.
Una vez el dominio se pueda comprar por cualquiera cabe la posibilidad que se pueda usar para acciones nefastas. Esto combinado con el municipio no removiendo el dominio de paginas oficiales puede causar situaciones de disgustos, en el mejor de los casos, o peligro genuino y desinformación en el peor.
Servicios como Facebook y Twitter nos ha permitido llegar a una audiencia enorme de una manera inmediata. Para muchas personas estos servicios son el internet, es su interface a información y comunidad. Estas son herramientas que municipios pueden utilizar como su propiedad principal o de manera suplemental a sus propiedades digitales existentes.
¿Dónde esta el problema entonces?
El problema esta en el tipo de uso y el mantenimiento del mismo. Encontramos varios municipios que una pagina o grupo de Facebook era su única propiedad digital y estaba abandonada. En ocaciones se nos hacia un poco difícil saber si el grupo o pagina era una oficial del municipio.
Al igual que los dominios en el internet, cualquiera puede crear una pagina de Facebook con el nombre de un municipio. Los municipios tienen que darle seguridad a sus ciudadanos que la información que están viendo es real y qué viene del municipio.
Sin importar la situación, el municipio debe de tener una estrategia digital unificadora para el manejo y mantenimiento de todas sus propiedades digitales. ¿Qué debería ser esa estrategia? Esa contestación solo la puede suplir el municipio.
Para nosotros lo principal es mantener la información de los municipios actualizada. Los municipios y el gobierno estatal deben de colaborar en esto. Parte de la estrategia del municipio debe ser el mantener su información actualizada pero necesitan las herramientas para hacerlo. Enviar un correo electrónico con información a actualizar no es suficiente. Sin saber cómo funciona pr.gov, pensamos que lo idóneo sería ofrecer una sección en esta página donde los municipios puedan mantener su información.
Dicho esto, la realidad es que los presupuestos y recursos disponibles para los municipios pueden ser bien limitados. Con esto en mente intentamos crear un listado de sugerencias que se pueden implementar por su cuenta y en etapas.
Primordialmente necesitan una estrategia digital. La misma puede incluir:
Esta es una excelente oportunidad para que el gobierno estatal, utilizando a PRITS, tenga un rol de liderazgo y trabaje una estrategia digital para Puerto Rico.
El mantener las propiedades digitales de entidades de gobierno es altamente importante. Debería considerarse parte de los servicios esenciales que se le ofrece al ciudadano.
Los municipios necesitan tener una estrategia para mantener sus propiedades digitales con información actualizada y correcta. Esto crea confianza y mantiene al ciudadano informado en su día a día y en momentos de emergencia.
Para que esto sea eficiente el gobierno estatal necesita ofrecer herramientas para mantener la información en sus directorios al día. Estas herramientas y procesos de mantenimiento de data necesitan ser accesibles y fáciles de utilizar.
Al final del día la meta debe de ser mantener al ciudadano informado y combatir la desinformación. Con cambios pequeños estamos seguros que esto se puede lograr para el beneficio de todos.
]]>