<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Noghartt&apos;s garden</title><description>A place where I put all my thoughts</description><link>https://noghartt.dev/</link><item><title>2025 in Review</title><link>https://noghartt.dev/blog/2025-in-review/</link><guid isPermaLink="true">https://noghartt.dev/blog/2025-in-review/</guid><pubDate>Tue, 30 Dec 2025 14:08:29 GMT</pubDate><content:encoded>&lt;p&gt;Here we go, following the tradition once again. Here I am again, writing my yearly
review. As I said in the &lt;a href=&quot;./2024-12-30T23:58:32.012Z-2024-in-review.md&quot;&gt;2024 in Review&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The next year, for me, will be a year of consistency, reconstruction, maintenance
and improvement.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’d say that if I were writing this today, I’d need to rewrite it as: &lt;em&gt;“The next year,
for me, will be a year of discovering, understanding, and frustration.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This year had some unexpected turns, and it was very different from previous years.
I didn’t do well in some parts of my life that I consider important, but on the other
hand, I had new opportunities and lived more this year, with more travel and more
experiences.&lt;/p&gt;
&lt;p&gt;And also, as a tradition once again, this year I definitely do have things that I
need to improve.&lt;/p&gt;
&lt;h2&gt;On health&lt;/h2&gt;
&lt;p&gt;On the health side, it was a year of ups and downs. On the one hand, I started taking
a bit more control of my health: starting my ADHD treatment, fixing some issues with
my body, and going to the doctor to solve them (something I had procrastinated on a
lot).&lt;/p&gt;
&lt;p&gt;In 2025, I was a bit more consistent with some aspects of my health: going to the
gym turned out to be a fun thing to do. I started loving working out. It was the
time of the day when I could just drop any thought and start focusing only on pushing
(or pulling) weights. Something I noticed is that working out really helped keep my
anxiety levels more stable. I still have some issues with anxiety, but it’s more
moderate now.&lt;/p&gt;
&lt;p&gt;Another thing I would like to be more consistent with during the year, and which
will be one of my health focuses for next year, is climbing. It was an insanely good
hobby I discovered. Although bouldering is a bit frustrating sometimes, the feeling
of accomplishment when you finish a project is really good. I want to have at least
one climbing session per week, lasting 2–3 hours, mostly bouldering.&lt;/p&gt;
&lt;p&gt;But there are some things that didn’t go as well as I expected. Specifically, my
sleep: I believe I could be more consistent. Based on my Oura Ring data, I had some
discoveries and insights around my sleep that will help me better optimize the way
I sleep.&lt;/p&gt;
&lt;p&gt;One of the core insights I had about sleep was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Having 210 mcg of melatonin 2 hours before bed helps me a lot with having better,
more consistent sleep (especially REM and deep sleep).&lt;/li&gt;
&lt;li&gt;Loud noises have a big impact on my sleep quality. I bought earplugs, and they
were one of the best purchases I made to improve my sleep.&lt;/li&gt;
&lt;li&gt;Bedroom temperature. Living in Brazil is really hard, especially during the
summer, since it gets very hot. Having ways to better control room temperature
is a great investment for sleep quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something I noticed from my sleep-quality rollercoaster is that on days when I don’t
sleep well, my mind becomes completely numb, I’m angrier, and more anxious. How do I
know this? Because this year I had a lot of days with poor sleep.&lt;/p&gt;
&lt;p&gt;That will be one of my main focuses for next year: being more consistent with my
sleep. From my point of view, sleep is the fundamental thing that creates momentum
for everything else. If I’m not doing well with sleep, as a side effect, everything
else also suffers. As a note for next year’s review, the first thing I need to fix
is solving my sleep anxiety. I don’t struggle with sleep itself, but I struggle to
go to bed.&lt;/p&gt;
&lt;p&gt;The last thing I want to mention here is that I started meditating. It isn’t a habit
yet, but it’s something I’m working on. I believe that making meditation one of my
core improvements in 2026 will bring a lot of fulfillment.&lt;/p&gt;
&lt;h2&gt;On reading&lt;/h2&gt;
&lt;p&gt;This year was kind of disappointing for my reading habits. I set a goal of reading
at least 12 books by the end of the year, and I finished a total of ZERO books.&lt;/p&gt;
&lt;p&gt;I started a lot of new books or continued some older ones, but my reading consistency
dropped to its lowest level in the last five years. For most of the year, I was
reading &lt;em&gt;Gödel, Escher, Bach&lt;/em&gt;, but it was harder than expected, since I had to read
and reread many pages to clearly understand what the author was trying to say.&lt;/p&gt;
&lt;p&gt;I’m not good at managing multiple books in parallel; it’s really hard for me to be
consistent when reading several books at the same time. I also read parts of other
books, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Origins of Efficiency&lt;/li&gt;
&lt;li&gt;Structure and Interpretation of Computer Programs&lt;/li&gt;
&lt;li&gt;Nicomachean Ethics&lt;/li&gt;
&lt;li&gt;Database Design and Implementation&lt;/li&gt;
&lt;li&gt;The Elements of Computing Systems&lt;/li&gt;
&lt;li&gt;The Mind Illuminated&lt;/li&gt;
&lt;li&gt;Crafting Interpreters&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those are the other books currently in my reading queue for next year.&lt;/p&gt;
&lt;h3&gt;Blog posts and bookmarks&lt;/h3&gt;
&lt;p&gt;On the other hand, I read a lot of blog posts this year. You can check all of them
in &lt;a href=&quot;/bookmarks&quot;&gt;my bookmarks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wrote a small script to extract metrics from my bookmarks for this year, and I’ll
share some insights below.&lt;/p&gt;
&lt;p&gt;All bookmarks from 2025, grouped by month:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/bookmarks-monthly-2025.png&quot; alt=&quot;Bar chart showing my bookmarks grouped by month&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My most active month was &lt;strong&gt;December&lt;/strong&gt;, with 193 bookmarks. To be honest, I think this
is mostly related to a habit I developed of tagging everything as &lt;code&gt;#for-later&lt;/code&gt;
before actually reading it. This is also reflected in the next metrics.&lt;/p&gt;
&lt;p&gt;Here’s a heatmap of my bookmarks in a GitHub-like view, which gives a clearer picture
of how my bookmarking behavior is distributed:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/bookmarks-heatmap-2025.png&quot; alt=&quot;Heatmap of my bookmarks in 2025&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And the last useful metric shows the number of bookmarks per tag:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/bookmarks-top-tags-2025.png&quot; alt=&quot;Line chart of my bookmarks per tag&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As mentioned above, there’s some deviation due to the &lt;code&gt;#for-later&lt;/code&gt; habit. Ignoring
that tag, the most used ones are &lt;code&gt;#cs&lt;/code&gt; and its subtags, with a total of 343 bookmarks
this year.&lt;/p&gt;
&lt;h2&gt;On career and work&lt;/h2&gt;
&lt;p&gt;This year was more like a year of consistent focus on my work itself. I had the
opportunity to work on many different projects at my job, which gave me valuable
insights into handling systems used by more than a million users.&lt;/p&gt;
&lt;p&gt;Projects like building a durable workflow engine to manage long-running tasks for
LLM agents, or setting up simulations and benchmarks to maintain output quality,
are good examples of what I worked on.&lt;/p&gt;
&lt;p&gt;For next year, there are a lot of exciting things coming, and I’ll be involved in
many of them.&lt;/p&gt;
&lt;p&gt;Regarding my broader career, I’m still struggling to manage my side projects. I
have some plans to better structure how I approach their development, so I can
work on them alongside everything else.&lt;/p&gt;
&lt;h2&gt;On life&lt;/h2&gt;
&lt;p&gt;One area where I achieved a lot this year was life in general. I reached milestones
that my younger self wouldn’t believe were possible.&lt;/p&gt;
&lt;h3&gt;Europe trip&lt;/h3&gt;
&lt;p&gt;This year, I had the opportunity to go on a trip to Europe with my girlfriend and
her family. It was my first international trip, which made it especially meaningful
to me.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/italy-2025-foro-romano.jpeg&quot; alt=&quot;Foro Romano&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I procrastinated a lot on writing a blog post about this trip, but it’s on my list
for next year (I promise).&lt;/p&gt;
&lt;p&gt;Between late June and early August 2025, I traveled between Rome and Madrid, and it
was one of the best experiences I’ve had. I’m not someone who enjoys traveling that
much in general — I’m more of a homebody — but experiencing two different cultures
and so much history was incredible.&lt;/p&gt;
&lt;p&gt;Rome is beautiful. Everything there tells a story, and as a history nerd, I was
amazed by what the city had to offer. Every alley and street revealed something new.
Visiting the Vatican, the Colosseum, and the Roman Forum opens your mind in ways you
can’t fully appreciate without being there. I hope I can visit Rome again someday.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/spain-2025.jpeg&quot; alt=&quot;A street in Madrid&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We also stayed in Madrid for seven days. What a great city — bright and full of life.
We visited the Museo Nacional del Prado, where I saw incredible works by amazing
artists. I also ate some of the best sushi of my life (until now — I suspect Japan
will change that someday).&lt;/p&gt;
&lt;p&gt;Toledo is a city close to Madrid with its own magic. It’s a medieval city that
preserves much of its original structure. Sadly, I wasn’t able to visit the Toledo
Cathedral because the line was too long, and we only had the morning and afternoon
there.&lt;/p&gt;
&lt;p&gt;In the end, I can say that I truly loved this trip. Being there with my girlfriend
gave the whole adventure a special meaning. I really hope to return someday, ideally
with her.&lt;/p&gt;
&lt;h2&gt;Next steps for 2026&lt;/h2&gt;
&lt;p&gt;That was my year in review. Overall, it was a year of ups and downs. I discovered
and learned many things, and I started understanding myself better — especially how
my mind works. Looking back at what I wrote last year:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have a strong feeling that, given my 2024, it will be a better year in all
aspects. I have a lot of plans for the next year and I’ll commit to all of them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’d say that 2025 had many good moments, but also areas where I completely failed
and need to improve next year. In the end, what matters most is identifying those
gaps and setting clear goals for the year ahead.&lt;/p&gt;
&lt;p&gt;One thing I want to change is how much I read blog posts. I don’t want to consume
them at the same volume as this year. Why? Because much of it was driven by FOMO,
not by genuine interest. I can clearly identify which articles actually changed my
mental models. Going forward, I want better criteria for choosing what I read.&lt;/p&gt;
&lt;p&gt;Along the same lines, I want to revisit old articles and start creating flashcards.
Building a stronger flashcard habit could be very useful, especially since my
memory isn’t always great.&lt;/p&gt;
&lt;p&gt;On the health side, the three things I want to maintain are: improving my sleep
habits and routines, controlling light exposure better, starting a meditation
habit, and continuing with workouts (gym and climbing).&lt;/p&gt;
&lt;p&gt;As I mentioned last year but didn’t accomplish, I want to start tracking specific
life metrics. Measuring what matters gives clarity, and I strongly believe in the
idea that &lt;em&gt;“what gets measured gets improved.”&lt;/em&gt; If I want to commit to habits, I
need to measure them.&lt;/p&gt;
&lt;p&gt;Overall, this was a year of gaining maturity. Even though I didn’t accomplish all
my goals, and life felt chaotic at times, things turned out well. That’s part of
the process of dealing with the chaos we call life.&lt;/p&gt;
&lt;p&gt;If this were me last year, I would have said it was a bad year. But looking back at
the past months, I see real progress. I feel more mature, happier, and more excited
about what’s coming. That’s the mindset I want to carry into next year.&lt;/p&gt;
&lt;p&gt;I also have many plans and ideas for this blog. Writing is one of the things I want
to keep improving.&lt;/p&gt;
&lt;p&gt;Happy New Year, reader! I hope the winds of 2026 bring you success and everything
you seek to achieve your goals!&lt;/p&gt;
</content:encoded></item><item><title>Notes on my Linux system</title><link>https://noghartt.dev/blog/notes-on-my-linux-system/</link><guid isPermaLink="true">https://noghartt.dev/blog/notes-on-my-linux-system/</guid><pubDate>Sun, 14 Dec 2025 14:26:54 GMT</pubDate><content:encoded>&lt;p&gt;Recently, I became again a daily Linux user. Using Arch Linux, btw. I was a macOS
user for about 3 years, which was a good OS by the way, but I missed a lot of features
which was so much easier to do on the new environment, like tiling window managers,
easier workflow setup for autostart programs and a better way to manage my config
using declarativeness.&lt;/p&gt;
&lt;p&gt;This blog post here, we&apos;ll be more about things which was useful for me somehow,
and I need to record to myself for the future, if I want to come back here, in case
of a distrohopping or something else. I hope it can be useful for you too.&lt;/p&gt;
&lt;h2&gt;Autorunning xinit and applying DBUS autostart&lt;/h2&gt;
&lt;p&gt;I&apos;m using X11 (yes, not using Wayland, yet).So I did the most simple setup I could
to start my i3 on a given display. For that, I added on my &lt;code&gt;.zprofile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if [ -z &quot;$DISPLAY&quot; ] &amp;amp;&amp;amp; [ &quot;$XDG_VTNR&quot; = 1 ]; then
  exec startx
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, every time I logged and my shell starts, the &lt;code&gt;.zprofile&lt;/code&gt; will be triggered,
which will run the &lt;code&gt;exec startx&lt;/code&gt;, since both variables conditionals are true.&lt;/p&gt;
&lt;p&gt;And, on my &lt;code&gt;~/.xinitrc&lt;/code&gt;, I had to start the D-Bus manually, which is required to
have some things working, like the PAM/gnome-keyring and the dunst (for libnotify/notification-daemon).&lt;/p&gt;
&lt;p&gt;For that, what I did was:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source /etc/X11/xinit/xinitrc.d/50-systemd-user.sh

exec dbus-launch --sh-syntax --exit-with-session i3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Autostart with Desktop Entries&lt;/h2&gt;
&lt;p&gt;Right now, I&apos;m using the &lt;code&gt;~/.config/autostart&lt;/code&gt; from X11 with desktop entries to handle
the autostart of some of my programs, like Redshift, for example. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Desktop Entry]
Version=1.0
Name=Redshift
_GenericName=Color temperature adjustment
_Comment=Color temperature adjustment tool
Exec=redshift
Icon=redshift
Terminal=false
Type=Application
Categories=Utility;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding this desktop entry, every time you start your X11 workflow, these programs
will be executed. If I want to test it before, I can run this command below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dex --autostart
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Creating Autostart Systemd Services on User Land&lt;/h2&gt;
&lt;p&gt;I do have some docker containers which I&apos;m running on my PC while on autostart.
Kind of self-hosted, while I&apos;m fixing some issues with my homelab. TIL, I can
create a service on user land with systemd on the folder: &lt;code&gt;~/.config/systemd/user&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That was what I did, I&apos;m running &lt;a href=&quot;https://miniflux.app/&quot;&gt;miniflux&lt;/a&gt; when I log in
into my user. That&apos;s the service file as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Miniflux docker compose flow
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/path/to/my/miniflux/folder
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=default.target
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Automatically appending i3 layout + opening programs&lt;/h2&gt;
&lt;p&gt;I&apos;d like to have some programs opening automatically when I log in into my user.
And I&apos;d like to specifically route it to a given workspace + with a specific layout.&lt;/p&gt;
&lt;p&gt;I learned that i3 provides something for that: the &lt;code&gt;i3-save-tree&lt;/code&gt; + &lt;code&gt;append_layout&lt;/code&gt; config.
Then, on my &lt;code&gt;~/.config/i3/config&lt;/code&gt; file, I did this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;assign [class=&quot;obsidian&quot;] workspace 10
assign [class=&quot;Todoist&quot;]  workspace 10
assign [class=&quot;Anki&quot;]     workspace 10

exec --no-startup-id ~/.config/i3/start-ws10.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;m assigning a rule to enforce that all windows with the class being &lt;code&gt;obsidian&lt;/code&gt;,
&lt;code&gt;Todoist&lt;/code&gt; or &lt;code&gt;Anki&lt;/code&gt;, will be routed directly into the workspace 10. After that,
I&apos;ll be running the script for start the programs on that workspace:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
i3-msg &quot;workspace 10; append_layout ~/.config/i3/layouts/saved-tree.json&quot; # that was saved by i3-save-tree
sleep 1
gtk-launch anki
gtk-launch obsidian
gtk-launch todoist

i3-msg &quot;workspace 1&quot;;
i3-msg &quot;exec ghostty&quot;;
i3-msg &quot;exec firefox&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Fixing issues with Realtek 8852AE, my 802.11AX device&lt;/h2&gt;
&lt;p&gt;I had some issues with my Wi-Fi, we&apos;re it sometimes started disconnecting while
I was on a meeting, it was specifically happening while on meetings or video-calls,
so basically looking a bit into Arch Linux forum, I saw that it could be some issue
with an inconsistency with Wi-Fi 7. So what I found is that I could disable the
power save mode on the device and it would work as expected.&lt;/p&gt;
&lt;p&gt;Then, I created a file called &lt;code&gt;/etc/modprobe.d/70-rtw89.conf&lt;/code&gt;, with the following
content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options rtw89_pci disable_aspm_l1=y disable_aspm_l1ss=y
options rtw89pci disable_aspm_l1=y disable_aspm_l1ss=y
options rtw89_core disable_ps_mode=y
options rtw89core disable_ps_mode=y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, I just need to reboot my PC. No more issues with my Wi-Fi networking.&lt;/p&gt;
&lt;h2&gt;On Declarativeness Config&lt;/h2&gt;
&lt;p&gt;Something which isn&apos;t good on my config right now, it&apos;s the way I&apos;m doing the store
of it. I really miss the fact that with Nix specifically, I do have some way to
easily reproduce the same environment, and do not lose mostly of the configurations
of all binaries and stuffs which I do have on my computer, like rofi, i3, my Desktop
Entries, systemd services, etc.&lt;/p&gt;
&lt;p&gt;I&apos;m not happy with the way I&apos;m handling it right now (without Nix), so I&apos;ll be changing
it in the next days or when I stop procrastinating it.&lt;/p&gt;
</content:encoded></item><item><title>On sidenotes implementation</title><link>https://noghartt.dev/blog/on-sidenotes-implementation/</link><guid isPermaLink="true">https://noghartt.dev/blog/on-sidenotes-implementation/</guid><pubDate>Tue, 04 Nov 2025 01:10:45 GMT</pubDate><content:encoded>&lt;p&gt;This week, I finally implemented my sidenotes on this blog. It was a work in progress for about 1 year, from the first attempt at implementation until reaching a decent solution.&lt;/p&gt;
&lt;p&gt;All the implementation was based on a &quot;philosophy&quot; of what I believe is the best way to present a blog to the reader and organize how it can be read. It was mainly inspired by &lt;a href=&quot;https://gwern.net/sidenote&quot;&gt;Sidenotes in Web Design&lt;/a&gt;, by Gwern[^1].&lt;/p&gt;
&lt;p&gt;I think that, specifically for blog posts, sidenotes can be more useful than footnotes/endnotes, which, at least for me, bring a bad user experience, where you need to go back and forth between the anchored sections of your text to have the full context of something that has been written.&lt;/p&gt;
&lt;p&gt;On the other hand, sidenotes help give an easy stream of text with the full context of a given scope, considering that all sidenotes are close to their paragraphs. It&apos;s easier to follow a text with your eye when you have all the sections together, without the overhead of the navigation.&lt;/p&gt;
&lt;h2&gt;Core philosophies&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Focus on being web-friendly.&lt;/strong&gt; As one of the core points of my implementation, I approached it as much as possible, following some web-friendly concepts. What does that mean? Ideally, the entire implementation should be JavaScript-free.&lt;/p&gt;
&lt;p&gt;In my current implementation, sadly, this isn&apos;t 100% true (maybe it never will be), because I had to make some trade-offs to improve the user experience for sidenote usage. But all the core implementation is based on &lt;a href=&quot;https://edwardtufte.github.io/tufte-css/&quot;&gt;Tufte CSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, following it, I added some approaches most inspired by the way Gwern did their sidenotes: anchoring each sidenote. Then you can easily click on any sidenote and use it as the anchor for that page. I really like anchoring.&lt;/p&gt;
&lt;p&gt;And for mobile devices, it shows, close to the text that each sidenote refers to, whether it can be readily displayed or not. Try accessing these on a mobile device and check this behavior. It&apos;s really cool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Avoid introducing new stuff.&lt;/strong&gt; I want to be as compatible as possible with the current footnote implementation in markdown, without adding any new syntax or a different approach to managing text. In the end, this should be just markdown, and I intend to keep it that way going forward, so I wouldn&apos;t like to use MDX, for example.&lt;/p&gt;
&lt;p&gt;With that in mind, I narrowed my options on how to approach it. But the main reason for this decision is to ensure that all my notes can be easily ported between platforms and that I can write them wherever I am. Because, as I said, it&apos;s just a bunch of simple markdown notes.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Specifically, the implementation is split into two parts: the markdown plugins and the styles and UX improvements.&lt;/p&gt;
&lt;p&gt;The markdown plugins are being added to override the expected behavior of the known footnotes approach and replace it with our own sidenotes implementation. They are composed of these two plugins: &lt;a href=&quot;https://github.com/noghartt/blog/blob/main/plugins/remarkPluginSidenotes.ts&quot;&gt;remarkPluginSidenotes.ts&lt;/a&gt; and &lt;a href=&quot;https://github.com/noghartt/blog/blob/main/plugins/rehypePluginSidenotes.ts&quot;&gt;rehypePluginSidenotes.ts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Talking about them, the first one handles all the boring jobs: traversing the AST, extracting the footnote, removing unnecessary nodes, and injecting new nodes.&lt;/p&gt;
&lt;p&gt;The second one retrieves the HTML result and applies specific replacements to manage it. It ensures the expected attributes are added to the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; tags. These will be needed to guarantee that the anchoring of the elements works as expected.&lt;/p&gt;
&lt;p&gt;Now, the rest of the implementation is available &lt;a href=&quot;https://github.com/noghartt/blog/blob/main/src/pages/blog/%5Bslug%5D/index.astro#L306-L601&quot;&gt;here&lt;/a&gt;. It&apos;s doing a lot of things here, but explaining in a high-level way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inject all needed styles for the sidenotes[^2].&lt;/li&gt;
&lt;li&gt;Add some stylizations, just to be cute. Similar to how Gwern did on their blog. A bidirectional hover linking both the sidenote number and the sidenote container, per se. When you hover or click on each sidenote, it will have a different style.&lt;/li&gt;
&lt;li&gt;Add the logic to ensure the page loads to the correct anchor element, if it exists.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s where all the JavaScript I mentioned before appears. Sadly, some of the things I&apos;d like to do with my sidenotes aren&apos;t achievable only using CSS, so I had to use JS in part of the implementation.&lt;/p&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;There&apos;s a lot of cool stuff that I could do using sidenotes. Definitely, there are some improvements and better experiences that can be done in future iterations, which will be what I&apos;ll be looking to.&lt;/p&gt;
&lt;p&gt;For example, a friend of mine suggested that, on a mobile device, instead of showing the sidenote in the middle of the following line, right after the original reference, it could be a pop-up. It&apos;s something interesting that I&apos;ll be working on for future improvement.&lt;/p&gt;
&lt;p&gt;Also, I&apos;d like to render richer Markdown and other content within the sidenotes. It&apos;s limited in what I can do, mainly because of how it&apos;s being parsed, but that&apos;s another improvement I&apos;ll be working on.&lt;/p&gt;
&lt;p&gt;This is a bit about how I did the first implementation of my blog&apos;s sidenote. I hope it brings some cool ideas and flourishes creative ideas you can use on your own blog.&lt;/p&gt;
&lt;p&gt;[^1]: As a showcase, this is how it will look with the new implementation.
[^2]: As mentioned before, all this stylization is based on &lt;a href=&quot;https://edwardtufte.github.io/tufte-css/&quot;&gt;Tufte CSS&lt;/a&gt;. Yes, I&apos;m using a sidenote just because it&apos;s cool.&lt;/p&gt;
</content:encoded></item><item><title>Changelog 25#41</title><link>https://noghartt.dev/blog/changelog-2541/</link><guid isPermaLink="true">https://noghartt.dev/blog/changelog-2541/</guid><pubDate>Sun, 12 Oct 2025 22:20:47 GMT</pubDate><content:encoded>&lt;p&gt;Okay, I&apos;ll be starting a new kind of blog post here. The idea is bringing some
insights and things I watched, read or did in the week.&lt;/p&gt;
&lt;h2&gt;What I&apos;m doing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Studied a bit about how exactly DNA/RNA works. Understand a bit about RNA polymerase
and how exactly RNA transcript into mRNA.&lt;/li&gt;
&lt;li&gt;Read a bit about &lt;a href=&quot;https://en.wikipedia.org/wiki/Game_theory&quot;&gt;Game Theory&lt;/a&gt;.
Learned more about &lt;a href=&quot;https://en.wikipedia.org/wiki/Zero-sum_game&quot;&gt;Zero-sum games&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Nash_equilibrium&quot;&gt;Nash equilibrum&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Minimax&quot;&gt;Minimax&lt;/a&gt;
and the &lt;a href=&quot;https://en.wikipedia.org/wiki/Prisoner%27s_dilemma&quot;&gt;Prisoner&apos;s Dilemma&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I&apos;m still working in my &lt;a href=&quot;https://github.com/noghartt/viewstamped-replication-rs&quot;&gt;Viewstamped Replication Protocol&lt;/a&gt; implementation.
Finishing the implementation of my &lt;a href=&quot;https://notes.eatonphil.com/2024-08-20-deterministic-simulation-testing.html&quot;&gt;Deterministic Simulation Testing&lt;/a&gt; runner,
which is missing some specific parts for test: adding the randomness workflow + seed to
insert random actions during the tests, etc.&lt;/li&gt;
&lt;li&gt;Finished reading Akira, volume 1.&lt;/li&gt;
&lt;li&gt;Started reading Nicomachean Ethics, by Aristotle.&lt;/li&gt;
&lt;li&gt;Based on the release of &lt;a href=&quot;https://borretti.me/article/hashcards-plain-text-spaced-repetition&quot;&gt;Hashcards&lt;/a&gt;, I started
doing some new experiments with &lt;a href=&quot;https://en.wikipedia.org/wiki/Spaced_repetition&quot;&gt;Spaced Repetition&lt;/a&gt;. I&apos;ll
be coming back here in the next weeks with some report on that.&lt;/li&gt;
&lt;li&gt;Started a new run in Factorio + playing Terraria with a friend of mine.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What I read&lt;/h2&gt;
&lt;p&gt;This will be mostly based on the things I read based on my &lt;a href=&quot;/bookmarks&quot;&gt;bookmarks&lt;/a&gt;.
Just compiling some of the most interesting/cool things, the other ones, feel free to
check by yourself in the other page, there&apos;s more than I could reference here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lesswrong.com/posts/wEebEiPpEwjYvnyqq/when-money-is-abundant-knowledge-is-the-real-wealth&quot;&gt;When Money is Abundant, Knowledge is the real wealth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://interjectedfuture.com/what-is-algebraic-about-algebraic-effects/&quot;&gt;What is Algebraic about Algebraic Effects?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=u7ii_Lvm9rM&quot;&gt;CMU #08 - B+Trees: The Best Data Structure in the World&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MOV instructions are Turing Complete: &lt;a href=&quot;https://justanotherelectronicsblog.com/?p=771&quot;&gt;Weird CPU architectures, the MOV only CPU&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rakhim.exotext.com/examples-are-the-best-documentation&quot;&gt;Examples are the best documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mitchellh.com/writing/building-large-technical-projects&quot;&gt;My Approach to Building Large Technical Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.quantamagazine.org/rna-is-the-cells-emergency-alert-system-20250714&quot;&gt;RNA is the cell&apos;s emergency alert system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The most cool ones I read this week, I think are the above. Maybe I&apos;m forgetting something I read
which is on my bookmarks, but if that&apos;s the case, it&apos;s wasn&apos;t too much relevant to link here anyway.&lt;/p&gt;
</content:encoded></item><item><title>Falling Into the Perfectionism Trap</title><link>https://noghartt.dev/blog/falling-into-the-perfectionism-trap/</link><guid isPermaLink="true">https://noghartt.dev/blog/falling-into-the-perfectionism-trap/</guid><pubDate>Sat, 27 Sep 2025 07:51:52 GMT</pubDate><content:encoded>&lt;p&gt;Every time I open my Obsidian to start writing a new blog post, I remember the
other 15 drafts sitting there. Will those ever see the light of day? I don&apos;t know.
And that&apos;s a concern for me.&lt;/p&gt;
&lt;p&gt;It&apos;s easy to take ideas and put them into two or three phrases. But being able
to write for a long time (I&apos;m Gen Z—two hours is a long time for me, don&apos;t judge)
is just hard to do if I&apos;m not in the mood. And in the last few months, the one thing
I haven’t found is the mood.&lt;/p&gt;
&lt;p&gt;I&apos;d like to write about a lot of different things: my trip to Europe (the first
one, by the way), my studies on DST (jokes aside for Brazilians, I mean Deterministic
Simulation Testing), my studies on Distributed Systems. But I&apos;m just not in the
mood to write. Why? I don&apos;t know.&lt;/p&gt;
&lt;p&gt;I do believe I’ve really fallen into the perfectionism trap for writers. I can’t
count on one hand the number of drafts I was genuinely proud of last year. There&apos;s
always something missing—a phrase, a section, a requirement. That’s what I call
the perfectionism trap: when you look at the work you did, and all you can see
are the gaps and how far you are from the final result.&lt;/p&gt;
&lt;p&gt;But what is the final result? Sometimes I don’t even know. It’s just the feedback
loop of never feeling satisfied with what I wrote. It took me a while to understand
it. Even now, I don’t fully know where it comes from. Maybe I’m comparing myself
with other authors and trying to be like them? Yes, maybe. Maybe I’m too focused
on how the text is structured and not on whether the quality of what I’m producing
is good enough to be read? Maybe that too.&lt;/p&gt;
&lt;p&gt;My blog never was, and never will be, a platform just for the public. It never
was. My blog is about having a place where I can share all my things—from cooking
recipes and board game reviews to a 4,000-word wall-of-text book review or a report
on my learnings from building a compiler from scratch.&lt;/p&gt;
&lt;p&gt;It was never about being shorter or longer, but about whether, in essence, it
represents my thoughts and my spirit at that moment. But I’m not sure when I lost
that idea.&lt;/p&gt;
&lt;p&gt;In the end, to escape the perfectionism trap, it requires understanding that perfection
isn’t about a single piece of writing (or anything else) but the composition of
the whole body of work (and in this case, I’m not talking only about writing).&lt;/p&gt;
&lt;p&gt;What matters now is that I’ve found myself again and rediscovered the road I missed
a long time ago. There’s a lot of work to do here.&lt;/p&gt;
</content:encoded></item><item><title>Using nginx as a load balancer for my ngrok exposed local services</title><link>https://noghartt.dev/blog/using-nginx-as-a-load-balancer-for-my-ngrok-exposed-local-services/</link><guid isPermaLink="true">https://noghartt.dev/blog/using-nginx-as-a-load-balancer-for-my-ngrok-exposed-local-services/</guid><pubDate>Sun, 24 Aug 2025 23:18:18 GMT</pubDate><content:encoded>&lt;p&gt;Just a small post sharing something I learned last week. This is the kind of post that
could be a tweet, but instead, I want to put it here, on my blog. This was useful for me,
I know it can be again in the future, hope it will be useful for you too at some point.&lt;/p&gt;
&lt;p&gt;Last week, I had to do some tests given a specific scenario: having a load balancer which
should redirect to the same application running in 3 different ports in parallel.
After thinking a bit about how could I have the best setup to test it, I found a super
easy way to handle this: nginx.&lt;/p&gt;
&lt;p&gt;I found this documentation &lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/&quot;&gt;here&lt;/a&gt;, which
explains to me exactly how I could achieve this: specifially using a keyword called &lt;code&gt;upstream&lt;/code&gt;. Using it with the
&lt;code&gt;proxy_pass&lt;/code&gt;, will let me to put my reverse proxy to target this set of servers, where I can select how I want to route
of each of the exposed servers there (by default, it&apos;s routed as round robin).&lt;/p&gt;
&lt;p&gt;The nginx configuration would be like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;worker_threads auto;

http {
    upstream backend {
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;
        server 127.0.0.1:8003;
    }

    server {
        listen 8888;

        location / {
            proxy_pass http://backend;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the documentation I shared before, it also shows some other options and other use cases you can
achieve using this &lt;code&gt;upstream&lt;/code&gt; keyword.&lt;/p&gt;
&lt;p&gt;After that, I just need to expose my ngrok service to expose its reverse proxy to listen into the port 8888,
as I said in my &lt;code&gt;nginx.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ngrok http --url=example.ngrok-free.app 8888
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, all the requests that comes in &lt;code&gt;https://example.ngrok-free.app&lt;/code&gt; will be redirect automatically to my local reverse proxy
which will be automatically handled by its load balancer.&lt;/p&gt;
</content:encoded></item><item><title>Writing Your First Nix Overlay</title><link>https://noghartt.dev/blog/writing-your-first-nix-overlay/</link><guid isPermaLink="true">https://noghartt.dev/blog/writing-your-first-nix-overlay/</guid><pubDate>Sat, 04 Jan 2025 18:58:22 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After about 1 year, I came back to Nix as one of my main tools for my workflow.
In case, you can see my entire macOS configuration, written in Nix, &lt;a href=&quot;https://github.com/noghartt/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After having to change MacBook devices twice during the end of the last year, I really missed
Nix on my daily usage, where I need to setup my config every time, instead of just running a command.
That&apos;s why I&apos;m using Nix again after some period without it.&lt;/p&gt;
&lt;p&gt;Now, I reached a specific scenario last week, where I need to write a specific overlay for a tool. In my case,
&lt;a href=&quot;https://github.com/beancount/beanprice&quot;&gt;beanprice&lt;/a&gt;. I&apos;m using &lt;a href=&quot;https://github.com/beancount/beancount&quot;&gt;beancount&lt;/a&gt;, as
my daily-driven tool to track my finances, and I&apos;d like to track the value of my stocks in an easier way, instead
of having to manually adding it everytime.&lt;/p&gt;
&lt;p&gt;Doing some search, I discovered that the beancount&apos;s brewfile didn&apos;t install this binary for me. After trying the
&lt;code&gt;nixpkgs&lt;/code&gt; version of this binary, I discovered another thing: with that version, it comes with the &lt;code&gt;bean-price&lt;/code&gt;
binary, but it comes with an old version, where it didn&apos;t contain a specific module to fetch some of the stock
prices that I&apos;d like to fetch (more specifically, the &lt;a href=&quot;https://github.com/beancount/beanprice/blob/master/beanprice/sources/alphavantage.py&quot;&gt;alphavantage source&lt;/a&gt;).
For that reason, it seems to be a good argument to have an overlay for that. That&apos;s what I did, and was my first
time writing an overlay from scratch.&lt;/p&gt;
&lt;h2&gt;Writing the Module File&lt;/h2&gt;
&lt;p&gt;The overlays on Nix are a kind of function, it gives for us the ability to provide some overriding some specific configurations
for a given module, package or anything else that your creativity let you think about.&lt;/p&gt;
&lt;p&gt;In my case, what should I be doing? Writing a new overlay that would add a new package called &lt;code&gt;bean-price&lt;/code&gt; into all Python
packages modules. For that, I used this &lt;a href=&quot;https://github.com/GaetanLepage/nixpkgs/blob/master/doc/languages-frameworks/python.section.md&quot;&gt;Python section&lt;/a&gt; as my reference to do that.&lt;/p&gt;
&lt;p&gt;That&apos;s the output of what I did:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  lib,
  buildPythonPackage,
  python3Packages,
  fetchPypi,
  isPy3k,
}:

buildPythonPackage rec {
  version = &quot;1.2.1&quot;;
  format = &quot;setuptools&quot;;
  pname = &quot;beanprice&quot;;

  disabled = !isPy3k;

  src = fetchPypi {
    inherit pname version;
    hash = &quot;sha256-0/W1q25z6xNjhb7mZFpJUZ6TVNNA1BK341gOxlpOGVc=&quot;;
  };

  # Tests require files not included in the PyPI archive.
  doCheck = false;

  propagatedBuildInputs = with python3Packages; [
    python
    python-dateutil
    beancount
  ];

  meta = with lib; {
    homepage = &quot;https://github.com/beancount/beanprice&quot;;
    description = &quot;Daily price quotes fetching library for plain-text accounting &quot;;
    longDescription = &apos;&apos;
      A script to fetch market data prices from various sources on the internet and render them for plain text accounting price syntax (and Beancount).

      This used to be located within Beancount itself (at v2) under beancount.prices. This repo will contain all future updates to that script and to those price sources.
    &apos;&apos;;
    license = licenses.gpl2Only;
    maintainers = [ ];
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we&apos;re doing here? We&apos;re calling the &lt;code&gt;buildPythonPackage&lt;/code&gt; function accordingly to the Python interpreter. And will run four steps,
accordingly to this documentation &lt;a href=&quot;https://github.com/GaetanLepage/nixpkgs/blob/master/doc/languages-frameworks/python.section.md#buildpythonpackage-function-buildpythonpackage-function&quot;&gt;here&lt;/a&gt;: &lt;code&gt;buildPhase&lt;/code&gt;, &lt;code&gt;installPhase&lt;/code&gt;, &lt;code&gt;postFixup&lt;/code&gt; and &lt;code&gt;installCheck&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With that, we will be able to build and have our own binary of a given package, that, in case, we&apos;re fetching all those
informations based on the &lt;code&gt;src&lt;/code&gt; with the &lt;code&gt;fetchPypi&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;Finally, we had this overlay done, now, we need to let both &lt;code&gt;nixpkgs&lt;/code&gt; and &lt;code&gt;home-manager&lt;/code&gt; know about that.&lt;/p&gt;
&lt;h2&gt;Consuming the Overlays&lt;/h2&gt;
&lt;p&gt;In my opinion, as a good pattern for that, I like to have the overlay being &quot;exported&quot; on a main file.
For my config, I wrote a &lt;code&gt;overlays/default.nix&lt;/code&gt; that does it for me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /overlays/default.nix

final: prev:

let
  pythonPackageExtensionsOverrides = self: super: {
    bean-price = prev.callPackage ./bean-price {
      inherit (super) buildPythonPackage isPy3k;
    };
  };
in
{
  pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [pythonPackageExtensionsOverrides];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, what I&apos;m doing is: getting all my overrides related to python and overriding it on &lt;code&gt;pythonPackagesExtensions&lt;/code&gt;.
Which basically override it for every Python extension (&lt;code&gt;python3&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;python39&lt;/code&gt;, &lt;code&gt;python312&lt;/code&gt;, etc).&lt;/p&gt;
&lt;p&gt;Now, we just need to add it on the imported &lt;code&gt;nixpkgs&lt;/code&gt; and on &lt;code&gt;home-manager&lt;/code&gt;, to guarantee that everything is good.&lt;/p&gt;
&lt;p&gt;From another post that I wrote last year, where I teach &lt;a href=&quot;https://noghartt.dev/blog/set-up-nix-on-macos-using-flakes-nix-darwin-and-home-manager&quot;&gt;how to install Nix + nix-darwin + home-manager on macOS&lt;/a&gt;. My &lt;code&gt;flake.nix&lt;/code&gt; config was like that:&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt; &amp;lt;code&amp;gt;flake.nix&amp;lt;/code&amp;gt; config without overlays&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  inputs = {
    nix-homebrew.url = &quot;...&quot;;
    home-manager.url = &quot;...&quot;;
  };

  outputs = inputs @ { self, nix-homebrew, home-manager ... }: let
    nixpkgsConfig = {
      config.allowUnfree = true;
    };
  in {
    darwinConfigurations = let
      inherit (inputs.nix-darwin.lib) darwinSystem;
    in {
      machine = darwinSystem {
        system = &quot;aarch64-darwin&quot;;

        specialArgs = { inherit inputs; };

        modules = [
          ./hosts/mbp/configuration.nix
          inputs.home-manager.darwinModules.home-manager
          {
            nixpkgs = nixpkgsConfig;

            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.noghartt = import ./home/home.nix;
          }
        ];
      };
    };
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, we will need to adjust it in two parts to guarantee that everything is good:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  inputs = {
    nix-homebrew.url = &quot;...&quot;;
    home-manager.url = &quot;...&quot;;
+   nixpkgs.url = &quot;github:NixOS/nixpkgs&quot;;
  };

- outputs = inputs @ { self, nix-homebrew, home-manager, ... }: let
+ outputs = inputs @ { self, nix-homebrew, home-manager, nixpkgs, ... }: let
+   overlays = [ (import ./overlays) ];
+
+   system = &quot;aarch64-darwin&quot;;
+
+   pkgs = import nixpkgs { inherit system overlays; };
+
    nixpkgsConfig = {
+     inherit overlays;
+
      config.allowUnfree = true;
    };
  in {
+   packages = pkgs;
+
    darwinConfigurations = let
      inherit (inputs.nix-darwin.lib) darwinSystem;
    in {
      machine = darwinSystem {
        system = &quot;aarch64-darwin&quot;;

        specialArgs = { inherit inputs; };

        modules = [
          ./hosts/mbp/configuration.nix
          inputs.home-manager.darwinModules.home-manager
          {
            nixpkgs = nixpkgsConfig;

            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.noghartt = import ./home/home.nix;
          }
        ];
      };
    };
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that, you will be able to add both overlays to &lt;code&gt;nixpkgs&lt;/code&gt; side, so you can add the overlays
at a system-level, for NixOS, nix-darwin, or any place you&apos;re using it. And, inheriting &lt;code&gt;overlays&lt;/code&gt;
at the &lt;code&gt;nixpkgsConfig&lt;/code&gt; at L16, will let you use the overlay in &lt;code&gt;home-manager&lt;/code&gt; level.&lt;/p&gt;
&lt;p&gt;Now, in your home-manager config, you can do something like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ pkgs, config, lib, ... }:

{
  home.stateVersion = &quot;25.05&quot;;

  home.packages = with pkgs; [
    fava
    python3Packages.beancount
    python3Packages.bean-price
  ];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Solving Conflicts on Overlays&lt;/h2&gt;
&lt;p&gt;One issue that I had on this &lt;code&gt;bean-price&lt;/code&gt; overlay is, as I said, the &lt;code&gt;nixpkgs&lt;/code&gt; version of the &lt;code&gt;beancount&lt;/code&gt;
adds the &lt;code&gt;bean-price&lt;/code&gt; binary. So, both packages are conflicting to decide which of the binaries should
be chosen.&lt;/p&gt;
&lt;p&gt;The first solution that I saw, was adding a &lt;code&gt;meta.priority = 10;&lt;/code&gt; on the overlay. But haven&apos;t success, it
still getting the outdated version of the &lt;code&gt;bean-price&lt;/code&gt; binary. In that case, I did a different approach:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /overlays/default.nix

final: prev:

let
  pythonPackageExtensionsOverrides = self: super: {
    bean-price = prev.callPackage ./bean-price {
      inherit (super) buildPythonPackage isPy3k;
    };
+
+   beancount = super.beancount.overrideAttrs (oldAttrs: {
+     postInstall = &apos;&apos;
+       ${oldAttrs.postInstall or &quot;&quot;}
+       rm $out/bin/bean-price
+     &apos;&apos;;
+   });
  };
in
{
  pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [pythonPackageExtensionsOverrides];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I added an overlay to &lt;code&gt;beancount&lt;/code&gt; package too, where add a step on &lt;code&gt;postInstall&lt;/code&gt; that just remove
the binary related to &lt;code&gt;/bin/bean-price&lt;/code&gt;. With that, everything works as expected.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;DISCLAIMER!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I didn&apos;t find any other way to solve this issue. Everyone that knows a better, elegant approach to do
it, feel free to reach me out. I would really like to have a better way to solve this.&lt;/p&gt;
&lt;p&gt;Also, if I find something, I come back to this post and update it accordingly to what I find.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is just a brief tour around how you can approach to write your first overlay. And a good introduction
to understand how useful is Nix at all, you can do a lot of things or extend things that you already had as you want.
It&apos;s a powerful tool in the right hands.&lt;/p&gt;
</content:encoded></item><item><title>2024 in Review</title><link>https://noghartt.dev/blog/2024-in-review/</link><guid isPermaLink="true">https://noghartt.dev/blog/2024-in-review/</guid><pubDate>Mon, 30 Dec 2024 23:58:32 GMT</pubDate><content:encoded>&lt;p&gt;Following the tradition, writing my annual review. This year, being from ups and downs, a lot of things happened.
I can consider 2024 a good year looking from the macro perspective, but far from what I would like. I was able to
conclude my biggest objective for this year, but looking from the personal side, I wasn&apos;t good as I expected.&lt;/p&gt;
&lt;p&gt;Reflecting on what happened in this year, gave us some insights about what are the things that is going well and
which things we will need to fix on the next year. And, in my case, I have a lot of things to fix.&lt;/p&gt;
&lt;p&gt;Similar to last year, the structure of the post will be following like this: we will have some core points like &quot;health&quot;,
&quot;reading&quot;, &quot;habits&quot;, &quot;coding&quot;, &quot;career&quot;, etc. And, for this year, I&apos;ll be doing a kind of comparison to see how much
we improved on those ones or if we was able to maintain it.&lt;/p&gt;
&lt;h2&gt;Health&lt;/h2&gt;
&lt;p&gt;In the opposition from what I said in the expectations for 2024, I didn&apos;t take too much care from my health this year. I
was a lot below the average on the three critical points on health that I believe that would help me: sleep, gym and nutrition.&lt;/p&gt;
&lt;p&gt;Specifically about those three points, I didn&apos;t dedicate myself enough to fit what I expected from those ones, and all those threes
are interconnected, which had side-effects in other aspects of my life, like, for example, feeling tired during the days. In this year,
I could see how much having an unhealth life impacts in our life and, in my case, mostly having psychological effects about it.&lt;/p&gt;
&lt;p&gt;From my experience, it was pretty hard to have a good night of sleep, staying focused for long times or even not being too stressful during the
day. Also, it seems that it impacts a lot on &quot;ADHD crisis&quot;, where, in some days, it was just impossible to work without my medicines.&lt;/p&gt;
&lt;p&gt;Also, from sleep routine, I think that this year was a bit difficult to stay focused on that too. Even because my new apartment is on the downtown,
there&apos;s more noise and chaos, then being more disciplined on that was very hard. My sleep time average was about 6 hours, but knowing myself, I know
that this isn&apos;t enough to be 100% functional on the next day. Also, I completely lost my habit of waking up between 6AM and 7AM.&lt;/p&gt;
&lt;p&gt;I&apos;m not fully commited on gym too, it&apos;s a pretty hard habit to maintain, I need to commit hard on that and being focused on the long term objectives.
But, not just from bad things, my year in health is going on, this year I discovered a new sport that I really loved: climbing. I really love it. It&apos;s one of
the things that I really want to maintain in the next year.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;This year, I started the year maintaining the goal of 12 books until the end of the year, but I reached out only about 6 or 7 of them, to be honest, some
of them are so useless in their concepts that is completely insignificant for myself. During the year, I noted this bad behavior, I wasn&apos;t reading because
I&apos;d like to read more about the theme, I just read because of the quantity. After that, I decided to slow down my reading and coming back with better books
that I&apos;d like to read. Some of the books that I can mentioned that I read was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Database Internals, by Alex Petrov&lt;/li&gt;
&lt;li&gt;Antifragile, by Nassim N. Taleb&lt;/li&gt;
&lt;li&gt;Fooled by Randomness, by Nassim N. Taleb&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, I started a lot of books that I dropped after some time, because I was feeling that the reading wasn&apos;t productive as I expected, like: &lt;em&gt;&quot;Noise: A Flaw in Human Judgement&quot;&lt;/em&gt;
and &lt;em&gt;&quot;Thinking Fast and Slow&quot;&lt;/em&gt;, both from Daniel Kahneman, are two of those books that I dropped after some time.&lt;/p&gt;
&lt;p&gt;In the moment I&apos;m writing this, I&apos;m reading what I believed that will be my first readings from 2025: &lt;em&gt;&quot;Godel, Escher, Bach: an Eternal Golden Braid&quot;&lt;/em&gt;, by Douglas R. Hofstadter,
and &lt;em&gt;&quot;The Mind Illuminated&quot;&lt;/em&gt;, by John Yates, the last one as a recommendation from a friend, because I&apos;m really interested in investigate some long term effects from meditation
in my life. Further that, for the next year, I have a lot of good books to read, most of them focused on technical aspects, but I want to reread some of the old books that I read too.&lt;/p&gt;
&lt;h2&gt;Career and Work&lt;/h2&gt;
&lt;p&gt;I think that, from the career perspective, this year was awesome. I was able to complete the most import objective from my year in this aspect. Now, I have the great opportunity of
working with awesome guys at &lt;a href=&quot;https://fireflies.ai&quot;&gt;Fireflies.ai&lt;/a&gt;, and it&apos;s being awesome in every sense. I&apos;m working with a lot of good engineers and having the opportunity to bring
innovation for millions of users, further the aspect of learning a lot of new skills and technologies around it.&lt;/p&gt;
&lt;p&gt;From my career perspective, I could be better on that, I believe I could dedicate myself more during the year and investing more time on side projects and learning in general. I
have some advances on the distributed systems topics, but below my expectations. For the next year, one of my goals is bringing a more actively approach on this topic.&lt;/p&gt;
&lt;h2&gt;Writing&lt;/h2&gt;
&lt;p&gt;From the writing side, I&apos;d say that was an year in average. I have a feeling that I could do it better, but I have some great works this year, like: &lt;a href=&quot;https://noghartt.dev/blog/increasing-your-friction-area/&quot;&gt;Increasing Your Friction Area&lt;/a&gt;,
&lt;a href=&quot;https://noghartt.dev/blog/paxos-made-simple-with-rust/&quot;&gt;Implementing Simple Paxos Consensus Algorithms With Rust&lt;/a&gt; and &lt;a href=&quot;https://noghartt.dev/blog/rss-and-why-i-love-it/&quot;&gt;RSS and why I love it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Not considering the drafted posts and this one, it was 10 posts during the entire year. It was in average, better than zero. For the next year, I will be more consistent on that.
I think that one of the greatest issues with writing is not trying to writing the perfect article, I need to write, just it. That will be my mantra for the next year.&lt;/p&gt;
&lt;h2&gt;Next steps for 2025&lt;/h2&gt;
&lt;p&gt;This as a summary review from my year, for sure there&apos;s a lot of other things that I didn&apos;t mentioned, either because I wouldn&apos;t like to do or because I forgot. And, for 2025,
I have a strong feeling that, given my 2024, it will be a better year in all aspects. I have a lot of plans for the next year and I&apos;ll commit in all of them.&lt;/p&gt;
&lt;p&gt;From the same thing I said last year, this next year I &lt;strong&gt;need&lt;/strong&gt; to focus on my health. It&apos;s not only about being a healthier person, but, if I want to be a high-performance person,
I need to have a healthier body and a healthier mind. That&apos;s why I&apos;ll be doing some checkups and working intensively to improve in this aspect of my life. From the psychological side,
I&apos;ll be leaving my social medias for a time and trying to reduce my screentime. As said before, I&apos;m really interested in meditation, I want to see how my mind, that is agitated by nature,
will perform after gym and meditation, if I can think better, improve my sleep, and other related things.&lt;/p&gt;
&lt;p&gt;Being more organized is other aspect of my life for 2025 that I will being focused on. Having a better scheduled time, will bring to me some improvements on my routine, which implies in having
a consistent performance accordingly to the tasks I need to work on. And, looking from the long term perspectivee too, being more organized can give me some useful insights around the things
that I worked on during the week, month, quarter, semester or year. Then, I can review and change the direction of something when necessary.&lt;/p&gt;
&lt;p&gt;From the point I mentioned above, with that in mind, writing will be one of the core habits I&apos;ll maintain and improve on the next year. Not writing blog posts, but writing my thoughts. Documenting
what I did, documenting things that I&apos;m looking on, documenting how I&apos;m doing things, because, in the future, those resources will be the reference for the next annual review, for example. I want
to have more quantitative date from my life too, following the idea from Stephen Wolfram &lt;a href=&quot;https://writings.stephenwolfram.com/2019/02/seeking-the-productive-life-some-details-of-my-personal-infrastructure/&quot;&gt;here&lt;/a&gt;,
I want to track my life in quantitative perspective to bring some useful insights about the correlation of data.&lt;/p&gt;
&lt;p&gt;My focus for the next year will be more on increasing consistency on good habits, that is, guarantee that the things that I&apos;m doing is coming from a good feedback loop and tha
it will have a good return in the long term.&lt;/p&gt;
&lt;p&gt;It wasn&apos;t the best year of my life, but I&apos;d say that one of the most importants. I&apos;d like to thanks my girlfriend for this incredible year at her side, I love you so much, I learn a lot from you.
Also, thanks for each of my friens that gave me the opportunity to share this year with them, it was incredible.&lt;/p&gt;
&lt;p&gt;The next year, for me, will be a year of consistency, reconstruction, maintenance and improvement.&lt;/p&gt;
&lt;p&gt;Happy New Year, reader! Hope that, in 2025, I bring a better version of me here.&lt;/p&gt;
</content:encoded></item><item><title>On Bookmarks, Lists and the Habit of Reading Later</title><link>https://noghartt.dev/blog/on-bookmarks-lists-and-the-habit-of-reading-later/</link><guid isPermaLink="true">https://noghartt.dev/blog/on-bookmarks-lists-and-the-habit-of-reading-later/</guid><pubDate>Wed, 25 Sep 2024 22:24:04 GMT</pubDate><content:encoded>&lt;p&gt;Bookmarks are underrated features. It&apos;s a good way to help you keep track
of not only what you need to read but also what you need to do. Further, your
bookmarks can be a way to structure your reading and your knowledge, for future
reference, as Josh Leeb talked about &lt;a href=&quot;https://joshleeb.com/posts/organizing-bookmarks.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;About the organization of my bookmarks&lt;/h2&gt;
&lt;p&gt;Inspired by a friend of mine, in January 2024 I started having a &quot;reading list&quot;
of my bookmarks. As commented on &lt;a href=&quot;https://noghartt.dev/blog/rss-and-why-i-love-it&quot;&gt;RSS and why I love it&lt;/a&gt;,
I have an RSS feed that I use to read a lot of things during the day. But, one thing
that I missed was the ability to have a list of things that shall store: what I
already read and what I need to read (in the future, that kind of list always
increases).&lt;/p&gt;
&lt;p&gt;So, as you can see on my &lt;a href=&quot;https://noghartt.dev/bookmarks&quot;&gt;bookmarks page&lt;/a&gt;, I have
a list containing all the content that I have consumed since January 2024, not just
articles, but also videos, podcasts, etc. I have &lt;a href=&quot;https://noghartt.dev/bookmarks/tags&quot;&gt;another page&lt;/a&gt;
to see them grouped by their tags, so I can easily find a specific bookmark given
the tag I want.&lt;/p&gt;
&lt;h3&gt;How do I store my bookmarks?&lt;/h3&gt;
&lt;p&gt;The tool that I use to manage my bookmarks is &lt;a href=&quot;https://omnivore.app/&quot;&gt;Omnivore&lt;/a&gt;,
an open-source bookmark manager and &quot;read-it-later&quot; app. For my use case, it&apos;s a
great tool, I have their extension for the browser installed that I use to store
the tab that I&apos;m seeing.&lt;/p&gt;
&lt;p&gt;Also, I&apos;m using their mobile app, which lets me read all bookmarks that I have.
In that case, I&apos;m using it mostly to read my &quot;read-it-later&quot; articles while in
the gym, for example.&lt;/p&gt;
&lt;h2&gt;About the list of my bookmarks&lt;/h2&gt;
&lt;p&gt;As mentioned before, further the list on Omnivore, I have a list of my bookmarks
inside this blog. I have two specific ways to organize them: grouped by
month and grouped by tags.&lt;/p&gt;
&lt;p&gt;Most of the time, I&apos;m using it based on tags because I think that it&apos;s how my brain
works, so it&apos;s faster to remember what I exactly want. For example, if I want to
read something that I didn&apos;t read yet, I can just go to the tag &lt;code&gt;#for-later&lt;/code&gt;. If
If I want to recover something related to a computer science topic, I can go to the
tag &lt;code&gt;#cs&lt;/code&gt; or one of their specific subtags like &lt;code&gt;#cs/distsys&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Specifically about tags, mentioning again Josh Leeb, who wrote a post about
&lt;a href=&quot;https://joshleeb.com/posts/scoped-tagging.html&quot;&gt;Scopped Tagging Bookmarks&lt;/a&gt;. where
he tries some approaches explains some of the problems and presents some approaches
for it.&lt;/p&gt;
&lt;p&gt;In my case, I have a kind of implementation of what he mentioned as HNT (Hierarchical
Namespaced Tagging), so on Omnivore and, you can see here at my blog, I did a hierarchical
structure for my tags. But, I think that it&apos;s a process that can be error-prone
sometimes, like when you need to be a more specific tag or a less specific one,
or when You didn&apos;t find a specific tag that matches your need for some bookmarks.&lt;/p&gt;
&lt;h2&gt;About the habit of reading later&lt;/h2&gt;
&lt;p&gt;Then, as mentioned before, one of my specific tags that I use (and I believe that
is one of the most used by myself), is &lt;code&gt;#for-later&lt;/code&gt;. Specifically this tag, I use
to store every bookmark that I didn&apos;t read yet but I think that it&apos;s interesting.&lt;/p&gt;
&lt;p&gt;I don&apos;t like the idea of storing &quot;read-it-later&quot; articles at all seems to be more
a product of a FOMO rather than a real interest, but it&apos;s something that I am
still maintaining just as a &quot;habit&quot;.&lt;/p&gt;
&lt;p&gt;Also, I think that it&apos;s a trade-off that you need to deal with, your list of read-it
later articles will be growing over time, and you will need to choose and validate
if that content really will be interesting for you in the future.&lt;/p&gt;
</content:encoded></item><item><title>Do not trust on yourself, trust on checklists</title><link>https://noghartt.dev/blog/do-not-trust-on-yourself-trust-on-checklists/</link><guid isPermaLink="true">https://noghartt.dev/blog/do-not-trust-on-yourself-trust-on-checklists/</guid><pubDate>Thu, 25 Jul 2024 01:24:19 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently, I saw a specific project from &lt;a href=&quot;https://x.com/LukeberryPi&quot;&gt;Lukeberry&lt;/a&gt; called &lt;a href=&quot;https://como-debugar-frontend.vercel.app/&quot;&gt;&quot;Como Debugar Frontend&quot;&lt;/a&gt;, in English, it would be called &quot;How to Debug Frontend&quot;.&lt;/p&gt;
&lt;p&gt;The UI behind this project is very simple, it&apos;s just a list of checkboxes that you can follow to match your situation
and validate that you are following the right steps to debug any issue that you could have through your front-end code.
But, the idea behind this project is powerful: we are susceptible to failure, and we shouldn&apos;t trust ourselves, instead,
we should have a fault-tolerant system that can help us to trust in the process.&lt;/p&gt;
&lt;h2&gt;Why do checklists matter?&lt;/h2&gt;
&lt;p&gt;A checklist is a &lt;a href=&quot;https://noghartt.dev/blog/the-awesomeness-of-lists&quot;&gt;specific kind of list&lt;/a&gt; that we can use to validate if we are following the expected steps to do something.
You can see through the entire internet a range of cases of usage of checklists, like those being applied to the
aviation or medical fields.&lt;/p&gt;
&lt;p&gt;In a scenario of stress or fatigue, you will be compromised by a decrease in your ability or cognitive functioning. The
usage of a checklist will give you a way to &lt;em&gt;&quot;metavalidate&quot;&lt;/em&gt; your capabilities and will let you reason about the
the current state of the situation you are facing.&lt;/p&gt;
&lt;p&gt;On &lt;a href=&quot;https://www.ucl.ac.uk/anaesthesia/sites/anaesthesia/files/hales-2006.pdf&quot;&gt;&quot;The checklist — a tool for error management and performance improvement&quot;&lt;/a&gt;, the authors of the paper bring some interesting data related to the
usage of checklists in some fields like aviation, medicine, and product manufacturing.&lt;/p&gt;
&lt;p&gt;We even have a book called &lt;em&gt;&quot;The Checklist Manifesto&quot;&lt;/em&gt;, that clarifies some ideas about the usage of checklists and the
spread of the concept. I suggest you read it, also read the &lt;a href=&quot;http://muratbuffalo.blogspot.com/2024/01/the-checklist-manifesto-dr-atul-gawande.html&quot;&gt;review from Murat Demirbas&lt;/a&gt;, it&apos;s a great review that explains some ideas of the book too.&lt;/p&gt;
&lt;h2&gt;How can I create my checklist?&lt;/h2&gt;
&lt;p&gt;Now that you already know the importance of checklists to bring a better experience to your work, you, being an engineer (I suppose that you are one), do you agree that you should have a checklist for your daily work?&lt;/p&gt;
&lt;p&gt;It will give you a documented, structured way to validate if some aspect or scope of your work is being followed as expected.
It will help to bring clarification to your work in the future for yourself and for the team that will need to work with you.&lt;/p&gt;
&lt;p&gt;So, which things from my work should have a checklist?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A checklist for the feature that you are working on.&lt;/li&gt;
&lt;li&gt;A checklist with the step-by-step process to test a new feature.&lt;/li&gt;
&lt;li&gt;A checklist with the step-by-step process to release a new version of your product.&lt;/li&gt;
&lt;li&gt;A checklist with the step-by-step process to debug a feature, like the &lt;a href=&quot;https://como-debugar-frontend.vercel.app/&quot;&gt;&quot;Como Debugar Frontend&quot;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A checklist with the playbook when you&apos;re talking with a customer.&lt;/li&gt;
&lt;li&gt;A checklist with the presentation of your product for an internal team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those are just some examples of the things that you can have a checklist for. With that, you can validate
the reality and check if it matches the expectations of the situation.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With that in mind, I hope that you can see how much valuable is to have a checklist for your daily work.
You can apply this concept to everything that you do, even outside your work, like the way you talk with your customers.&lt;/p&gt;
&lt;p&gt;I want to find some papers and articles that bring some data related to the usage of checklists and their reduction
in incidents and errors. But, clearly is a good idea to have a checklist with yourself to guarantee
a pragmatic approach to how you do your work, also it&apos;s a way to reduce the noise from outside and focus on the important things.&lt;/p&gt;
</content:encoded></item><item><title>Software Engineering is More Than Just Coding</title><link>https://noghartt.dev/blog/software-engineering-is-more-than-just-coding/</link><guid isPermaLink="true">https://noghartt.dev/blog/software-engineering-is-more-than-just-coding/</guid><pubDate>Tue, 09 Jul 2024 02:05:24 GMT</pubDate><content:encoded>&lt;p&gt;I have a strong belief that most of the time, there is a clear separation
between two concerns: software engineering and coding. Both look similar, both
work together, but they aren&apos;t the same.&lt;/p&gt;
&lt;p&gt;Software engineering is more than coding in the aspect that it involves more about
your work than just your pull request on GitHub. It&apos;s more about the processes
and patterns that you apply through your workflow that impact what I mean by
engineering here, in this blog post.&lt;/p&gt;
&lt;p&gt;Software engineering is about the guarantee that, from the macro perspective,
the product and the code that you are working on will correspond to the
expectations that they have, both from the product and technical sides.&lt;/p&gt;
&lt;p&gt;About the product side, it follows the expectations around the culture and what
your company, product or anything else you&apos;re working on has, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it is what the customer wants;&lt;/li&gt;
&lt;li&gt;If it will bring some quality of life improvement for your customer;&lt;/li&gt;
&lt;li&gt;If it will be a building block for a greater feature,&lt;/li&gt;
&lt;li&gt;And anything else that gives a clear objective for the final customer.
Assuming that your &lt;em&gt;&quot;customer&quot;&lt;/em&gt; here could be anything in that scenario
that will consume the product that you are working on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;About the technical side, the core properties that should be followed in my vision
are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The guarantee that everything related to your code
will follow the expectations around the patterns, the code guidelines that have
been discussed in your company, project, etc.&lt;/li&gt;
&lt;li&gt;Ensure that your feature has been tested, by yourself, by systematic tests,
here being any kind of test (integration, unit, property, end-to-end, anything).&lt;/li&gt;
&lt;li&gt;Ensure that the documentations are available and up-to-date according to the
expectations that you and your coworkers have around the feature/code that you
are working on.&lt;/li&gt;
&lt;li&gt;Ensure that the code won&apos;t break the existing codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;About my thoughts around what I believe are responsibilities of software
engineers that are more than coding, I will write some of my thoughts below:&lt;/p&gt;
&lt;h2&gt;Documentation as a Resource for the Future&lt;/h2&gt;
&lt;p&gt;Documentation is one of the most important parts of a project, in my opinion.
It&apos;s about the guarantee that the decisions and the resources that you have at
the moment you wrote a code have been saved in a way that can be validated in the
future, by yourself or any other developer that will need to maintain your code.&lt;/p&gt;
&lt;p&gt;Having a powerful context of the past decisions brings to the table the ability
to review it and understand why some options have been taken or not. Some projects
have been written by people that aren&apos;t in the company anymore and you can&apos;t contact
them, so think how much easier it would be for you when you try to run that old
project if they had at least one documentation about &lt;em&gt;&quot;How to run Project X&quot;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Documentation brings to you a safe guarantee that, in the future, yourself from
the past prepared all the place answering some of the future doubts that could
exists.&lt;/p&gt;
&lt;p&gt;Documentation should be an atemporal feature for anyone that wants to build
a resilient, scalable, and maintainable software.&lt;/p&gt;
&lt;h2&gt;Tests as The Reinforcement Guarantee&lt;/h2&gt;
&lt;p&gt;If your code isn&apos;t supported by tests, your code isn&apos;t production-ready. I would
say that for the majority of scenarios, you should have at least 1 test that
guarantees the behavior of a given scope.&lt;/p&gt;
&lt;p&gt;Recently, I read a great piece of blog posts from Matklad: &lt;a href=&quot;https://matklad.github.io/2021/05/31/how-to-test.html&quot;&gt;How to Test&lt;/a&gt;,
it brings some great material around how you could exactly test your software.
And I believe that a strong software should be test oriented, in a perspective
where you have the guarantee that, even if you inserted some specific new thing
into your system, the feedback loop of the tests that you have will ensure that, if
something has been broken, it will be caught up.&lt;/p&gt;
&lt;p&gt;Tests are the proof of the &lt;em&gt;axioms&lt;/em&gt; of your systems, the rules and the guarantee
that your system will be working in a specific way. They aren&apos;t about what exactly
users shouldn&apos;t do, but it&apos;s the guarantee that, based on what users really can do,
you won&apos;t have a breaking change.&lt;/p&gt;
&lt;p&gt;Tests also let you move fast, with the security that if there is any breaking
change, it will be easily caught by those ones.&lt;/p&gt;
&lt;p&gt;In any other kind of engineering, you have tests, redundancy, and tools that
provide safety through their work, like a civil engineer building a bridge.
Tests, for software engineers, follow the same idea.&lt;/p&gt;
&lt;h2&gt;Migrations and Refactors as Engineers&lt;/h2&gt;
&lt;p&gt;As &lt;a href=&quot;https://lore.kernel.org/lkml/CA+55aFy98A+LJK4+GWMcbzaa1zsPBRo76q+ioEjbx-uaMKH6Uw@mail.gmail.com/&quot;&gt;Linus said some time ago&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WE DO NOT BREAK USERSPACE!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At the moment that your code goes to production, you have more concerns than just
the usability of your code. How many people will be using it? How will a breaking
change impact them if you inserted a new one? What are the implications?
The second and third order effects of those changes? Can you think of the entire
chain of consequences of this action?&lt;/p&gt;
&lt;p&gt;You, as an engineer, should be carefully thoughtful about the decisions in your
code. The implications of a specific change can impact a lot of customers in a
harmful way that even you can&apos;t imagine.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Backward_compatibility&quot;&gt;Backward compatibility&lt;/a&gt;
is a term that I like a lot. Being the guarantee of the interoperability of an
older system (as said by Wikipedia), on the software side, it&apos;s the guarantee that
we will ensure the same behavior of our APIs even for old clients.&lt;/p&gt;
&lt;p&gt;Even for internal tooling or between shared modules across your codebase, you
should carefully think about backwards compatibility. You will always have a consumer
of an API and, in that scenario, your API is the interface that has been exported
by your functions and is being consumed on the other side of your codebase. The guarantee
that it won&apos;t break, or that it will change in every place, is a guarantee of less
entropy throughout your entire codebase.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is what I believe are some specific parts of a job of a software engineer,
coding is one of the easier parts of the job. You have a lot more concerns to think
about regarding your product, your code and other related aspects of the company.&lt;/p&gt;
&lt;p&gt;And I believe that we should be more engineers and not just developers.&lt;/p&gt;
</content:encoded></item><item><title>My Arch Linux Installation: systemd-boot, LUKS, Btrfs, swapfile and xmonad</title><link>https://noghartt.dev/blog/my-arch-linux-installation/</link><guid isPermaLink="true">https://noghartt.dev/blog/my-arch-linux-installation/</guid><pubDate>Sun, 07 Jul 2024 07:07:03 GMT</pubDate><content:encoded>&lt;h2&gt;Before the installation&lt;/h2&gt;
&lt;h3&gt;Save things that you need to be saved&lt;/h3&gt;

&lt;li&gt;&lt;strong&gt;The public and private GPG keys&lt;/strong&gt;:&lt;/li&gt;

&lt;pre&gt;&lt;code&gt;gpg --export --armor &amp;gt; public.key
gpg --export-secret-key --armor &amp;gt; private.key
&lt;/code&gt;&lt;/pre&gt;

&lt;li&gt;&lt;strong&gt;Your shared GPG and SSH files.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your data.&lt;/strong&gt;&lt;/li&gt;

&lt;p&gt;&lt;strong&gt;REMEMBER:&lt;/strong&gt; if you have some dotfiles or other projects in your PC, make sure
that you have pushed your changes.&lt;/p&gt;
&lt;h3&gt;Make sure the drive security is not frozen&lt;/h3&gt;
&lt;p&gt;If you are running a pre-installed system, you can cleaning all the storage
(in my case, a SSD NVMe), you can wipe your storage to clean all things inside it.
To do it on a SSD NVMe, you can do these things:&lt;/p&gt;
&lt;p&gt;Run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvme id-ctrl /dev/nvme0 -H |grep &quot;Format \|Crypto Erase\|Sanitize&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Erase all data from your storage (SSD NVMe)&lt;/h3&gt;
&lt;p&gt;You can run the &apos;nvme sanitize` command to erase all data from the storage.
You can see an example of the command here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvme sanitize &amp;lt;device&amp;gt; -a &amp;lt;action&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The possible actions that you can use is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-a &amp;lt;action&amp;gt;
--sanact=&amp;lt;action&amp;gt;
    Sanitize Action
    000b - Reserved
    001b - Exit Failure Mode
    010b - Start a Block Erase sanitize operation
    011b - Start an Overwrite sanitize operation
    100b - Start a Crypto Erase sanitize operation
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ATTENTION:&lt;/strong&gt; When you running the &lt;code&gt;sanitize&lt;/code&gt; command, you should replace your
binary value by their decimal part, e.g. &lt;code&gt;000b = 0&lt;/code&gt;, &lt;code&gt;001b = 1&lt;/code&gt;, &lt;code&gt;010b = 2&lt;/code&gt;, etc...&lt;/p&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/Solid_state_drive/NVMe&quot;&gt;Arch Linux: SSD/NVMe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/Solid_state_drive/Memory_cell_clearing#NVMe_drive&quot;&gt;Arch Linux: SSD/Memory cell clearing - NVMe drive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Wipe on an Empty Disk&lt;/h3&gt;
&lt;h4&gt;Create a temporary encrypted container on the complete device to be encrypted&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup open --type plain -d /dev/urandom /dev/nvme0n1 to_be_wiped
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Wipe the container with zeros&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=4096 status=progress
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;h3&gt;Disk partitioning (UEFI)&lt;/h3&gt;
&lt;p&gt;The partiotining that follows the concerns the UEFI installation.&lt;/p&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;p&gt;First of all, I have differente names for the partitions, but don&apos;t be lost for
so little:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mount point&lt;/th&gt;
&lt;th&gt;Partition name&lt;/th&gt;
&lt;th&gt;Partition type&lt;/th&gt;
&lt;th&gt;Bootable flags&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/boot&lt;/td&gt;
&lt;td&gt;/dev/nvme0n1p1&lt;/td&gt;
&lt;td&gt;EFI System&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;1 Gb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/&lt;/td&gt;
&lt;td&gt;/dev/nvme0n1p2&lt;/td&gt;
&lt;td&gt;Linux LVM&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Remainder of the device&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;lt;!-- TODO: See it beter --&amp;gt;
Where &lt;code&gt;/&lt;/code&gt; will be a LVM-encrypted partition having a group volume containing a
physical volume and &lt;code&gt;root&lt;/code&gt;as a logical volume.&lt;/p&gt;
&lt;p&gt;Finally, as mentioned in the introduction, we will format the &lt;code&gt;/&lt;/code&gt; volume as &lt;code&gt;Btrfs&lt;/code&gt;
and create two sub-volume:&lt;/p&gt;

&lt;li&gt;&lt;code&gt;/root&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/home&lt;/code&gt;&lt;/li&gt;

&lt;h4&gt;Creation of the File System&lt;/h4&gt;
&lt;p&gt;In order to know the name of your disk, it is necessary to list the partition
tables for the specified device:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fdisk -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s select our disk to build the table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cfdisk /dev/nvme0n1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create a new empty &lt;code&gt;GPT&lt;/code&gt;partition table.&lt;/p&gt;
&lt;p&gt;And now, you can setup all the partiions in a &quot;visual&quot; way.&lt;/p&gt;
&lt;h3&gt;Setup the Disk Encryption&lt;/h3&gt;
&lt;p&gt;In order to enable disk encryption, we will first create a root LUKS volume, open
it and then format it.&lt;/p&gt;
&lt;p&gt;In a brief explaination, LUKS is a container format that will be used to encrypt
containers, where our encryption key will be stored.&lt;/p&gt;
&lt;h4&gt;Creation of a root LUKS volume&lt;/h4&gt;
&lt;p&gt;To encrypt our &lt;code&gt;/&lt;/code&gt; partition, we will use the &lt;code&gt;cryptsetup&lt;/code&gt; tool:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup --hash sha512 --use-random --verify-passhphrase luksFormat /dev/nvme0n1p2
Are you sure? YES
Enter passhphrase (twice)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Opening the root LUKS volume as block device&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;/&lt;/code&gt; partition being encrypted, we will open the LUKS container on &lt;code&gt;/dev/nvme0n1p2&lt;/code&gt;
disk and name it &lt;code&gt;cryptlvm&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup open /dev/nvme0n1p2 cryptlvm
Enter passhphrase
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The decrypted container is now available at &lt;code&gt;/dev/mapper/cryptlvm&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Setup the LVM&lt;/h3&gt;
&lt;p&gt;LVM is a logical volume manager for the Linux kernel. It is thank to to it that
we can easily resize our partitions if necessary.&lt;/p&gt;
&lt;h4&gt;Create a physical volume on top of the opened LUKS container&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pvcreate /dev/mapper/cryptlvm
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Add the previously created physical volume to a volume group&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;vgcreate vg /dev/mapper/cryptlvm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;!-- TODO: Write this section --&amp;gt;&lt;/p&gt;
&lt;h4&gt;Create the swap logical volume on the volume group&lt;/h4&gt;
&lt;h4&gt;Create the root logical volume on the volume group&lt;/h4&gt;
&lt;p&gt;&amp;lt;!-- TODO: See if it is necessary because of swapfile --&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lvcreate -l 100%FREE vg -n root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Formatting the filesystem&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mkfs.fat -F32 /dev/nvme0n1p1
mkfs.btrfs -L btrfs /dev/mapper/vg-root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Btrfs subvolumes&lt;/h3&gt;
&lt;p&gt;Subvolumes are part of the filesystem with its own and independnet file/directory
hierarchy, where each subvolume can share file extents.&lt;/p&gt;
&lt;h4&gt;Create Btrfs subvolumes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mapper/vg-root /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Mounting Btrfs subvolumes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SSD_MOUNTS=&quot;autodefrag,compress=lzo,discard,noatime,nodev,rw,space_cache,ssd&quot;
mount -o subvol=root,$SSD_MOUNTS /dev/mapper/vg-root /mnt

mkdir -p /mnt/{boot,home}

mount -o discard,noatime,nodev,noexec,nosuid,rw /dev/nvme0n1p1 /mnt/boot
mount -o $SSD_MOUNTS,nosuid,subvol=home
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;Some details about the option on &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; flag:&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;autodefrag&lt;/code&gt;: enable automatic file defragmentation for small random writes in
files with a maximum file size of 64K;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compress=lzo&lt;/code&gt;: compresses files with the lzo type which is a lossless data
compression algorithm that is focused on decompression speed;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;discard&lt;/code&gt;: enable discarding of freed file blocks using TRIM operation (useful
for SSD devices);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noatime&lt;/code&gt;: allows measurable performance gains by eliminating the need for the
system to write to the file system for files that are simply read;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodev&lt;/code&gt;: disallows creating and accessing device nodes (used in particular for
special files in /dev);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noexec&lt;/code&gt;: does not allow the execution of executable binaries in the mounted
file system;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nosuid&lt;/code&gt;: specifies that the filesystem cannot contain set userid files;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rw&lt;/code&gt;: allows reading and writing;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;space_cache&lt;/code&gt;: control the free space cache. This greatly improves performance
when reading block group free space into memory;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssd&lt;/code&gt;: by default, &lt;code&gt;Btrfs&lt;/code&gt; will enable or disable SSD allocation heuristics
depending on whether a rotational or non-rotational device is in use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h3&gt;Base system&lt;/h3&gt;
&lt;h4&gt;Update the mirrors&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S reflector
reflector --threads 8 --protocol http --protocol https --verbose --sort rate --country Brazil --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Installation of the packages onto a given root file system&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacstrap /mnt base linux-firmware linux-zen lvm2 sudo man-db base-devel linux-tools git hdsentinel fwupd sudo
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Configuration of the system&lt;/h3&gt;
&lt;p&gt;We will configure the system base in order to have a decent environment.&lt;/p&gt;
&lt;h4&gt;Generate a fstab file&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;genfstab -U /mnt &amp;gt;&amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Change root into the new system&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Create the swap file&lt;/h4&gt;
&lt;p&gt;To create the swap file, we will create a zero length file, set the &lt;code&gt;No_COW&lt;/code&gt; attribute
and make sure compression is disabled:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;truncate -s 0 /swapfile
chattr +C /swapfile
btrfs property set /swapfile compression none
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is recommended to set the size of swap file being 4-8GB if you don&apos;t intend to use
hibernation (suspend-to-disk):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/swapfile bs=1M count=16384 status=progress &amp;amp;&amp;amp; sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the permission for the file (a world-readable swap file is a huge local vulnerability):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod 600 /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Format the &lt;code&gt;/swapfile&lt;/code&gt; file to swap and activate it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkswap /swapfile
swapon /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, add an entry for the swap file in the fstab:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;/swapfile none swap defaults 0 0&quot; &amp;gt;&amp;gt; /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Set the timezone&lt;/h4&gt;
&lt;p&gt;Install the &lt;a href=&quot;https://wiki.archlinux.org/title/Network_Time_Protocol_daemon&quot;&gt;Network Time Protocol&lt;/a&gt;
and enable it as daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S ntp
systemctl enable ntpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a symlink of the timezone:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generate &lt;code&gt;/etc/adjtime&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hwclock --systohc
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Network configuration&lt;/h4&gt;
&lt;p&gt;Install and enable network management daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S networkmanager
systemctl enable NetworkManager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So add a hostname to the machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo ThinkPad &amp;gt; /etc/hostname
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Remember that you can replace &lt;code&gt;ThinkPad&lt;/code&gt; with whatever you like.&lt;/p&gt;
&lt;p&gt;Add matching entries to &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1  localhost
::1     localhost
127.0.1.1  ThinkPad.localdomain ThinkPad
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Set the root passsword&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Create the main user&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;useradd -mG storage,wheel -s /bin/bash someone
passwd someone
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, change the &lt;code&gt;/etc/sudoers&lt;/code&gt; file according to the config that you want
to deal with &lt;code&gt;sudo&lt;/code&gt; command.&lt;/p&gt;
&lt;h4&gt;Create a initial ramdisk environment&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/mkinitcpio.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should the &lt;code&gt;HOOKS&lt;/code&gt; field with these things:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
HOOKS=(base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt lvm2 filesystems btrfs)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, recreate the &lt;code&gt;initramfs&lt;/code&gt;image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkinitcpio -p linux-zen
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Setup the boot manager&lt;/h3&gt;
&lt;h4&gt;Install &lt;code&gt;systemd-boot&lt;/code&gt; into the EFI system partition&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;bootctl install
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Configuring the loader&lt;/h4&gt;
&lt;p&gt;On &lt;code&gt;/boot/loader/loader.conf&lt;/code&gt;insert this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;default arch
timeout 10
console-mode max
editor no
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;Some details about the parameters:&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;default&lt;/code&gt;: default entry to select;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timeout&lt;/code&gt;: menu timeout in second, useful to allow people who have multiple
operating systems;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;console-mode&lt;/code&gt;: changes UEFI console mode;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;editor&lt;/code&gt;: whether to enable the kernel parameters editor or not. Strongly
recommended to set this option to no to avoid bypass root password and gain
root access.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h4&gt;Adding the loader&lt;/h4&gt;
&lt;p&gt;First install the &lt;a href=&quot;https://wiki.archlinux.org/title/microcode&quot;&gt;microcode&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S amd-ucode
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After it, insert on &lt;code&gt;/boot/loader/entries/arch.conf&lt;/code&gt; this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=$(blkid /dev/nvme0n1p2 -s UUID -o value)=cryptlvm rd.luks.options=discard root=/dev/mapper/vg-root resume=/dev/mapper/vg-root rootfstype=btrfs resume_offset=$(filefrag -v /swapfile | sed &apos;4q;d&apos; | awk &apos;{print $4}&apos; | cut -d&apos;.&apos; -f1) quiet nowatchdog splash rw
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Graphical environment&lt;/h3&gt;
&lt;h4&gt;Install the window manager&lt;/h4&gt;
&lt;p&gt;First of all, install &lt;a href=&quot;https://wiki.archlinux.org/title/xorg&quot;&gt;xorg&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S xorg-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, install the &lt;a href=&quot;https://wiki.archlinux.org/title/xmonad&quot;&gt;xmonad&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S xmonad xmonad-contrib
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Install a display manager&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S lightdm
systemctl enable lightdm
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Install a AUR helper&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -sri
cd .. &amp;amp;&amp;amp; rm -r yay
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Keyring&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S gnome-keyring seahorse
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Terminal&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S alacritty tmux
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Shell&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S fish
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Image manipulations&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S gimp inkscape
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NTFS&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S ntfs-3g
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Sound system&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;pacman -S pulseaudio alsa-utils pavucontrol alsamixer
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Other&lt;/h4&gt;
&lt;p&gt;In order to save the read and write cycles of the SSD and thus extend the lifetime of the SSD, the browser profile can be moved in RAM with profile-sync-daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S profile-sync-daemon
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, enable and activate the service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl --user enable psd --now
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;After installation&lt;/h2&gt;
&lt;h3&gt;Enable fstrim&lt;/h3&gt;
&lt;p&gt;First enable and start &lt;code&gt;fstrim&lt;/code&gt; timer. On Arch-based system you can do it running
this commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this, if you running with &lt;code&gt;LUKS&lt;/code&gt; encryption, you should add some things on
the Arch entry from systemd-boot, inside &lt;code&gt;/boot/loader/entries/arch.conf&lt;/code&gt;, add it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
options rd.luks.name=&amp;lt;UUID&amp;gt;=cryptlvm ... rd.luks.options=discard
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reboot the system. And now, you can check if it&apos;s running correctly executing this
command: &lt;code&gt;lsblk --discard&lt;/code&gt;. If has no-zero entries on &lt;code&gt;DISC-GRAN&lt;/code&gt; and &lt;code&gt;DISC-MAX&lt;/code&gt;
columns means TRIM is enabled.&lt;/p&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/Solid_state_drive#Periodic_TRIM&quot;&gt;Arch Linux: Periodic TRIM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://confluence.jaytaala.com/display/TKB/Enable+periodic+TRIM+-+including+on+a+LUKS+partition&quot;&gt;Enable periodic TRIM - including on a LUKS partition&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Disable &lt;code&gt;watchdog&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Append on your boot parameters (probably &lt;code&gt;/boot/loader/entries/arch.conf&lt;/code&gt;) the following option:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
options rd.luks.name=&amp;lt;UUID&amp;gt;=cryptlvm ... nowatchdog
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After it, you can &lt;strong&gt;optionally&lt;/strong&gt; disable the loading of the module responsible of
the hardware watchdog, too. Do it blacklisting the related module.&lt;/p&gt;
&lt;p&gt;Creating a &lt;code&gt;.conf&lt;/code&gt; inside &lt;code&gt;/etc/modprobe.d/&lt;/code&gt; and append a line for the module you
want to blacklist with &lt;code&gt;blacklist&lt;/code&gt; keyword. Here an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/modprobe.d/nowatchdog.conf
blacklist iTCO_wdt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/improving_performance#Watchdogs&quot;&gt;Arch Linux: Improving performance - Watchdogs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Troubleshooting&lt;/h2&gt;
&lt;h3&gt;Thinkpad T14 Gen 1 Brazillian keyboard layout&lt;/h3&gt;
&lt;p&gt;If you are using this installation on a &lt;strong&gt;Thinkpad T14 Gen 1&lt;/strong&gt; with a Brazillian
keyboard layout (ABNT2) like me, you should use this rule to turns the keyboard
usable. You should run this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setxkbmap -model thinkpad60 -layout br -variant anbt2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or just paste the &quot;text&quot; below on the following path: &lt;code&gt;/etc/X11/xorg.conf.d&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Section &quot;InputClass&quot;
 Identifier &quot;system-keyboard&quot;
 MatchIsKeyboard &quot;on&quot;
 Option &quot;XkbLayout&quot; &quot;br&quot;
 Option &quot;XkbModel&quot; &quot;thinkpad60&quot;
 Option &quot;XkbVariant&quot; &quot;abnt2&quot;
EndSection
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Other installation tutorials&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rememberYou/dotfiles/wiki/Installation&quot;&gt;GitHub: rememberYou/dotfiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://root.nix.dk/en/manjaro-cli-install/systemd-boot-luks-btrfs&quot;&gt;Manjaro UEFI using systemd-boot, LUKS and btrfs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nerdstuff.org/posts/2020/2020-004_arch_linux_luks_btrfs_systemd-boot/&quot;&gt;Installing Arch Linux with Btrfs, systemd-boot and LUKS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/clavelc/d598781ebd8257f48eee21959bede3bf&quot;&gt;Arch Linux, with LUKS, btrfs, systemd-homed, systemd-oomd, zram swap, encrypted DNS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/ansulev/7cdf38a3d387599adf9addd248b09db8&quot;&gt;Install Arch Linux with full encrypted btrfs subvolume inside luks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/EduardoRFS/a22047bc06b44117ee5d1359eb6ccede&quot;&gt;EduardoRFS&apos;s gist: arch-tutorial.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lunaryorn.com/arch-linux-with-luks-and-almost-no-configuration&quot;&gt;Arch Linux with LUKS and (almost) no configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://austinmorlan.com/posts/arch_linux_install/&quot;&gt;ARCH LINUX - UEFI, SYSTEMD-BOOT, LUKS, AND BTRFS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jlhinson.com/posts/2021-08-19-arch-linux-install&quot;&gt;Arch Linux install with BTRFS and encrypted root&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/User:M0p/LUKS_Root_on_Btrfs&quot;&gt;ArchWiki: User:M0p/LUKS Root on Btrfs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marcocetica.com/posts/arch_lvm_luks_guide/&quot;&gt;Install Arch Linux w/ LVM + LUKS + Systemd-boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>My first impressions with Neovim</title><link>https://noghartt.dev/blog/my-first-impressions-with-neovim/</link><guid isPermaLink="true">https://noghartt.dev/blog/my-first-impressions-with-neovim/</guid><pubDate>Tue, 18 Jun 2024 00:11:26 GMT</pubDate><content:encoded>&lt;p&gt;I consider myself a kind of heavy Emacs user. During some time, about 3
years, I was using Emacs as my daily driven tool for literally everything.&lt;/p&gt;
&lt;p&gt;I even used it as &lt;a href=&quot;https://github.com/ch11ng/exwm&quot;&gt;my desktop manager&lt;/a&gt; for some time.
And to be honest, I loved it. It&apos;s cool to have everything in one place, and
seeing all the pieces of the system interconnected, it&apos;s cool.&lt;/p&gt;
&lt;p&gt;But, I suffered some &lt;em&gt;skill issues&lt;/em&gt; when talking about a piece of software that, for me, is
important: LSPs. I spend too much time trying to debug performance issues related to
Emacs and LSP, and I was not able to find a solution to it, for large codebases it triggers
some I/O blocking issues that freeze the entire editor, this wasn&apos;t the ideal kind of experience
that I wanted. For that reason, I decided to switch to Neovim.&lt;/p&gt;
&lt;h2&gt;The first attempt&lt;/h2&gt;
&lt;p&gt;I&apos;m a real fan of editors who bring the ability to have my config and let me do it in a
&quot;declarative&quot; way. Neovim is a great example of that. Just put some code into your &lt;code&gt;init.vim&lt;/code&gt; (or &lt;code&gt;init.lua&lt;/code&gt;)
and take some motions. I appreciate it a lot.&lt;/p&gt;
&lt;p&gt;Then, I decided that on a weekend I would try to have a minimal configuration for Neovim and let it
be my daily driver for the rest of the next week. The idea was just a simple config to bring what I
consider essentials to my daily workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some keybindings to navigate between files, buffers, windows, and tabs.&lt;/li&gt;
&lt;li&gt;Some keybindings that improve my quality of life during the usage of Neovim.&lt;/li&gt;
&lt;li&gt;An LSP client to have the ability to use the language server of my choice, given all the languages that I try to use.&lt;/li&gt;
&lt;li&gt;A cool theme, because I want to be cute.&lt;/li&gt;
&lt;li&gt;Some kind of plugin manager, because I think that it&apos;s a great improvement to have it.&lt;/li&gt;
&lt;li&gt;A plugin that lets me easily know the keybindings of the editor, because I can&apos;t remember them all.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The selection of plugins&lt;/h2&gt;
&lt;p&gt;It was just like 10 plugins, being them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lazy.nvim&lt;/code&gt;, to manage the plugins.&lt;/li&gt;
&lt;li&gt;LSP support using &lt;code&gt;lsp-config&lt;/code&gt;, &lt;code&gt;mason.nvim&lt;/code&gt;, and &lt;code&gt;nvim-cmp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A theme based on Gruvbox.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;which-key.nvim&lt;/code&gt;, similar to the Emacs one, to have a list of all the keybindings that have been defined through the configuration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oil.nvim&lt;/code&gt;, to have a better experience navigating through files.&lt;/li&gt;
&lt;li&gt;I remapped by myself some keybindings to have a better motion experience using them, mainly for editor/window/file navigation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It was everything that I wanted, and I think that was the right decision because it gave me some great
experience trying to learn more about the native features of Neovim, mainly related to the Vim motions.&lt;/p&gt;
&lt;h2&gt;Setting up Neovim and documentation&lt;/h2&gt;
&lt;p&gt;I think that one great feature of Neovim is Lua. Seems to be a great, simple, but powerful language to write code. It has a familiar
syntax that can be easily learned if you have a background and don&apos;t need any tricks (that was one of my concerns with EmacsLisp, even though I like EL and Lisp in general).&lt;/p&gt;
&lt;p&gt;After you have done the right setup and installed at least the plugins related to Lua and their LSP, you can easily code all the
configurations to Neovim. For that, I suggest you use the &lt;a href=&quot;https://github.com/folke/neodev.nvim&quot;&gt;&lt;code&gt;neodev.nvim&lt;/code&gt;&lt;/a&gt; plugin, which
will help you to have a better experience with the configuration of Neovim.&lt;/p&gt;
&lt;p&gt;One aspect of Neovim that I missed a lot was the documentation. I don&apos;t know if is something related to my mental model, but
the &lt;code&gt;:help&lt;/code&gt; command from Neovim isn&apos;t great compared to the similar one from Emacs. Isn&apos;t easier to iterate through the documentation or
even iterate through a Lua code to understand if some piece of code is doing what I want, like executing a piece of the buffer or
putting a function into a REPL that can be easily used.&lt;/p&gt;
&lt;p&gt;Just in case, I know the existence of the &lt;code&gt;:lua&lt;/code&gt; command, but seems to be a bit limited through the developer experience to use it, I think
that is the most similar feature that we can have in Neovim to compare through the Emacs part. I need to test more the &lt;a href=&quot;https://github.com/Vigemus/iron.nvim&quot;&gt;&lt;code&gt;iron.nvim&lt;/code&gt;&lt;/a&gt;
to validate if it gives some kind of good developer experience at all.&lt;/p&gt;
&lt;p&gt;But, the thing that I was most during the first days was: documentation and some tooling to easily iterate to understand something
on Neovim.&lt;/p&gt;
&lt;p&gt;By the way, after I discovered the &lt;code&gt;Telescope help_tags&lt;/code&gt; command, turn made it easier to go through the documentation, it helped me a lot to understand
some of the concepts and read them. However, I&apos;m still a bit confused about some aspects of the navigation in the documentation.&lt;/p&gt;
&lt;h2&gt;Daily workflow and motions&lt;/h2&gt;
&lt;p&gt;In general, my experience using it as my daily editor was surprisingly good. I think that most of the time, it&apos;s more related to how
easily is to navigate through the files and have some kind of ergonomics to do it. For the first days, I was struggling and being a little upset
because the learning curve was a bit steep for motions, I was using the Neovim with a cheat sheet to get at least the basic motions, so I don&apos;t look
like a gorilla using keyboards and, after a while, I was able to easily use all the simple motions that I needed to do, like those to navigate,
to move around the editor, to move to the next/previous line, to move to the next/previous word, etc.&lt;/p&gt;
&lt;p&gt;I think that I miss some specific micro-features that I found in other editors, like the ability to move to the previous/next line when hitting the
&lt;code&gt;j&lt;/code&gt; or &lt;code&gt;k&lt;/code&gt; key at the start or end of the line, or the ability to move the line up or down following my cursor, etc. I already saw some custom
implementations of all these features, so I think that isn&apos;t a big problem, I&apos;ll just need to implement it by myself.&lt;/p&gt;
&lt;p&gt;But, I still struggle with some aspects of the editor, like the substitutions, the search and replace, the undo/redo, etc. I&apos;ll need to better learn how
they work to understand it and apply it in the right way easily.&lt;/p&gt;
&lt;h2&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;In general, it was a great experience to use Neovim as my daily driver. It was easier than I expected, and I think that I&apos;m going to stick with it.
Although I&apos;m still hitting some issues, I think that all the pros of Neovim are worth it, having a better experience with the editor
pay by itself.&lt;/p&gt;
&lt;p&gt;If you want to see the configuration of Neovim that I used, you can &lt;a href=&quot;https://github.com/noghartt/dotnvim&quot;&gt;check it out here&lt;/a&gt;. Feel free to use it as a base
for your configuration, and if you have any questions, feel free to ask me on &lt;a href=&quot;https://twitter.com/noghartt&quot;&gt;Twitter&lt;/a&gt; or send me an &lt;a href=&quot;mailto:hi@noghartt.dev&quot;&gt;email&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>RSS and why I love it</title><link>https://noghartt.dev/blog/rss-and-why-i-love-it/</link><guid isPermaLink="true">https://noghartt.dev/blog/rss-and-why-i-love-it/</guid><pubDate>Wed, 15 May 2024 01:45:37 GMT</pubDate><content:encoded>&lt;p&gt;Inspired by some discussions through Twitter/X over the last few days, I decided to write
about RSS and why I love them. I think it&apos;s a great technology that few people know
about and I think it&apos;s worth learning more about it.&lt;/p&gt;
&lt;p&gt;One of the greatest things that the Internet could bring to us is data consumption.
Do you already ask yourself how much data we consume compared with the past?
How easy is it to just type something into a search engine and get a lot of information about it?
Is just awesome.&lt;/p&gt;
&lt;p&gt;But, with great power comes great responsibility. And with a lot of information comes a lot of noise.
I&apos;m a person who likes to read blogs and learn new things, it&apos;s a great hobby and it&apos;s cool
to see other people sharing their thoughts about something, being tech or not. And by that fact, I,
being a lazy person, was thinking so hard about how to keep up with all the blogs that I like to read.&lt;/p&gt;
&lt;p&gt;And then, I found RSS feeds. I would say a cool invention from the 2000s that is still more useful for us
nowadays than it was in the past. What a great idea would be just to aggregate every blog that you like to read
into one place and just read it from there. Simple, but you can see how amazing is it?&lt;/p&gt;
&lt;p&gt;The ability to have all those blogs in one place, ensuring that every new update will be there for
easy access, being notified about it and also being able to read it offline is just amazing. And that&apos;s why
I love RSS feeds. It&apos;s a simple technology that is still useful for us nowadays and I hope it will be for a long time.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/rss-feeds.png&quot; alt=&quot;NetNewsWire&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is my RSS feed reader, NetNewsWire. On that, I have all the things I like to follow: blogs, podcasts, YouTube channels,
newsletters, etc. I have more than 100 feeds there and I can&apos;t imagine my life without it. All links that you can find
on &lt;a href=&quot;/bookmarks&quot;&gt;bookmarks&lt;/a&gt; come from that feed reader.&lt;/p&gt;
&lt;p&gt;Being an ADHD person, I think that having this kind of tool is helpful for me. I let my NetNewsWire open all the time
and just read the things that I like when I have time. It&apos;s a great way to keep up with the things that I like to read and
also a great way to keep my mind busy with something that I like.&lt;/p&gt;
&lt;p&gt;I hope you enjoyed this post and I hope you can give a try to RSS feeds. It&apos;s a great technology that is still useful for us.&lt;/p&gt;
&lt;p&gt;If you would like to follow my blog, you can use my &lt;a href=&quot;/rss.xml&quot;&gt;RSS feed&lt;/a&gt; that I have here.
I am sharing my OPML file (the same one you saw in the image above), if you want some
suggestions of cool blogs to follow, you can get them &lt;a href=&quot;https://gist.github.com/noghartt/53e05e6bccb41e9fd69e24fa36ec65ce&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Set up Nix on macOS using flakes, nix-darwin and home-manager</title><link>https://noghartt.dev/blog/set-up-nix-on-macos-using-flakes-nix-darwin-and-home-manager/</link><guid isPermaLink="true">https://noghartt.dev/blog/set-up-nix-on-macos-using-flakes-nix-darwin-and-home-manager/</guid><pubDate>Sun, 03 Mar 2024 19:37:49 GMT</pubDate><content:encoded>&lt;p&gt;About three years ago, I started using NixOS on my personal laptop. In those days, I
needed a config that would allow me to have a stable system, that could be reproducible
over all my machines, and that would allow me to have a development environment that would
be easy to maintain and to share with others. NixOS comes to fit all these requirements.&lt;/p&gt;
&lt;p&gt;But, since I started using a MacBook Pro (2022), I do not feel the necessity of using the
Nix package manager, since I can use Homebrew to install all the packages that I need and
have some kind of reproducibility with shell scripts. But, for some needs, I would like to
use Nix again on my macOS now, and this blog post will be about how to set up Nix on macOS
like me.&lt;/p&gt;
&lt;h2&gt;Installing Nix on macOS&lt;/h2&gt;
&lt;p&gt;Installing Nix on macOS is easy. You can use the following command to install Nix on your
machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl --proto &apos;=https&apos; --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command installs the Nix package manager based on the &lt;a href=&quot;https://github.com/DeterminateSystems/nix-installer&quot;&gt;DeterminateSystem/nix-installer&lt;/a&gt;,
based on the explanation by the &lt;a href=&quot;https://zero-to-nix.com/concepts/nix-installer&quot;&gt;Zero to Nix&lt;/a&gt;, it gives
better error messages, an installation plan (like Terraform), and other cool features that bring
a better installation experience for you.&lt;/p&gt;
&lt;p&gt;Just follow the step by step of the installation flow and everything will be fine.&lt;/p&gt;
&lt;h2&gt;Creating the flake file&lt;/h2&gt;
&lt;p&gt;After installing Nix, you can create a &lt;code&gt;flake.nix&lt;/code&gt; file that will be the entry point for your
entire Nix configuration on your machine. This file will be used to define the packages that
you want to install, the system configuration, and the home-manager configuration.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  description = &quot;Nix configuration&quot;;

  inputs = {
    nixpkgs.url = &quot;github:NixOS/nixpkgs&quot;;

    nix-darwin.url = &quot;github:lnl7/nix-darwin/master&quot;;
    nix-darwin.inputs.nixpkgs.follows = &quot;nixpkgs&quot;;

    home-manager.url = &quot;github:nix-community/home-manager&quot;;
    home-manager.inputs.nixpkgs.follows = &quot;nixpkgs&quot;;
  };

  outputs = inputs @ { self, ... }: let
    nixpkgsConfig = {
      config.allowUnfree = true;
    };
  in {

  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the basic structure of my &lt;code&gt;flake.nix&lt;/code&gt;, it defines all the inputs that I will need
to use in my configuration, they are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nixpkgs&lt;/code&gt;: The main NixOS/Nixpkgs repository, that will be used to define the packages
that I want to install on my machine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nix-darwin&lt;/code&gt;: The nix-darwin repository. It brings all modules to configure your macOS
system using a declarative way.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;home-manager&lt;/code&gt;: The home-manager repository. It brings all modules to configure your
user environment using a declarative way.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Configuring nix-darwin&lt;/h2&gt;
&lt;p&gt;After creating the &lt;code&gt;flake.nix&lt;/code&gt; file, you can configure the &lt;code&gt;nix-darwin&lt;/code&gt; module. You will
need to create a &lt;code&gt;darwinConfigurations&lt;/code&gt; field on the outputs of your &lt;code&gt;flake.nix&lt;/code&gt; file, and
add the hostname of your machine with the &lt;code&gt;darwinSystem&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  # ...

  outputs = inputs @ { self, nix-homebrew, home-manager ... }: let
    nixpkgsConfig = {
      config.allowUnfree = true;
    };
  in {
    darwinConfigurations = let
      inherit (inputs.nix-darwin.lib) darwinSystem;
    in {
      machine = darwinSystem {
        system = &quot;aarch64-darwin&quot;;

        specialArgs = { inherit inputs; };

        modules = [
          ./hosts/mbp/configuration.nix
          inputs.home-manager.darwinModules.home-manager
          {
            nixpkgs = nixpkgsConfig;

            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.noghartt = import ./home/home.nix;
          }
        ];
      };
    };
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In that case, what I&apos;m doing is: creating a new configuration called &lt;code&gt;machine&lt;/code&gt; on the &lt;code&gt;darwinConfigurations&lt;/code&gt;
systems, and declaring some specific properties of that given system, they are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system of that machine is &lt;code&gt;aarch64-darwin&lt;/code&gt;, which is the system of the new Apple Silicon
Macs (MacBook Pro M1).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;specialArgs&lt;/code&gt; field is used to pass the inputs to the &lt;code&gt;darwinSystem&lt;/code&gt; function. All modules
are functions that accept some arguments, the &lt;code&gt;specialArgs&lt;/code&gt; field lets you pass new arguments
for all these imported modules.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;modules&lt;/code&gt; field is used to define the modules that will be used to configure the system.
In that case, I&apos;m using the &lt;code&gt;configuration.nix&lt;/code&gt; file to define my system configuration, the
&lt;code&gt;home-manager&lt;/code&gt; module to configure the user environment, the &lt;code&gt;homebrew.nix&lt;/code&gt; file to install
all the packages that I want to install using Homebrew, and the &lt;code&gt;home.nix&lt;/code&gt; file to configure
my user environment using home-manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Configuring my system&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;configuration.nix&lt;/code&gt; file is used to define some system configurations related to my
MacBook Pro, like user home dir, some extra options related to Nix binaries, and other system-related configurations that you want to declare. In my case, I wrote the following &lt;code&gt;configuration.nix&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_:

{
  services.nix-daemon.enable = true;

  users.users.noghartt = {
    home = &quot;/Users/noghartt&quot;;
  };

  nix.extraOptions = &apos;&apos;
    auto-optimise-store = true
    experimental-features = nix-command flakes
    extra-platforms = x86_64-darwin aarch64-darwin
  &apos;&apos;;

  homebrew = {
    enable = true;

    casks = [
      &quot;discord&quot;
      &quot;visual-studio-code&quot;
    ];
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Configuring the home-manager&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;home.nix&lt;/code&gt; file is used to define the user environment configurations using the home-manager.
In my case, I wrote just a simple &lt;code&gt;home.nix&lt;/code&gt; file that installs some packages for me. It is
like a &lt;code&gt;configuration.nix&lt;/code&gt; file but for the user environment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ pkgs, ... }:

{
  home.stateVersion = &quot;23.11&quot;;

  home.packages = with pkgs; [
    htop
    curl
    coreutils
    jq
  ];

  programs.zsh = {
    enable = true;

    shellAliases = {
      ls = &quot;ls --color&quot;;
    };
  };
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that configuration, I can install the initial packages that I want to use on my
machine using Nix, and gives me the powerful ability of reproducibility in a declarative way.&lt;/p&gt;
&lt;h2&gt;Building and activating the configuration&lt;/h2&gt;
&lt;p&gt;After creating all the files, you can build and activate the configuration using the following.
You just need to run two specific commands to build and activate the configuration on your
machine:&lt;/p&gt;
&lt;h3&gt;1. Building the configuration&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;nix build .#darwinConfigurations.machine.config.system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will build the configuration of your machine targeting the &lt;code&gt;darwinConfigurations.machine&lt;/code&gt;
outputs. Do not forget of changing the &lt;code&gt;machine&lt;/code&gt; of the given name of your system configuration.&lt;/p&gt;
&lt;h3&gt;2. Activating the configuration&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;./result/sw/bin/darwin-rebuild switch --flake .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will activate the configuration of your machine using the &lt;code&gt;darwin-rebuild&lt;/code&gt; command. It will
switch the configuration of your machine to the new configuration that you have built.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this blog post, I showed how to set up Nix on macOS using flakes, nix-darwin, and home-manager
like I do. I hope that this blog post can help you set up your configuration and let you
use Nix on your machine too.&lt;/p&gt;
&lt;p&gt;I really love how the Nix package manager works, and I think that it is a great tool to use
on your machine since it gives you a lot of power to manage your system and your user environment.
You really should give it a try.&lt;/p&gt;
&lt;p&gt;If you want to see my configuration, you can check it out on my &lt;a href=&quot;https://github.com/noghartt/nixcfg&quot;&gt;repository&lt;/a&gt;,
it&apos;s all open source, feel free to use it as a base for your configuration if you want.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to ask me on &lt;a href=&quot;https://twitter.com/noghartt&quot;&gt;Twitter&lt;/a&gt; or send me an &lt;a href=&quot;mailto:hi@noghartt.dev&quot;&gt;email&lt;/a&gt;. I will be glad
to help you with your doubts.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2023/02/28/some-notes-on-using-nix/&quot;&gt;Some notes on using Nix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sandstorm.de/de/blog/post/my-first-steps-with-nix-on-mac-osx-as-homebrew-replacement.html&quot;&gt;My first steps with Nix on Mac OSX as Homebrew replacement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.6nok.org/how-i-use-nix-on-macos/&quot;&gt;How I use Nix on macOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050&quot;&gt;Setup nix, nix-darwin, and home-manager from scratch on MacBook M1 Pro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Misterio77/nix-starter-configs&quot;&gt;Nix Starter Config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Implementing Simple Paxos Consensus Algorithm With Rust</title><link>https://noghartt.dev/blog/paxos-made-simple-with-rust/</link><guid isPermaLink="true">https://noghartt.dev/blog/paxos-made-simple-with-rust/</guid><pubDate>Mon, 12 Feb 2024 11:55:28 GMT</pubDate><content:encoded>&lt;h2&gt;What Is Consensus?&lt;/h2&gt;
&lt;p&gt;I would say that one of the core properties of a system is the agreement on which data
are right at a given moment.&lt;/p&gt;
&lt;p&gt;At that moment, one of the more important aspects of a distributed system shows up:
the consensus. Where every participant agrees on a single state, even if some actor
fails.&lt;/p&gt;
&lt;p&gt;Some use cases where consensus brings a strong advantage are network agreement in a
server cluster, database replicati      ons, and even in blockchain networks.&lt;/p&gt;
&lt;h2&gt;The Simple Paxos&lt;/h2&gt;
&lt;p&gt;The Simple Paxos algorithm is the most simple implementation of the Paxos Protocol family.
As presented by Leslie Lamport on the &lt;a href=&quot;https://lamport.azurewebsites.net/pubs/lamport-paxos.pdf&quot;&gt;The Part-Time Parliament&lt;/a&gt;
and &lt;a href=&quot;https://lamport.azurewebsites.net/pubs/paxos-simple.pdf&quot;&gt;Paxos Made Simple&lt;/a&gt;,
the idea of the Simple Paxos is simple:&lt;/p&gt;

&lt;li&gt;Your node can assume 3 different roles: &lt;em&gt;proposers&lt;/em&gt;, &lt;em&gt;acceptors&lt;/em&gt; and &lt;em&gt;learners&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Your node can be all these roles at the same time.&lt;/li&gt;
&lt;li&gt;An acceptor will accept the first value that is received as a proposal.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;proposer&lt;/em&gt; will receive a promise from every &lt;em&gt;acceptor&lt;/em&gt;, that promise let
the &lt;em&gt;proposer&lt;/em&gt; knows that the node will accept the proposed value.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;proposer&lt;/em&gt; reach the &lt;em&gt;quorum&lt;/em&gt;, that is, the majority, when receive a promise
of $N/2 + 1$ where $N$ is the number of nodes in the system.&lt;/li&gt;
&lt;li&gt;After reach the &lt;em&gt;quorum&lt;/em&gt;, the &lt;em&gt;learners&lt;/em&gt; will receive the accepted value from
the &lt;em&gt;acceptors&lt;/em&gt;. The &lt;em&gt;learners&lt;/em&gt; will put the accepted value into their state
machines.&lt;/li&gt;

&lt;p&gt;&lt;img src=&quot;/assets/paxos-sequence-diagram.png&quot; alt=&quot;Paxos Sequence Diagram&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(This is a simple sequence diagram coming from Wikipedia, but it&apos;s a good representation)&lt;/p&gt;
&lt;h3&gt;Preparing the proposal for a new value&lt;/h3&gt;
&lt;p&gt;A &lt;em&gt;proposer&lt;/em&gt; is the node that will propose a new value to reach the consensus
around their system. In this case, each proposal follows this pattern: &lt;code&gt;(id, v)&lt;/code&gt;,
where the &lt;code&gt;id&lt;/code&gt; is an incrementally natural number, and &lt;code&gt;v&lt;/code&gt; is the proposed value,
for our implementation, we will assume &lt;code&gt;v&lt;/code&gt; as a string.&lt;/p&gt;
&lt;p&gt;First things first. We need to start our server. In this case, using Rust, I will
use Axum to do all the work for me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use Axum::{
    routing::{get, post},
    Router,
    http::StatusCode,
    extract::{State, Json}
};
use clap::Parser;
use serde::{Serialize, Deserialize};
use tokio::sync::Mutex;

type Ledger = HashMap&amp;lt;Id, Value&amp;gt;;
struct AppState {
    node: Node,
    nodes: Arc&amp;lt;Mutex&amp;lt;Vec&amp;lt;Node&amp;gt;&amp;gt;&amp;gt;,
    acceptor: Arc&amp;lt;Mutex&amp;lt;Acceptor&amp;gt;&amp;gt;,
    proposer: Arc&amp;lt;Mutex&amp;lt;Proposer&amp;gt;&amp;gt;,
    ledger: Arc&amp;lt;Mutex&amp;lt;Ledger&amp;gt;&amp;gt;,
}

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    #[arg(long)]
    id: u64,
    #[arg(short, long)]
    port: String,
}

#[tokio::main]
async fn main() {
    let args = Args::parse();
    let port = args.port;
    let node_id = args.id;

    let node_http_addr = format!(&quot;0.0.0.0:{}&quot;, port);

    println!(&quot;Starting new node: http://{}&quot;, node_http_addr);

    let node = Node::new(node_id, node_http_addr.parse().unwrap());
    let state = AppState {
        node,
        nodes: Arc::new(Mutex::new(Vec::new())),
        acceptor: Arc::new(Mutex::new(Acceptor::default())),
        proposer: Arc::new(Mutex::new(Proposer::new())),
        ledger: Arc::new(Mutex::new(HashMap::new())),
    };

    let app = Router::new()
        .route(&quot;/prepare&quot;, post(prepare))
        .route(&quot;/handle-prepare&quot;, post(handle_prepare))
        .with_state(state);

    let listener = tokio::net::TcpListener::bind(node_http_addr).await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

#[derive(Clone, Debug)]
struct Proposer {
    pub id: u64,
}

impl Proposer {
    pub fn new() -&amp;gt; Self {
        Self {
            id: 0,
        }
    }

    pub async fn prepare(&amp;amp;mut self, state: &amp;amp;AppState, value: String) -&amp;gt; Result&amp;lt;Proposal, String&amp;gt; {
      todo!()
    }

    pub async fn propose(&amp;amp;self, state: &amp;amp;AppState, propose: &amp;amp;Proposal) -&amp;gt; Result&amp;lt;(), String&amp;gt; {
      todo!()
    }
}

#[derive(Clone, Debug, Default)]
struct Acceptor {
    pub last_proposal_number: u64,
    pub accepted_proposal: Option&amp;lt;Propose&amp;gt;,
}

#[derive(Serialize, Deserialize, Debug)]
struct Proposal {
    pub id: u64,
    pub value: Option&amp;lt;String&amp;gt;,
}

async fn prepare() -&amp;gt; () {
  todo!()
}

async fn handle_prepare() -&amp;gt; () {
  todo!()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we have a server running on the port that we want. You can test it by running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cargo run -- --id 1 --port 3000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will implement the proposer logic on the &lt;code&gt;/prepare&lt;/code&gt; endpoint. The &lt;em&gt;proposer&lt;/em&gt;
will send a prepare message to all &lt;em&gt;acceptor&lt;/em&gt; messages and wait
for the promises.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async fn prepare(State(state): State&amp;lt;AppState&amp;gt;, value: String) -&amp;gt; (StatusCode, String) {
    let mut proposer = state.proposer.lock().await;
    let proposal = match proposer.prepare(&amp;amp;state, value).await {
        Err(e) =&amp;gt; return (StatusCode::BAD_REQUEST, e.clone()),
        Ok(proposal) =&amp;gt; proposal,
    };

    todo!()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this first phase, we will only send the prepare message to all acceptors. The
prepare message is a simple message with the &lt;code&gt;id&lt;/code&gt; of the proposal. The acceptor will
receive this message and will send a promise to the proposer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;impl Proposer {
    // ...

    pub async fn prepare(&amp;amp;mut self, state: &amp;amp;AppState, value: String) -&amp;gt; Result&amp;lt;Proposal, String&amp;gt; {
        let client = Client::new();

        self.id += 1;

        let nodes = state.nodes.lock().await;
        let reqs = nodes.iter().map(|node| {
            client.post(format!(&quot;http://{}/handle-prepare&quot;, node.addr))
            .json(&amp;amp;self.id)
            .send()
        });

        let responses = futures::future::join_all(reqs).await;

        let mut promises = Vec::with_capacity(responses.len());

        for response in responses.into_iter().flatten() {
            promises.push(response.json::&amp;lt;HandleProposalPayload&amp;gt;().await.unwrap());
        }

        let quorum = (nodes.len() / 2) + 1;

        if promises.len() &amp;lt; quorum {
            return Err(String::from(&quot;Proposal does not receive promises of the entire quorum&quot;));
        }

        let accepted_promise = promises
            .into_iter()
            .filter(|promise| promise.value.is_some())
            .max_by_key(|promise| match &amp;amp;promise.value {
                None =&amp;gt; 0,
                Some(value) =&amp;gt; value.id,
            });

        // Sorry, I&apos;m not proud of it, but it&apos;s the best that I can do for now. :(
        // Feel free to improve it (PLEASE!).
        let value = match accepted_promise {
            None =&amp;gt; Some(value),
            Some(payload) =&amp;gt; {
                match payload.value {
                    None =&amp;gt; Some(value),
                    Some(proposal) =&amp;gt; {
                        match proposal.value {
                            None =&amp;gt; Some(value),
                            b =&amp;gt; b,
                        }
                    },
                }
            }
        };

        let proposal = Proposal { id: self.id, value };

        Ok(proposal)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We implement the &lt;code&gt;proposer.prepare&lt;/code&gt; method to send the prepare message to all acceptors. What
this is doing is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Calling the &lt;code&gt;/handle-prepare&lt;/code&gt; endpoint of all nodes in the system.&lt;/li&gt;
&lt;li&gt;Waiting for the promises of the acceptors.&lt;/li&gt;
&lt;li&gt;Checking if the proposer received the quorum of promises.&lt;/li&gt;
&lt;li&gt;If the proposer received the quorum, it will check if there is a value that was accepted
by the acceptors. If there is, the proposer will use this value as the proposed value. If
not, the proposer will use the value that it wants to propose.&lt;/li&gt;
&lt;li&gt;Return the proposal.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Receiving the prepared value and sending the promise&lt;/h3&gt;
&lt;p&gt;Cool. We&apos;re coming to what we can call the phase &lt;code&gt;1b&lt;/code&gt;. The &lt;em&gt;acceptor&lt;/em&gt; will receive
the prepare message and need to send a promise if everything is OK. In this case, which
things do we need to check?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the proposal number is greater than the last proposal number that the acceptor
received.&lt;/li&gt;
&lt;li&gt;If the acceptor already accepted a value, if yes, it needs to send the accepted
value to the &lt;em&gt;proposer&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#[derive(Serialize, Deserialize, Debug)]
struct HandleProposalPayload {
    error: Option&amp;lt;String&amp;gt;,
    value: Option&amp;lt;Proposal&amp;gt;,
}

async fn handle_prepare(State(state): State&amp;lt;AppState&amp;gt;, proposal_id: String) -&amp;gt; (StatusCode, Json&amp;lt;HandleProposalPayload&amp;gt;) {
    let proposal_id: u64 = proposal_id.parse().unwrap();
    let mut acceptor = state.acceptor.lock().await;

    if proposal_id &amp;lt;= acceptor.last_proposal_number {
        let payload = HandleProposalPayload {
            error: Some(String::from(&quot;The proposal ID is lesser than the last accepted proposal number&quot;)),
            value: None,
        };
        return (StatusCode::BAD_REQUEST, Json(payload));
    }

    if acceptor.accepted_proposal.is_some() &amp;amp;&amp;amp; acceptor.last_proposal_number == proposal_id {
        let value = acceptor.accepted_proposal.clone();
        let payload = HandleProposalPayload {
            error: None,
            value: Some(Proposal { id: proposal_id, value }),
        };
        return (StatusCode::OK, Json(payload));
    }

    acceptor.last_proposal_number = proposal_id;

    let payload = HandleProposalPayload {
        error: None,
        value: Some(Proposal { id: proposal_id, value: None }),
    };

    (StatusCode::OK, Json(payload))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We improved the &lt;code&gt;handle-prepare&lt;/code&gt; function to handle all the logic of the acceptor
receiving the prepare message, instead of just a &lt;code&gt;todo!()&lt;/code&gt;. If everything is OK,
the acceptor will return a promise to the proposer. If not, it will return an error
message.&lt;/p&gt;
&lt;h3&gt;Receiving the promise and handling the acceptance message&lt;/h3&gt;
&lt;p&gt;Now that the proposer received the promise, we need to start with the phase &lt;code&gt;2a&lt;/code&gt;.
The proposer will send the accept message to all acceptors. The accept message needs
to contain the proposal and their identifier.&lt;/p&gt;
&lt;p&gt;Then, the first part of our implementation will be improving the implementation of our
&lt;code&gt;Proposer&lt;/code&gt; struct. In this case, we will need to add a new function called &lt;code&gt;propose&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#[derive(Serialize, Deserialize, Debug)]
struct HandleAcceptPayload {
    error: Option&amp;lt;String&amp;gt;,
    value: Option&amp;lt;Proposal&amp;gt;,
}

impl Proposer {
    // ...

    pub async fn propose(&amp;amp;self, state: &amp;amp;AppState, proposal: &amp;amp;Proposal) -&amp;gt; Result&amp;lt;(), String&amp;gt; {
        let client = Client::new();
        let nodes = state.nodes.lock().await;

        let reqs = nodes.iter().map(|node| {
            client.post(format!(&quot;http://{}/handle-accept&quot;, node.addr))
                .json(&amp;amp;proposal)
                .send()
        });

        let responses = futures::future::join_all(reqs).await;

        let mut accepted_promises = Vec::with_capacity(responses.len());

        for response in responses.into_iter().flatten() {
            accepted_promises.push(response.json::&amp;lt;HandleAcceptPayload&amp;gt;().await.unwrap());
        }

        let quorum = (nodes.len() / 2) + 1;

        if accepted_promises.len() + 1 &amp;lt; quorum {
            return Err(String::from(&quot;Proposal not accepted by majority&quot;));
        }

        Ok(())
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;propose&lt;/code&gt; function will send the accept message to all acceptors and wait for the
acceptance of the proposal. If the proposer receives the quorum of acceptances, it will
return &lt;code&gt;Ok(())&lt;/code&gt;. If not, it will return an error message.&lt;/p&gt;
&lt;p&gt;Now, we need to implement the &lt;code&gt;/handle-accept&lt;/code&gt; endpoint to handle the accept message.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async fn handle_accept(State(state): State&amp;lt;AppState&amp;gt;, propose: Json&amp;lt;Proposal&amp;gt;) -&amp;gt; (StatusCode, Json&amp;lt;HandleAcceptPayload&amp;gt;) {
    let mut acceptor = state.acceptor.lock().await;
    if acceptor.last_proposal_number != propose.id {
        let payload = HandleAcceptPayload {
            error: Some(String::from(&quot;Node received a proposal with a proposal ID different!&quot;)),
            value: None,
        };
        return (StatusCode::BAD_REQUEST, Json(payload));
    }

    acceptor.accepted_proposal = propose.value.clone();

    let payload = HandleAcceptPayload {
        error: None,
        value: Some(Proposal { id: propose.id, value: propose.value.clone() }),
    };

    (StatusCode::OK, Json(payload))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we have the acceptor receiving the accept message and handling it. If everything
is OK, the acceptor will accept the proposal and return an acceptance message to the
proposer.&lt;/p&gt;
&lt;p&gt;We will need to add the &lt;code&gt;proposer.propose&lt;/code&gt; call on the &lt;code&gt;/prepare&lt;/code&gt; endpoint.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async fn prepare(State(state): State&amp;lt;AppState&amp;gt;, value: String) -&amp;gt; (StatusCode, String) {
    // ...

    match proposer.propose(&amp;amp;state, &amp;amp;proposal).await {
        Err(e) =&amp;gt; (StatusCode::BAD_REQUEST, e),
        Ok(_) =&amp;gt; {
            let client = Client::new();
            let nodes = state.nodes.lock().await;

            let reqs = nodes.iter().map(|node| {
                client.post(format!(&quot;http://{}/handle-learn&quot;, node.addr))
                    .json(&amp;amp;proposal)
                    .send()
            });

            futures::future::join_all(reqs).await;

            (StatusCode::OK, String::from(&quot;Proposal accepted by the majority!&quot;))
        },
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Removing that old &lt;code&gt;todo!()&lt;/code&gt; and putting the &lt;code&gt;proposer.propose&lt;/code&gt; call on the &lt;code&gt;/prepare&lt;/code&gt;,
we have the proposer sending the accept message to all acceptors and waiting for
the acceptance of the proposal. If the proposer receives the quorum of acceptances,
it will send the accepted value to all learners.&lt;/p&gt;
&lt;h3&gt;Learning the accepted value&lt;/h3&gt;
&lt;p&gt;The last part of our implementation is the &lt;code&gt;/handle-learn&lt;/code&gt; endpoint. The learner
will receive the accepted value and put it into their state machines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async fn handle_learn(State(state): State&amp;lt;AppState&amp;gt;, payload: Json&amp;lt;Proposal&amp;gt;) -&amp;gt; (StatusCode, ()) {
    let mut ledger = state.ledger.lock().await;
    match &amp;amp;payload.value {
        None =&amp;gt; ledger.insert(payload.id, String::from(&quot;&quot;)),
        Some(v) =&amp;gt; ledger.insert(payload.id, v.clone()),
    };
    (StatusCode::OK, ())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After learning the accepted value, the learner will put it into their state machines. And
then we have the consensus around the system. The &lt;em&gt;acceptor&lt;/em&gt; will
send the accepted value to the &lt;em&gt;learner&lt;/em&gt;, but I think it&apos;s easier to implement
just sending the accepted value to the &lt;em&gt;learner&lt;/em&gt; via &lt;em&gt;proposer&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is the most simple implementation of Paxos Protocol consensus algorithm.
You have some variants that brings some improvements to the Paxos, like the
Multi-Paxos and EPaxos. All of these have some properties that are best for
specific use cases.&lt;/p&gt;
&lt;p&gt;If you want to see the repo with the implementation of this algorithm, you can
access it &lt;a href=&quot;https://github.com/noghartt/paxos-from-scratch&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://github/hnrbs&quot;&gt;hnrbs&lt;/a&gt;, one of my inspirations to write this
code and learn more about Paxos and consensus.
You can see &lt;a href=&quot;https://github.com/hnrbs/paxos&quot;&gt;his implementation here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lamport.azurewebsites.net/pubs/lamport-paxos.pdf&quot;&gt;The Part-Time Parliament&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lamport.azurewebsites.net/pubs/paxos-simple.pdf&quot;&gt;Paxos Made Simple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Database Internals&lt;/li&gt;
&lt;li&gt;Designing Data-Intensive Applications&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Embrace The Chaos of Your Life</title><link>https://noghartt.dev/blog/embrace-the-chaos-of-your-life/</link><guid isPermaLink="true">https://noghartt.dev/blog/embrace-the-chaos-of-your-life/</guid><pubDate>Sun, 04 Feb 2024 15:23:35 GMT</pubDate><content:encoded>&lt;p&gt;The last weeks were too hard for me. I need to spend too much time doing things
in my personal life and ensure that I can bring good work to my professional life.&lt;/p&gt;
&lt;p&gt;For me, when this happens, there are always difficult moments. These moments are
always complicated because they impacted me in different areas of my life, which
generated a vicious cycle of bad moments and anxiety.&lt;/p&gt;
&lt;p&gt;But, the last time that this happened, in the same scenario, I learned a new aspect
of life that hadn&apos;t clicked for me yet, but it&apos;s a too simple idea that someone can ask:
&quot;Dude, it&apos;s too obvious. Why in the hell you didn&apos;t understand it before?&quot;. And my
answer would be: I don&apos;t know.&lt;/p&gt;
&lt;p&gt;You need to learn to embrace the chaos happening in your life and use it as a motion to
stay on track with the things you need to do. As everyone one day said, life is like a
rollercoaster with ups and downs, and you can&apos;t avoid the down moments of your life.
What matters is how you approach them.&lt;/p&gt;
</content:encoded></item><item><title>Increasing Your Friction Area</title><link>https://noghartt.dev/blog/increasing-your-friction-area/</link><guid isPermaLink="true">https://noghartt.dev/blog/increasing-your-friction-area/</guid><pubDate>Sun, 21 Jan 2024 14:39:29 GMT</pubDate><content:encoded>&lt;p&gt;One of the best ways to grow in your life, in any aspect, is by increasing your
exposed friction area to experiences. What I call friction area is the &lt;em&gt;&quot;surface&quot;&lt;/em&gt;
that will be exposed to the reactions you do.&lt;/p&gt;
&lt;p&gt;Everything you do in your day compounds your friction area, and everything has feedback.
If you let yourself do more things, you&apos;ll iterate more over their reactions.&lt;/p&gt;
&lt;p&gt;With a bigger surface, you compound what things will happen to you. It&apos;s a way to control
your life thinking in the long-term game. When you compose your surface area with good actions,
you will be more likely to receive positive feedback.&lt;/p&gt;
&lt;p&gt;As Sibelius Seraphini said in the article: &lt;a href=&quot;https://sibelius.substack.com/p/how-to-become-a-senior-engineer-faster&quot;&gt;How to become a Senior engineer faster?&lt;/a&gt;,
if you want to grow faster in your career, you need to say &quot;Yes&quot; to every new opportunity.
It&apos;s a way to let yourself live more experiences. With more experiences, you grow faster, and
when you grow faster, you&apos;ll live better experiences. You increased your friction area, and you&apos;re
receiving more positive feedback. Positive feedback loops compound.&lt;/p&gt;
&lt;p&gt;When Shawn &quot;swyx&quot; Wang said on &lt;a href=&quot;https://www.swyx.io/create-luck&quot;&gt;How to Create Luck&lt;/a&gt;, what
I called the friction area can be called the &quot;luck surface area&quot; too. It&apos;s the same idea. It&apos;s
more about how you&apos;re building habits and a routine that lets you create a strong friction
area that brings positive feedback for you.&lt;/p&gt;
&lt;p&gt;The idea of &quot;friction area&quot; is a way to bring a mental model that lets you move and iterate faster,
building a systematic way to iterate over the feedback loop of your experiences. It allows you to reap
the rewards of your actions more quickly and manage them better in the long term.&lt;/p&gt;
&lt;p&gt;Now, what are you doing to increase your friction area?&lt;/p&gt;
</content:encoded></item><item><title>2023 in Review</title><link>https://noghartt.dev/blog/2023-in-review/</link><guid isPermaLink="true">https://noghartt.dev/blog/2023-in-review/</guid><pubDate>Sat, 30 Dec 2023 19:52:17 GMT</pubDate><content:encoded>&lt;p&gt;For the second year, following some of the most inspirational blogs that I follow, I will write about my year, and this time it will be public. Some of the coolest blogs that I follow on a day-to-day basis are doing it, so why can&apos;t do it too, right?&lt;/p&gt;
&lt;p&gt;I would say that 2023 was one of the greatest years of my life. Like everyone else, I had ups and downs, but the fact that I learned too much in a lot of areas of my life, makes me think that I&apos;m a completely new person from how I started the year. Reading the OKRs that I wrote for this year I consider this idea even more.&lt;/p&gt;
&lt;p&gt;It&apos;s a good exercise to reflect on what happened this year and prepare for what is coming next, my idea with this post is to finish this year with a golden key and start the next one with all the excitement that I have writing here.&lt;/p&gt;
&lt;p&gt;For this post, I will cover some specific topics that I want to share here, they are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Books and reading&lt;/li&gt;
&lt;li&gt;Programming&lt;/li&gt;
&lt;li&gt;Job&lt;/li&gt;
&lt;li&gt;Writing&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Health&lt;/h2&gt;
&lt;p&gt;I would say that 2023 was not my year for health. I do not prioritize it in a lot of ways, but the three great ones that I think are: food, exercise, and sleep. And the impact of this choice came at different times throughout my year.&lt;/p&gt;
&lt;h3&gt;Food&lt;/h3&gt;
&lt;p&gt;I love to cook things and do meal prepping, but I do not spend too much of the year around it. The trade-off was that what I was eating, in general, doesn&apos;t have some nutritive benefits, and as we know,  what you eat in general is a fundamental part of the rest of your health. The quality of food in general wasn&apos;t too good.&lt;/p&gt;
&lt;h3&gt;Exercise&lt;/h3&gt;
&lt;p&gt;It has its ups and downs during the year. I tried a lot of times to go to the gym and turn it into a consistent habit because I love to do exercise. I love to run and take walks, it helps me a lot to clean my brain and help me with my thoughts, and it&apos;s connected with other aspects like controlling my anxiety and helps in the quality of my sleep. But I don&apos;t take the right priority on it and I lose my streak several times during the year.&lt;/p&gt;
&lt;h3&gt;Sleep&lt;/h3&gt;
&lt;p&gt;I&apos;m an easier sleep, I don&apos;t have any issue trying to sleep and I can easily do it in any place that I want to do. But, the quality of my sleep is awful. Doing some tracking around it, I take just 6 hours of sleeping with an average of 1 hour of REM sleep. I made some improvements in the consistency: like not going to sleep every night around 4 AM and waking up almost all days at 6 or 7 AM.&lt;/p&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;p&gt;This was a great year around my reading habit. I proposed to myself to take 12 books and successfully read them until the last day of December. From those 12 books, I read 10. Which, for me, it&apos;s a great achievement, considering that I completely lost one of the habits that I most like: the habit of reading.  If you want to check which are these books, you can check it on &lt;a href=&quot;/lists/list-of-books-that-i-read&quot;&gt;my list of books that I read&lt;/a&gt;. For the next year, I already have a lot of books that I want to read, most of them technical books.&lt;/p&gt;
&lt;p&gt;One of the core things that I learned from this habit and that I will bring to my 2024 is: that I don&apos;t want to read more books, I just want to read those that make me learn something. This is one of the core philosophies that I will follow for 2024, ensuring that it&apos;s better to spend time with books that impact my life, like the ones related to self-improvement that bring some cool ideas or those technical ones that are related to a subject of my interest.&lt;/p&gt;
&lt;h2&gt;Career and Work&lt;/h2&gt;
&lt;p&gt;A great year related to my career! I had the first opportunity to give a talk, and I learned a lot of cool things in a lot of different subjects, like Math, Distributed Systems, Web stuff, Compilers, and other cool stuff that I have a lot of interest in. I want to write about all these things someday. I started a lot of different projects too, like these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/noghartt/nero&quot;&gt;nero&lt;/a&gt;, my tree-walk interpreted programming language written in Rust.&lt;/li&gt;
&lt;li&gt;I rewrote my &lt;a href=&quot;https://github.com/noghartt/blog&quot;&gt;blog&lt;/a&gt; in Astro.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/noghartt/paxos-from-scratch&quot;&gt;Paxos From Scratch&lt;/a&gt;, my attempt to learn more about consensus algorithms, also written in Rust;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One thing that I want to bring to 2024 is the ambition to finish the projects that I started one day. I think that considering all these aspects, it was a great year for my career and I expect that 2024 may be the same.&lt;/p&gt;
&lt;p&gt;For my work, I continue working at &lt;a href=&quot;https://woovi.com&quot;&gt;Woovi&lt;/a&gt;, for a total of 1 year and 9 months, and I can say that it is one of the best decisions I made for myself. I need to thank every one of my coworkers for this year, I was able to learn a lot not only about the work, but I was able to have some introspective processes thanks to conversations I had with each of them, and what best I could bring to myself. But I&apos;m far from achieving the performance that I believe is ideal for my professional side, and that&apos;s exactly what I&apos;m going to look for in 2024.&lt;/p&gt;
&lt;h2&gt;Writing&lt;/h2&gt;
&lt;p&gt;I started to write more about my ideas and insights related to things that I like in tech in 2022, but I would say that was 2023 the year where I consolidated it as one of my passions and one of habits that I love to have. Exposing my ideas and my beliefs in words helps me a lot to understand myself and organize my thoughts in a way that seems coherent.&lt;/p&gt;
&lt;p&gt;In 2023 I wrote a lot, I have cool blog posts that I wrote both here in this blog or &lt;a href=&quot;https://dev.to&quot;&gt;dev.to&lt;/a&gt;, like these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/woovi/design-system-101-top-down-approach-in-component-spacing-281m&quot;&gt;Design System 101: Top-down Approach in Component Spacing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/woovi/server-side-rendering-ssr-from-scratch-with-react-19jm&quot;&gt;Server-side Rendering (SSR) From Scratch with React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/woovi/avoiding-ui-regressions-with-jest-49f3&quot;&gt;Avoiding UI Regressions With Jest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other blog posts have been written here. You can find them on the &lt;a href=&quot;https://noghartt.dev&quot;&gt;respective list&lt;/a&gt;. 2023 was a good year for improving my writing skills and knowing how to write for the final user in a good way.&lt;/p&gt;
&lt;h2&gt;Next steps in 2024?&lt;/h2&gt;
&lt;p&gt;Well, this was a little about my year in review. I believe that 2024 will be so great than 2023 will be for me, and I hope that can be great for you too.&lt;/p&gt;
&lt;p&gt;For 2024, the core aspect of what I want to focus on is health. Believing more and more that having a healthier body and a healthier mind is a core, fundamental piece to have a peak performance in any other aspect of my life. Focusing a lot on what I already talked about before: food, exercise, and sleep.&lt;/p&gt;
&lt;p&gt;Meal prepping and cooking are some of the best hobbies that I have in my life, and improving them during 2024 will be great stuff. Even because cooking is a good way to take some rest of the &lt;em&gt;&quot;outside world&quot;&lt;/em&gt; and recharge your batteries.&lt;/p&gt;
&lt;p&gt;Exercise and sleep will be carefully taken as priorities too. Ensuring that I&apos;ll turn it into one of the habits for my new year.&lt;/p&gt;
&lt;p&gt;I want to write more too. I have a lot of ideas for blog posts and series that I would like to write and I will move forward to get out of the paper and put it into screens, In 2024 I will write much more.&lt;/p&gt;
&lt;p&gt;In terms of other aspects of my life, I want to take more travels with my girlfriend, one feeling that I think I&apos;ve lost in the last years was the anxiety of discovering new things, new people, new languages, and/or new cultures. I believe that it is an enriching way to grow in life and learn more about yourself and others, and it&apos;s the kind of experience that you take for the rest of your life, it&apos;s what makes you alive. I already have some things planned on it and others I will discover yet.&lt;/p&gt;
&lt;p&gt;The word for my 2024 will be consistency. In every aspect of my life.&lt;/p&gt;
&lt;p&gt;I would like to say a big thank you to all the people who played an important role in my 2023. I hope your year was as special as mine. And a special thank you to these people: to my girlfriend who supports me despite my annoyance, I love you too much, to my friends who made my 2023 much better, and a special thank you to Sibelius and Ivan who were essential mentors and friends for my professional and personal growth in this year, thanks for all the advices.&lt;/p&gt;
&lt;p&gt;Happy New Year, reader! I hope that 2024 will be so great for you too!&lt;/p&gt;
</content:encoded></item><item><title>One Year Using Obsidian</title><link>https://noghartt.dev/blog/one-year-using-obsidian/</link><guid isPermaLink="true">https://noghartt.dev/blog/one-year-using-obsidian/</guid><pubDate>Wed, 27 Dec 2023 20:21:07 GMT</pubDate><content:encoded>&lt;p&gt;On December 26th, 2023, I started my new and current vault in Obsidian, and was one of the best decisions that I could bring to my 2023. Now I&apos;m doing the review around this beautiful tool that follows me in my entire year.&lt;/p&gt;
&lt;p&gt;In the last years of my life, I turned more and more of a heavy user of note-taking tools, even those &lt;em&gt;&quot;rudimentar&quot;&lt;/em&gt; ones like a pen and paper, I already tried a lot of tools around this subject, like Logseq, Notion, Bear, Apple Notes, Evernote, and finally Emacs with &lt;a href=&quot;https://orgmode.org/&quot;&gt;org-mode&lt;/a&gt;, when I thought that would be the state of the art of note-taking tools for me, and yes, I think that Emacs with org-mode is one of the best tools that I&apos;ve used in my entire life. And I used it for about two years, and was good.&lt;/p&gt;
&lt;p&gt;Although I like to use org-mode, I always felt that having a tool fits my workflow more easily. I&apos;d like to just put words into a file and push it to a place where I could find it easier in the future.  And well, I think that I finally found it.&lt;/p&gt;
&lt;h2&gt;Obsidian and My Workflow&lt;/h2&gt;
&lt;p&gt;The powerful philosophy around Obsidian is the concept of &lt;a href=&quot;https://stephango.com/file-over-app&quot;&gt;File over App&lt;/a&gt; that Steph Ango writes about. By the fact that it&apos;s just a tool that handles Markdown files in a better way and you can enhance this experience with some community plugins, you can have infinite ways to manage your workflow.&lt;/p&gt;
&lt;p&gt;It&apos;s one of the core arguments that shows why I think that Obsidian was the best tool for me at that moment, and fit it until now. If I want to move it to another app or build my solution, I just need to handle a bunch of Markdown files and everything will work great, it&apos;s a future-proof solution.&lt;/p&gt;
&lt;p&gt;My workflow is simple despite the range of community plugins and what you can do inside a vault, I just have six plugins, being them plugins that help me automatize some jobs, such as the Commander, QuickAdd, Templater, and Dataview, a query language plugin, allows me to do some specific tooling in my notes, but avoid it as much as possible.&lt;/p&gt;
&lt;p&gt;I try to maintain each note as raw as possible, just with what we can find in Markdown by default because I want to help me to migrate to another software if I need to in the future.&lt;/p&gt;
&lt;h2&gt;Obsidian and My Learnings&lt;/h2&gt;
&lt;p&gt;I would say that was an awesome year for my note-taking habits in general. I could develop more about this habit and I can found what are the exact ways that work for me. I don&apos;t know everything yet, and every day I try to improve some aspect of this habit, but I saw a lot of improvements in my entire life just by taking some notes during my day.&lt;/p&gt;
&lt;p&gt;Some statistics about what I did in my 2023 year with Obsdian:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I wrote a total of 512 notes.&lt;/li&gt;
&lt;li&gt;227 of them are daily journaling, which is ~44.33% of my entire vault.&lt;/li&gt;
&lt;li&gt;251 of them are related to my &lt;em&gt;Zettelkasten&lt;/em&gt;, which is ~49% of my entire vault.&lt;/li&gt;
&lt;li&gt;30 of them are drafts of blog posts that I hope someday will be the light, which is ~5.85% of my vault.&lt;/li&gt;
&lt;li&gt;I added 107 tags between the files, being the #computer-science the most used tag, with 130 files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are some statistics related to my work on my vault in this year, I believe that 2024 will be greater than that.&lt;/p&gt;
&lt;p&gt;The major learning related to my adventure with Obsidian was: that note-taking isn&apos;t about the tools that you use but about your process. A great process allows you to arrange your notes in a creative, better way that fits your expectations. Regardless of being Notion, Obsidian or just using your pen and a notebook. What matters is your process.&lt;/p&gt;
&lt;p&gt;By the way, this is the graph of my Obsidian on the day that I wrote this post, let&apos;s see how it will be in the next year:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/obsidian-graph-2023.png&quot; alt=&quot;Obsidian Graph 2023&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>The Awesomeness of Lists</title><link>https://noghartt.dev/blog/the-awesomeness-of-lists/</link><guid isPermaLink="true">https://noghartt.dev/blog/the-awesomeness-of-lists/</guid><pubDate>Tue, 26 Dec 2023 14:28:10 GMT</pubDate><content:encoded>&lt;p&gt;Lists are a universal tool for productivity, everything can be compound into a list or can be considered one. For example, the post-its that you have in your office wall they can be treated as a list, you can handle it recursively, putting new lists inside a list.&lt;/p&gt;
&lt;p&gt;We are presented to lists being a child and they follow us for our entire life, it&apos;s an easier way to create a condensed, simplistic way to arrange data to be used. You even can have specific lists that are being written as an ordered way to instruct someone to do something, like a cooking recipe or a tutorial.&lt;/p&gt;
&lt;p&gt;You can compound and have a lot of useful data that contextualizes you about everything in a specific scope by doing a list, like me, that does a list about the key points that I want to write about in this post.&lt;/p&gt;
&lt;p&gt;The fact that you can build this solution in a lot of different solutions helps us to maintain a lot of lists easier. You can have your supermarket lists written in pieces of paper, a list of blogs that you follow written in a gist in GitHub, or even a thread at Twitter with the list of the coolest blog posts that you read, &lt;a href=&quot;https://twitter.com/noghartt/status/1521123090587082752&quot;&gt;like me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Being a forgetful person with a considerably low attention-span, I found in lists an useful, disciplined way to go through my daily routine. I have lists to handle it , like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What I need to do on my job or at home;&lt;/li&gt;
&lt;li&gt;What are the meetings;&lt;/li&gt;
&lt;li&gt;What I need to follow-up;&lt;/li&gt;
&lt;li&gt;What I didn&apos;t do;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These to-do lists helps me to handle my routine in an easier way, helping me to be a more organized person. Furthermore, it gives me an visibility and tracking about the things that I need to do, the urgency of them and I missed on my daily activities or my daily habits.&lt;/p&gt;
&lt;p&gt;I also handle more than my daily tasks in this structure, I like to put all my useful resources into it. My notes has a lot of lists around it. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A list for the blogs and podcasts that I like to follow;&lt;/li&gt;
&lt;li&gt;What are the tracking of the books that I&apos;m reading (or already read) over the year;&lt;/li&gt;
&lt;li&gt;Useful links for articles or tool resources that I believe will be useful at some moment;&lt;/li&gt;
&lt;li&gt;And every resource that I believe will be useful for me at some moment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lists can express a great range of communication between two or more people, they give you all the insights and the scopes related to a subject. You can structure it like a checkbox of items containing the things that you need to do with their priorities, or like an ordered list containing your favorite cooking recipe, or just an unordered list containing the summary of the presentation of a course.&lt;/p&gt;
&lt;p&gt;They are an universal, easily tool of thought that helps us to derive through your day and the entire range of things happening at the same time.&lt;/p&gt;
&lt;p&gt;Given this versatility to arrange the content and the fact that you can put everywhere, like a piece of paper, a computer file or even just structuring your thoughts as a list of things, it&apos;s what make me an enjoyer of lists and why I think that other people should be too.&lt;/p&gt;
&lt;p&gt;This is my &lt;em&gt;ode to lists&lt;/em&gt;. Thanks.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I would especially like to thank @Eckzzo and @fersilvaa16 who helped review this post.
Thank you very much guys.&lt;/p&gt;
</content:encoded></item><item><title>My reading list - November 2023</title><link>https://noghartt.dev/blog/my-reading-list-november-2023/</link><guid isPermaLink="true">https://noghartt.dev/blog/my-reading-list-november-2023/</guid><pubDate>Thu, 02 Nov 2023 14:16:34 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lawrencecpaulson.github.io/2023/11/01/Foundations.html&quot;&gt;What do we mean by &quot;the foundations of mathematics&quot;?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://notes.eatonphil.com/2023-11-01-postgres-table-access-methods.html&quot;&gt;Writing a storage engine for Postgres: an in-memory Table Access Method&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://karpathy.github.io/2020/06/11/biohacking-lite/&quot;&gt;Biohacking Lite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hillelwayne.com/post/lsp/&quot;&gt;A BETTER EXPLANATION OF THE LISKOV SUBSTITUTION PRINCIPLE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://buttondown.email/hillelwayne/archive/some-thoughts-on-software-expertise/&quot;&gt;Some Thoughts on Software Expertise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thehistoryoftheweb.com/im-a-teapot/&quot;&gt;Sorry, I&apos;m a Teapot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://spectrum.ieee.org/cosmic-ray-failures-of-power-semiconductor-devices&quot;&gt;Cosmic Ray Failures of Power Semiconductor Devices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://alan.norbauer.com/articles/browser-debugging-tricks&quot;&gt;67 Weird Debugging Tricks Your Browser Doesn&apos;t Want You to Know&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://alsado.ca/posts/principles-are-products-of-practice/&quot;&gt;principles are products of practice, not the reverse&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Thinking in Systems</title><link>https://noghartt.dev/blog/thinking-in-systems/</link><guid isPermaLink="true">https://noghartt.dev/blog/thinking-in-systems/</guid><pubDate>Tue, 10 Oct 2023 01:09:53 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Note: 5/5&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finished: 2023-10-09&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thinking in Systems is one of the best books that I read in 2023. To be honest,
I can&apos;t absorb all the knowledge that this work writes down.&lt;/p&gt;
&lt;p&gt;The idea around all this book is to give you a better idea around how systems works,
in a internal, rational way. As an introduction to &lt;em&gt;&quot;non system thinkers&quot;&lt;/em&gt;, the book
proposes to show to you.&lt;/p&gt;
&lt;p&gt;With that idea in mind, they will presentate a lot of concepts about system domains and,
based on that, it&apos;ll introduce a new &lt;em&gt;&quot;meta&quot;&lt;/em&gt; mental model that will allow you to see our
non-linear world in a better way.&lt;/p&gt;
</content:encoded></item><item><title>Iterate over your feedback loop</title><link>https://noghartt.dev/blog/iterate-over-your-feedback-loop/</link><guid isPermaLink="true">https://noghartt.dev/blog/iterate-over-your-feedback-loop/</guid><pubDate>Sun, 08 Oct 2023 17:23:51 GMT</pubDate><content:encoded>&lt;p&gt;In the last month, I was reading the &lt;a href=&quot;https://www.amazon.com/Thinking-Systems-Donella-H-Meadows/dp/1603580557&quot;&gt;Thinking in Systems&lt;/a&gt; book.
It&apos;s a good book that clarify some ideas about how to sistematically think
in how systems works and the &lt;em&gt;&quot;rational&quot;&lt;/em&gt; behind it.&lt;/p&gt;
&lt;p&gt;Around the complexity of an entire system. A system can be defined as a network
structure connecting pieces that will produces one or more things from it.&lt;/p&gt;
&lt;p&gt;One of the core aspects of a system is &lt;em&gt;feedback loop&lt;/em&gt;. Everything can cause a
feedback loop, and every action can produce a feedback on the system or another
system.&lt;/p&gt;
&lt;p&gt;A feedback loop is the source of a side-effect that impacts in some change around
an aspect of your system. The output of the system can generate a positive or a negative
response, this is the feedback of your action. Giving that response, you can use it against
your system as the new input, then you validate the new hypothesis and iterate over them.
This is what we call the feedback loop.&lt;/p&gt;
&lt;p&gt;Thinking that everything that you do is a part of a system, it will help you to
identify a set of feedback loops around your actions. But, why is important to
have this conscioussness around what you&apos;re doing?&lt;/p&gt;
&lt;p&gt;Identify the effects of your actions and their responses is a cheaper way to
iterate with a clearer idea of your goal. After the feedback, you can adjust
your mental model and identify if you&apos;re closer to your goal.&lt;/p&gt;
&lt;p&gt;Iterate faster over your feedback loops give you advantages, more iterations over
your loops give you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A better understand about where you are. If you&apos;re reaching your goal;&lt;/li&gt;
&lt;li&gt;A clearer understading around the rules of your system and the path that let you reach where you are;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More iterations implies in a better understading of the system. A more accurate
mental model.&lt;/p&gt;
&lt;p&gt;See what are the feedback loops around what you are doing.&lt;/p&gt;
</content:encoded></item><item><title>My reading list - October 2023</title><link>https://noghartt.dev/blog/2023-10-reading-list/</link><guid isPermaLink="true">https://noghartt.dev/blog/2023-10-reading-list/</guid><pubDate>Fri, 06 Oct 2023 02:07:39 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tratt.net/laurie/blog/2023/minor_advances_in_knowledge_are_still_a_worthwhile_goal.html&quot;&gt;Minor Advances in Knowledge Are Still a Worthwhile Goal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://viralinstruction.com/posts/hardware/&quot;&gt;What scientist must know about hardware to write fast code?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=30YWsGDr8mA&quot;&gt;Making Hard Things Easy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://viralinstruction.com/posts/uniontypes/&quot;&gt;Union vs Sum types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>My first talk</title><link>https://noghartt.dev/blog/my-first-talk/</link><guid isPermaLink="true">https://noghartt.dev/blog/my-first-talk/</guid><pubDate>Mon, 18 Sep 2023 00:14:03 GMT</pubDate><content:encoded>&lt;p&gt;In the last September 16th, 2023, I did my first talk ever in a meetup. In Belo Horizonte,
happened the first JSParty Brasil.&lt;/p&gt;
&lt;p&gt;The experience of giving a talk, seeing the public listening to you, they looking for your
slides while you explaining the aiming topic is awesome.&lt;/p&gt;
&lt;p&gt;The idea behind the talk was to show a presentation about the codemod culture behind Woovi.
How we scale refactor in a large codebase (more than 500k LOC) and how we move faster
with these refactors.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;If you want to see the presentation slides, click &lt;a href=&quot;https://docs.google.com/presentation/d/1Y8uUNnOF1_N9w7gbkIYCGQpqPTkdjtyKbHf8fqDXpEg/edit#slide=id.p&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>My reading list - September 2023</title><link>https://noghartt.dev/blog/2023-09-reading-list/</link><guid isPermaLink="true">https://noghartt.dev/blog/2023-09-reading-list/</guid><pubDate>Tue, 12 Sep 2023 21:58:56 GMT</pubDate><content:encoded>&lt;p&gt;Following the ideas from &lt;a href=&quot;https://samueldurantes.github.io/blog/post/my-reading-list&quot;&gt;My reading list&lt;/a&gt; and &lt;a href=&quot;https://poorlydefinedbehaviour.github.io/posts/reading_list_august_2023/&quot;&gt;Reading List August 2023&lt;/a&gt;,
I&apos;ll be update this note while reading something that I think that can be useful for myself in the future.&lt;/p&gt;
&lt;h2&gt;Computer Science&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reasoning.page/2023/09/12/code-without-fear-sometimes/&quot;&gt;Code without fear. Sometimes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sive.rs/pg&quot;&gt;Simplify: move code into database functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2023/09/14/in-a-git-repository--where-do-your-files-live-/&quot;&gt;In a git repository, where do your files live?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.recompiled.dev/blog/deopt/&quot;&gt;Side effecting a deopt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mrereports.substack.com/p/your-wifi-can-see-you&quot;&gt;Your WiFi Can See You&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tigerbeetle.com/blog/2023-09-19-64-bit-bank-balances-ought-to-be-enough-for-anybody/&quot;&gt;64-Bit Bank Balances ‘Ought to be Enough for Anybody’?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thelig.ht/ui-apps-are-broken/&quot;&gt;Most UI Applications are Broken Real-time Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://notes.eatonphil.com/2023-09-21-how-do-databases-execute-expressions.html&quot;&gt;How do databases execute expressions?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://buttondown.email/hillelwayne/archive/did-brendan-eich-really-make-javascript-in-10-days/&quot;&gt;Was Javascript really made in 10 days?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.bytebytego.com/p/a-crash-course-in-dns-domain-name&quot;&gt;A crash course in DNS (Domain Name System)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bradfrost.com/blog/post/the-design-system-ecosystem/&quot;&gt;The Design System Ecosystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ishadeed.com/article/threads-app-css-part-2/&quot;&gt;CSS Findings From The Threads App: Part 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Videos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=brOtbWIViWM&quot;&gt;Brazil Tried to Protect Its Computer Industry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Productivity&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=bJQj1uKtnus&quot;&gt;The Cult of Done&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://buttondown.email/hillelwayne/archive/in-defense-of/&quot;&gt;Collecting and curating material is good and we should do it more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lethain.com/work-on-what-matters/&quot;&gt;Work on what matters.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://resobscura.substack.com/p/historical-maps-probably-helped-cause&quot;&gt;Historical maps probably helped cause World War I&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Economy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theatlantic.com/ideas/archive/2023/09/airlines-banks-mileage-programs/675374/&quot;&gt;Airlines Are Just Banks Now&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Biology&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.quantamagazine.org/what-makes-life-tick-mitochondria-may-keep-time-for-cells-20230918/&quot;&gt;What Makes Life Tick? Mitochondria May Keep Time for Cells&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Blogroll</title><link>https://noghartt.dev/blog/blogroll/</link><guid isPermaLink="true">https://noghartt.dev/blog/blogroll/</guid><pubDate>Sat, 08 Jul 2023 03:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m a person that likes to read a lot of things, and I have a lot of blogs that I like to read. I&apos;ll list here some of them:&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#personal-blogs&quot;&gt;Personal blogs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#self-improvement&quot;&gt;Self-improvement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#computer-science&quot;&gt;Computer science&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#company-blogs&quot;&gt;Company blogs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#newsletters&quot;&gt;Newsletters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#rss-feeds&quot;&gt;RSS Feeds&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Personal blogs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://joelhooks.com/&quot;&gt;Joel Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gwern.net/&quot;&gt;Gwern Branwen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drewdevault.com/&quot;&gt;Drew DeVault&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/&quot;&gt;Eli Bendersky&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.eliotpeper.com/&quot;&gt;Eliot Peper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.julian.com/&quot;&gt;Julian Shapiro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.nikitavoloboev.xyz/&quot;&gt;Nikita Voloboev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://macwright.com/&quot;&gt;Tom MacWright&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.paulgraham.com/articles.html&quot;&gt;Paul Graham&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://seths.blog/&quot;&gt;Seth Godin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sivers.org/blog&quot;&gt;Derek Sivers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.perell.com/blog&quot;&gt;David Perell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.benkuhn.net/&quot;&gt;Ben Kuhn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://guzey.com/&quot;&gt;Alexey Guzey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hillelwayne.com/&quot;&gt;Hillel Wayne&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Self-improvement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fs.blog/&quot;&gt;Farnam Street&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jamesclear.com/articles&quot;&gt;James Clear&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://markmanson.net/articles&quot;&gt;Mark Manson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mindingourway.com/&quot;&gt;Minding your way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nesslabs.com/blog&quot;&gt;Ness Labs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nateliason.com/blog&quot;&gt;Nat Eliason&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.scotthyoung.com/blog/&quot;&gt;Scott Young&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Computer science&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/&quot;&gt;Julia Evans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.iamtk.co/&quot;&gt;TK Kinoshita&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://overreacted.io/&quot;&gt;Dan Abramov&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Company blogs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stripe.com/blog&quot;&gt;Stripe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/airbnb-engineering&quot;&gt;Airbnb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eng.uber.com/&quot;&gt;Uber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://netflixtechblog.com/&quot;&gt;Netflix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://engineering.atspotify.com/&quot;&gt;Spotify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dropbox.tech/&quot;&gt;Dropbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.googleblog.com/&quot;&gt;Google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://engineering.fb.com/&quot;&gt;Facebook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.twitter.com/engineering/en_us.html&quot;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/&quot;&gt;Microsoft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.amazon.com/blogs&quot;&gt;Amazon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Newsletters&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hackernewslettr.com/&quot;&gt;Hacker Newsletter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hndigest.com/&quot;&gt;Hacker News Digest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.blog/newsletter/&quot;&gt;The Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.bytebytego.com/&quot;&gt;ByteByteGo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.latent.space/&quot;&gt;Latent Space&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thepalindrome.org/&quot;&gt;The Palindrome&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;RSS Feeds&lt;/h2&gt;
&lt;p&gt;A way to group all these blogs in one place is to use a RSS reader. I use &lt;a href=&quot;https://feedly.com/&quot;&gt;Feedly&lt;/a&gt; to read all my RSS feeds.
If you want to get the OPML that I use to view these blogs, you can get it &lt;a href=&quot;https://gist.github.com/noghartt/53e05e6bccb41e9fd69e24fa36ec65ce&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Writing things down</title><link>https://noghartt.dev/blog/writing-things-down/</link><guid isPermaLink="true">https://noghartt.dev/blog/writing-things-down/</guid><pubDate>Sat, 18 Feb 2023 03:00:00 GMT</pubDate><content:encoded>&lt;p&gt;How much stuffs did you write down today?&lt;/p&gt;
&lt;p&gt;As time goes by, more I believe that you need to write things down more and more. Documenting stuffs is a good way to believe in the long term game.&lt;/p&gt;
&lt;p&gt;Writing is a good way to put your thoughts in a paper (or anything else) and validate if they make sense. If you are missing some point that is important to understand all the context behind the subject.&lt;/p&gt;
&lt;p&gt;Writing is a good way to align your ideas with other people. Comparing the idea and checking what you don&apos;t know yet.&lt;/p&gt;
&lt;p&gt;Everyone should write things down. Just write things down.&lt;/p&gt;
</content:encoded></item><item><title>Simplifying things</title><link>https://noghartt.dev/blog/simplifying/</link><guid isPermaLink="true">https://noghartt.dev/blog/simplifying/</guid><pubDate>Wed, 22 Jun 2022 03:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Simplifying things is one of the most underrated ideas that people have when doing anything.
But understand why you need it and how you can do it can improve a lot of things in your daily
workflow.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;abstraction&lt;/strong&gt; is a nice way to simplify things. But what is an abstraction?
It&apos;s the process of removing implementation details of the final result. Abstracting
things is a process that we, humans, do every day. You don&apos;t need to expose every
detail from something, abstract it in a way that turns more easily to understand is
a good way to do it.&lt;/p&gt;
&lt;p&gt;We can talk that &lt;strong&gt;automation&lt;/strong&gt; is a way to abstract things too, in general I agreed with
that. But, automate things is a way to turn it more simplified. For example, you
can automate your daily workflow in some ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove spams from your email inbox;&lt;/li&gt;
&lt;li&gt;Schedule things in your agenda;&lt;/li&gt;
&lt;li&gt;Routine;&lt;/li&gt;
&lt;li&gt;Write things;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And lot of other things that you can do to help your daily workdflow. I think that we
can agree that it&apos;s a good way to simplifcate your day, right?&lt;/p&gt;
&lt;h2&gt;Simplification as code&lt;/h2&gt;
&lt;p&gt;But thinking in programming, how we can simplify our model? What things we should do to
improve our daily coding sessions? How we can turn our work easier? There are some thigns
that we can do to improve it.&lt;/p&gt;
&lt;p&gt;One of the things that we could understand is: we don&apos;t need every feature from some package,
framework, etc. It&apos;s a good idea know about the existence of this function, but think if it&apos;s
really necessary the usage of it on the scope of your project is a way to do simplification even
before write a line of code.&lt;/p&gt;
&lt;p&gt;An example about it is: did you know that Mongoose (an ODM to handle MongoDb) has a way to manage
versions of your documents? If you didn&apos;t know, yes. There&apos;s a way to do it. The &lt;code&gt;__v&lt;/code&gt; is a simple
property that stores an incremental integer and the propose behind it is: every time that you change the
structure of this document, &lt;code&gt;__v&lt;/code&gt; will be incremented.&lt;/p&gt;
&lt;p&gt;In some cases, we can treat it to do something based on the version of this document. Write a migration,
treat some internal logic or other things like it. But, thinking in your code, do you think that it&apos;s a
good idea to handle something like it? Thinking in every thing that you need to treat when write a code
to handle it, it&apos;s a good idea to do it? With every conditional branch, every corner case, every minimal
detail that you need to trait when is handle some sensitive data like a document in your database.&lt;/p&gt;
&lt;p&gt;When you use a feature of the library, framework or something like that, and doesn&apos;t think in the consequences
of it, it&apos;s the opposite of simplification, you are turn your work harder from now on. You just complicated the
work that you or other person will have to do when maintain this code, and over time this work will be more and
more complicated because the complexity will grow, and thinking in some months or a year, you or the person that
will fix the bug that appears in your code will say that this code has been simplified or not?&lt;/p&gt;
</content:encoded></item></channel></rss>