<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Chiraag&#39;s Musings</title>
    <link>https://blog.chiraag.me/</link>
    <description>Ramblings at the intersection of socialism and engineering</description>
    <pubDate>Thu, 22 Oct 2026 17:11:59 +0000</pubDate>
    <item>
      <title>Cornell and rape culture</title>
      <link>https://blog.chiraag.me/cornell-and-rape-culture</link>
      <description>&lt;![CDATA[A woman recently filed a civil suit against Cornell University and a fraternity (Chi Phi) regarding a gang rape incident which took place in 2024. At the time, the students were largely unpunished and the local DA refused to pursue the case.&#xA;&#xA;!--more--&#xA;&#xA;It is the same old story all over again: Woman comes forward, police do an investigation (supposedly), case is not pursued because of &#34;insufficient evidence&#34;. It is hard to believe that the same story that plays out again and again and again somehow isn&#39;t tied to our societal fascination with misogyny and rape culture. And it is a fascination: there is a whole contingent of men (and yeah, it&#39;s mostly men) who will argue that there is no such thing as rape culture until they are blue in the face.&#xA;&#xA;We saw this with Christine Blasey Ford. We saw this with Dr. Anita Hill. We see this every day with people in our lives who are ashamed to even reveal that something happened, scared that they will be blamed: &#34;What were you wearing?&#34;, &#34;Did you lead him on?&#34;, etc etc. Bullshit questions which remove the responsibility from the perpetrator and put the victim under a microscope.&#xA;&#xA;When someone reports a robbery, we assume that the crime is real and investigate accordingly. When someone reports arson, we assume it isn&#39;t just someone faking it for the insurance payout. Somehow, though, when a woman comes forward about a rape or sexual assault (if, indeed, she even feels comfortable coming forward at all), the default assumption is to not believe her.&#xA;&#xA;And then there are the men who will blather on about innocent people being caught in the crossfire: &#34;Oh, we musn&#39;t overcorrect lest poor innocent men get accused.&#34; While yes, due process should be preserved and all evidence should be scrutinized, the bar for women seems to be impossibly high at the moment: At the moment of what is likely her greatest trauma, she should recollect exactly what happened and who did what, how she reacted, whether she explicitly said no, if she told anyone afterward, and so on. And god forbid if elements of her experience become fuzzy or if details change as she is forced to relive that trauma again and again.&#xA;&#xA;We are so far from believing women and investigating accordingly that we are not in any serious danger of actually catching innocent men in the crossfire. Rather, we continually let perpetrators walk free to rape another day with nothing but a slap on the wrist.&#xA;&#xA;Where is the justice? Where are the consequences for assholes who weaponize sex as a tool of oppression (indeed, rape is about power more than the actual sex)? Rather than a knee-jerk reaction of &#34;But what about the innocent men?&#34; every time someone says we should believe women, maybe just...believe women?]]&gt;</description>
      <content:encoded><![CDATA[<p>A woman recently filed a <a href="https://www.cornellsun.com/article/2026/09/tccsuykuvb4z">civil suit</a> against Cornell University and a fraternity (Chi Phi) regarding a gang rape incident which took place in 2024. At the time, <a href="https://www.cbsnews.com/newyork/news/cornell-university-lawsuit-fraternity-rape-allegations/">the students were largely unpunished</a> and the local DA refused to pursue the case.</p>



<p>It is the same old story all over again: Woman comes forward, police do an investigation (supposedly), case is not pursued because of “insufficient evidence”. It is hard to believe that the same story that plays out again and again and again somehow isn&#39;t tied to our societal fascination with misogyny and rape culture. And it <em>is</em> a fascination: there is a whole contingent of men (and yeah, it&#39;s mostly men) who will argue that there is no such thing as rape culture until they are blue in the face.</p>

<p>We saw this with Christine Blasey Ford. We saw this with Dr. Anita Hill. We see this every day with people in our lives who are ashamed to even reveal that something happened, scared that they will be blamed: “What were you wearing?”, “Did you lead him on?”, etc etc. Bullshit questions which remove the responsibility from the perpetrator and put the victim under a microscope.</p>

<p>When someone reports a robbery, we assume that the crime is real and investigate accordingly. When someone reports arson, we assume it isn&#39;t just someone faking it for the insurance payout. Somehow, though, when a woman comes forward about a rape or sexual assault (if, indeed, she even feels comfortable coming forward at all), the default assumption is to <em>not</em> believe her.</p>

<p>And then there are the men who will blather on about innocent people being caught in the crossfire: “Oh, we musn&#39;t overcorrect lest poor innocent men get accused.” While yes, due process should be preserved and all evidence <em>should</em> be scrutinized, the bar for women seems to be impossibly high at the moment: At the moment of what is likely her greatest trauma, she should recollect exactly what happened and who did what, how she reacted, whether she explicitly said no, if she told anyone afterward, and so on. And god forbid if elements of her experience become fuzzy or if details change as she is forced to relive that trauma again and again.</p>

<p>We are <em>so</em> far from believing women and investigating accordingly that we are not in any serious danger of <em>actually</em> catching innocent men in the crossfire. Rather, we continually let perpetrators walk free to rape another day with nothing but a slap on the wrist.</p>

<p>Where is the justice? Where are the consequences for assholes who weaponize sex as a tool of oppression (indeed, rape is about power more than the actual sex)? Rather than a knee-jerk reaction of “But what about the innocent men?” every time someone says we should believe women, maybe just...believe women?</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/cornell-and-rape-culture</guid>
      <pubDate>Mon, 28 Sep 2026 04:51:43 +0000</pubDate>
    </item>
    <item>
      <title>AI discourse</title>
      <link>https://blog.chiraag.me/ai-discourse</link>
      <description>&lt;![CDATA[I have strong feelings about &#34;AI&#34;, and I don&#39;t think that&#39;s much a of a secret. Every time it&#39;s brought up, though, it almost always seems to come back to the same thing: &#34;Have you tried the latest models? They&#39;re amazing!&#34; or &#34;How can you evaluate how good these are if you never use them?&#34;. So let&#39;s address that.&#xA;&#xA;#AI #ScientificML #CloudLLMs #ChatGPT #Gemini #Claude #Ente #Firefox #Mozilla&#xA;&#xA;!--more--&#xA;&#xA;Types&#xA;&#xA;First, we should be clear what we&#39;re talking about here, because &#34;AI&#34; can mean a ton of different things. AI could mean any and all of:&#xA;&#xA;Scientific machine learning, used within limited contexts to elucidate complex relationships within data and tease out more complicated models for which we don&#39;t currently have analytical forms.&#xA;Cloud-based LLMs, of the chatbot style (e.g. ChatGPT, Gemini, etc).&#xA;Local ML models run on-device (e.g. Firefox&#39;s on-device translation feature, Ente&#39;s machine learning, etc).&#xA;&#xA;Putting them all into the same bucket is sort of silly, right? So let&#39;s address each in turn.&#xA;&#xA;Scientific ML&#xA;&#xA;Scientific machine learning models tend to be limited in scope and the good ones build in validation protocols. I might have my own concerns here around whether having a model for which we don&#39;t have an analytical form is useful. There are certainly variants here which attempt to extract equations from data (which brings its own challenges), but the concerns here are around the scientific usefulness. The data all has good provenance (usually generated by the researcher themselves), the scope is limited (e.g. we want to better predict the behavior of this specific material), and energy usage etc is wrapped up into the broader HPC system (this could change of course, if we need to scale up the HPC systems to handle more ML work, but that&#39;s a concern in the future and assumes these types of methods are broadly applicable in every context and that we need to train these models on the HPC...quite often, if a model is well-designed, it can be trained locally anyway, bypassing this issue entirely).&#xA;&#xA;Cloud-based LLMs&#xA;&#xA;Cloud-based LLMs like ChatGPT, Claude, Gemini, and so on raise the most alarm bells for me, and these are the ones I am completely against. I find issues with data provenance (did folks consent to have their data used for training these models?) and the fact that these companies seem to want to gatekeep knowledge. The ideal case for these people is that we can no longer function without LLMs and we pay them money indefinitely to continue to be able to function. There are the privacy concerns (these companies are storing your chats and can produce them on request) and the environmental concerns (there are enough articles out there about this, from the renewed building of gas power plants to folks&#39; water becoming impotable to the fact that these data centers are being built in drought-prone areas). There are the ethical concerns around the fact that the pitch to companies is that they can replace all of their workers with these LLMs. There is the fact that they have no notion of &#39;truth&#39; (so they don&#39;t &#39;hallucinate&#39;, they just spit out bullshit --- hallucination implies that they have a working model of the world and are imagining things which are not there, which simply is not true of these LLMs). There are bandaids around some of these concerns. Some companies provide interfaces to these LLMs without storing chats (DuckDuckGo) or storing them client-side encrypted (Proton). But nothing addresses all of these concerns.&#xA;&#xA;Then there are the practical concerns. I simply don&#39;t see a use for them. I enjoy coding. I enjoy thinking about how to design interfaces and classes and modules so that extending them is easy. I enjoy debugging (within reason, of course). I enjoy deriving equations to figure out if something is correct. And I enjoy thinking. Why would I give that up to an LLM? Why would I prefer chatting with a sycophantic plausible-sounding bullshit generator rather than an actual human being with their own ideas and their own viewpoints? So much of this just feels like hype for hype&#39;s sake, where something sounds &#39;cool&#39; so people jump on the bandwagon.&#xA;&#xA;The basic fact is that if I have to double-check everything an LLM states anyway, I&#39;m better off doing the research myself. I&#39;m better off using Google Scholar (as long as that&#39;s still around /sigh) to search for research papers than asking an LLM to find stuff for me. Is there a good chance it will find stuff? Sure. Is there also a decent chance it will hallucinate papers that don&#39;t exist or imply a paper says something it doesn&#39;t? Also yes. The number of times I&#39;ve looked at a DuckDuckGo AI summary and found it claiming something which simply isn&#39;t true is...non-negligible. It&#39;s not super high, but it&#39;s also disturbingly common. And that&#39;s the issue, right? It&#39;s not so good that I can just rely on it, but it&#39;s also not so bad that I can just assume everything is bullshit. It&#39;s at this level where most of what it&#39;s saying is probably accurate, increasing the cognitive overhead beyond what it would take for me to just search for stuff on my own.&#xA;&#xA;Local models&#xA;&#xA;Local models, I think, are the future of &#34;AI&#34; insofar as we want natural language interactions with machines. They are cheaper to run. They can be designed with good data provenance (sidestepping potential lawsuits and ethical issues). They don&#39;t require gigantic data centers. But they&#39;re harder to build for all of these reasons.&#xA;&#xA;Something like Ente&#39;s on-device ML for face recognition and semantic search is great because the facial recognition data is encrypted before being uploaded to the server and all ML processing happens on-device. Firefox, similarly, has an on-device translation option which doesn&#39;t touch the cloud. I know Ente uses models with good provenance, but I can&#39;t figure out where the Firefox Translations dataset is. At the very least, though, any local ML model must have open datasets and open weights and biases for it to be ethical.&#xA;&#xA;Conclusion&#xA;&#xA;My strong feelings on &#39;AI&#39; mostly derive from my strong feelings about cloud-based LLMs. There is a bait-and-switch tactic where folks will imply someone is against other forms of ML (including scientific ML or local models) just because they are against what OpenAI, Anthropic, and the rest are doing. I&#39;m not against AI or ML in general, but this space has been co-opted by these giant companies doing highly unethical things. We can simultaneously be pro-ML (used judiciously) while also being anti-&#39;AI&#39; (as defined by these giant companies).]]&gt;</description>
      <content:encoded><![CDATA[<p>I have strong feelings about “AI”, and I don&#39;t think that&#39;s much a of a secret. Every time it&#39;s brought up, though, it almost always seems to come back to the same thing: “Have you tried the latest models? They&#39;re amazing!” or “How can you evaluate how good these are if you never use them?”. So let&#39;s address that.</p>

<p><a href="https://blog.chiraag.me/tag:AI" class="hashtag"><span>#</span><span class="p-category">AI</span></a> <a href="https://blog.chiraag.me/tag:ScientificML" class="hashtag"><span>#</span><span class="p-category">ScientificML</span></a> <a href="https://blog.chiraag.me/tag:CloudLLMs" class="hashtag"><span>#</span><span class="p-category">CloudLLMs</span></a> <a href="https://blog.chiraag.me/tag:ChatGPT" class="hashtag"><span>#</span><span class="p-category">ChatGPT</span></a> <a href="https://blog.chiraag.me/tag:Gemini" class="hashtag"><span>#</span><span class="p-category">Gemini</span></a> <a href="https://blog.chiraag.me/tag:Claude" class="hashtag"><span>#</span><span class="p-category">Claude</span></a> <a href="https://blog.chiraag.me/tag:Ente" class="hashtag"><span>#</span><span class="p-category">Ente</span></a> <a href="https://blog.chiraag.me/tag:Firefox" class="hashtag"><span>#</span><span class="p-category">Firefox</span></a> <a href="https://blog.chiraag.me/tag:Mozilla" class="hashtag"><span>#</span><span class="p-category">Mozilla</span></a></p>



<h2 id="types">Types</h2>

<p>First, we should be clear what we&#39;re talking about here, because “AI” can mean a ton of different things. AI could mean any and all of:</p>
<ol><li>Scientific machine learning, used within limited contexts to elucidate complex relationships within data and tease out more complicated models for which we don&#39;t currently have analytical forms.</li>
<li>Cloud-based LLMs, of the chatbot style (e.g. ChatGPT, Gemini, etc).</li>
<li>Local ML models run on-device (e.g. Firefox&#39;s on-device translation feature, Ente&#39;s machine learning, etc).</li></ol>

<p>Putting them all into the same bucket is sort of silly, right? So let&#39;s address each in turn.</p>

<h2 id="scientific-ml">Scientific ML</h2>

<p>Scientific machine learning models tend to be limited in scope and the good ones build in validation protocols. I might have my own concerns here around whether having a model for which we don&#39;t have an analytical form is useful. There are certainly variants here which attempt to extract equations from data (which brings its own challenges), but the concerns here are around the <em>scientific usefulness</em>. The data all has good provenance (usually generated by the researcher themselves), the scope is limited (e.g. we want to better predict the behavior of <em>this specific material</em>), and energy usage etc is wrapped up into the broader HPC system (this could change of course, if we need to scale up the HPC systems to handle more ML work, but that&#39;s a concern in the future and assumes these types of methods are broadly applicable in every context <em>and</em> that we need to train these models on the HPC...quite often, if a model is well-designed, it can be trained locally anyway, bypassing this issue entirely).</p>

<h2 id="cloud-based-llms">Cloud-based LLMs</h2>

<p>Cloud-based LLMs like ChatGPT, Claude, Gemini, and so on raise the most alarm bells for me, and these are the ones I am completely against. I find issues with data provenance (did folks <em>consent</em> to have their data used for training these models?) and the fact that these companies seem to want to gatekeep knowledge. The ideal case for these people is that we can no longer function without LLMs and we pay them money indefinitely to continue to be able to function. There are the privacy concerns (these companies are storing your chats and can produce them on request) and the environmental concerns (there are enough articles out there about this, from the renewed building of gas power plants to folks&#39; water becoming impotable to the fact that these data centers are being built in drought-prone areas). There are the ethical concerns around the fact that the pitch to companies is that they can replace all of their workers with these LLMs. There is the fact that they have no notion of &#39;truth&#39; (so they don&#39;t &#39;hallucinate&#39;, they just spit out bullshit —– hallucination implies that they have a working model of the world and are imagining things which are not there, which simply is not true of these LLMs). There are bandaids around some of these concerns. Some companies provide interfaces to these LLMs without storing chats (DuckDuckGo) or storing them client-side encrypted (Proton). But nothing addresses <em>all</em> of these concerns.</p>

<p>Then there are the practical concerns. I simply don&#39;t see a use for them. I <em>enjoy</em> coding. I <em>enjoy</em> thinking about how to design interfaces and classes and modules so that extending them is easy. I <em>enjoy</em> debugging (within reason, of course). I <em>enjoy</em> deriving equations to figure out if something is correct. And I <em>enjoy</em> thinking. Why would I give that up to an LLM? Why would I prefer chatting with a sycophantic plausible-sounding bullshit generator rather than an actual human being with their own ideas and their own viewpoints? So much of this just feels like hype for hype&#39;s sake, where something sounds &#39;cool&#39; so people jump on the bandwagon.</p>

<p>The basic fact is that if I have to double-check everything an LLM states anyway, I&#39;m better off doing the research myself. I&#39;m better off using Google Scholar (as long as that&#39;s still around /sigh) to search for research papers than asking an LLM to find stuff for me. Is there a good chance it will find stuff? Sure. Is there also a decent chance it will hallucinate papers that don&#39;t exist or imply a paper says something it doesn&#39;t? Also yes. The number of times I&#39;ve looked at a DuckDuckGo AI summary and found it claiming something which simply isn&#39;t true is...non-negligible. It&#39;s not super high, but it&#39;s also disturbingly common. And that&#39;s the issue, right? It&#39;s not so good that I can just rely on it, but it&#39;s also not so bad that I can just assume everything is bullshit. It&#39;s at this level where <em>most</em> of what it&#39;s saying is <em>probably</em> accurate, increasing the cognitive overhead beyond what it would take for me to just search for stuff on my own.</p>

<h2 id="local-models">Local models</h2>

<p>Local models, I think, are the future of “AI” insofar as we want natural language interactions with machines. They are cheaper to run. They can be designed with good data provenance (sidestepping potential lawsuits and ethical issues). They don&#39;t require gigantic data centers. But they&#39;re harder to build for all of these reasons.</p>

<p>Something like Ente&#39;s on-device ML for face recognition and semantic search is great because the facial recognition data is encrypted before being uploaded to the server and all ML processing happens on-device. Firefox, similarly, has an on-device translation option which doesn&#39;t touch the cloud. I know Ente uses <a href="https://ente.com/ml/">models with good provenance</a>, but I can&#39;t figure out where the <a href="https://github.com/mozilla/translations">Firefox Translations</a> dataset is. At the very least, though, any local ML model <em>must</em> have open datasets and open weights and biases for it to be ethical.</p>

<h2 id="conclusion">Conclusion</h2>

<p>My strong feelings on &#39;AI&#39; mostly derive from my strong feelings about cloud-based LLMs. There is a bait-and-switch tactic where folks will imply someone is against other forms of ML (including scientific ML or local models) just because they are against what OpenAI, Anthropic, and the rest are doing. I&#39;m not against AI or ML in general, but this space has been co-opted by these giant companies doing highly unethical things. We can simultaneously be pro-ML (used judiciously) while also being anti-&#39;AI&#39; (as defined by these giant companies).</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/ai-discourse</guid>
      <pubDate>Sun, 20 Sep 2026 17:06:49 +0000</pubDate>
    </item>
    <item>
      <title>Setting up the Pebble Time 2</title>
      <link>https://blog.chiraag.me/setting-up-the-pebble-time-2</link>
      <description>&lt;![CDATA[I recently received my pre-ordered Pebble Time 2 and wanted to configure it for maximum privacy without compromising on features (as much as possible). Most of it was pretty straightforward, but one aspect was somewhat perplexing.&#xA;&#xA;!--more--&#xA;&#xA;When setting up the watch, I declined to create a Pebble account as it currently only does OAuth through Google, Apple, and Github (Microsoft). I don&#39;t particularly have an issue with cloud backups of installed apps and settings, but I don&#39;t want to use OAuth through any of those providers. Either way, the watch pretty much doesn&#39;t require an account unless you want to submit a bug report or want battery analytics (more on that later). Certainly not ideal, but not the end of the world either as I expect that if I genuinely have issues I can submit an issue on their Github repo and manually attach logs as required. As for battery analytics, if it&#39;s an issue I can install and configure Muninn --- so far I&#39;m very impressed with the battery life (I charged it after opening and doing the initial setup and it&#39;s literally sipping battery...it&#39;s fantastic).&#xA;&#xA;I then went into the Settings tab in the Pebble app and disabled everything under Diagnostics (which would disable battery analytics anyway, even if I had an account). Everything is by-default local (including health information etc), so the analytics were the only thing that needed to be manually toggled.&#xA;&#xA;The one thing I had to figure out, though, was how to get proper (as in exportable) access to my watch&#39;s health data. This isn&#39;t currently possible within the Pebble app, and I didn&#39;t want to use Google Fit (or their replacement for it).&#xA;&#xA;I am on an Android 13 device (with Play Services), so I installed Health Connect (a service which locally aggregates health data from any number of sources --- it comes installed by default on Android 14+, but needs to be installed manually on older devices). This operates purely locally if you believe Google (I&#39;m not sure that I do, but I&#39;m sure we can verify this using Wireshark or other tools). I allowed Pebble to share data with Health Connect, but that was only one half of the picture.&#xA;&#xA;I then needed a consumer of the Health Connect data, something that would allow me to view it and export it as desired. My first try was OpenVitals, but I ran into issues with it hitting rate limits for some reason. The bug reports there implied that it was because I installed Health Connect through the Play Store (rather than having it pre-installed through the OS).&#xA;&#xA;Then I stumbled upon Heartwood, which operates purely locally. No cloud storage, no uploads, nothing. It simply allows me to look at my data and export it to either a JSON file or CSV file. This was exactly what I needed to complete the picture.&#xA;&#xA;So now I have a smartwatch that can track my workouts, steps, heartrate, etc and seamlessly export it to a CSV or JSON that I can play with on the computer (look at trends etc). All in a privacy-respecting way (as far as I can tell).&#xA;&#xA;I selected the Pebble Time 2 for a few reasons:&#xA;&#xA;Open source: The OS and mobile app are all open source.&#xA;epaper screen: The epaper screen means the battery life is insanely good compared to most normal smartwatches.&#xA;Private: Overall, the watch is privacy-forward. It&#39;s not perfect (analytics are enabled by default, only OAuth logins enabled for now, etc), but miles better than pretty much any other major smartwatch out there.&#xA;Hackable: The whole ethos around Pebble seems to be very hacker-forward, which is something I really like.&#xA;&#xA;I disabled most notifications other than communication ones (so Signal, WhatsApp, Messenger, Messages, and Cheogram) as well as Proton Calendar (I enable notification reminders for many events, so this functions as enough of an integration for now).&#xA;&#xA;Overall, I am extremely satisfied with my new watch! There are of course rough edges (I mean, the ecosystem was dormant for 10 years!). But I expect it to only improve, and it&#39;s already more than satisfactory for my needs.]]&gt;</description>
      <content:encoded><![CDATA[<p>I recently received my pre-ordered <a href="https://repebble.com/watch">Pebble Time 2</a> and wanted to configure it for maximum privacy without compromising on features (as much as possible). Most of it was pretty straightforward, but one aspect was somewhat perplexing.</p>



<p>When setting up the watch, I declined to create a Pebble account as it currently only does OAuth through Google, Apple, and Github (Microsoft). I don&#39;t particularly have an issue with cloud backups of installed apps and settings, but I don&#39;t want to use OAuth through any of those providers. Either way, the watch pretty much doesn&#39;t <em>require</em> an account unless you want to submit a bug report or want battery analytics (more on that later). Certainly not ideal, but not the end of the world either as I expect that if I genuinely have issues I can submit an issue on their Github repo and manually attach logs as required. As for battery analytics, if it&#39;s an issue I can install and configure <a href="https://apps.repebble.com/692b3821d7dcba000a809ba5">Muninn</a> —– so far I&#39;m very impressed with the battery life (I charged it after opening and doing the initial setup and it&#39;s literally sipping battery...it&#39;s fantastic).</p>

<p>I then went into the Settings tab in the Pebble app and disabled everything under Diagnostics (which would disable battery analytics anyway, even if I had an account). Everything is by-default local (including health information etc), so the analytics were the only thing that needed to be manually toggled.</p>

<p>The one thing I had to figure out, though, was how to get proper (as in exportable) access to my watch&#39;s health data. This isn&#39;t <a href="https://forum.repebble.com/t/exporting-health-data/853">currently possible within the Pebble app</a>, and I didn&#39;t want to use Google Fit (or their replacement for it).</p>

<p>I am on an Android 13 device (with Play Services), so I installed Health Connect (a service which locally aggregates health data from any number of sources —– it comes installed by default on Android 14+, but needs to be installed manually on older devices). This operates purely locally if you believe Google (I&#39;m not sure that I do, but I&#39;m sure we can verify this using Wireshark or other tools). I allowed Pebble to share data with Health Connect, but that was only one half of the picture.</p>

<p>I then needed a <em>consumer</em> of the Health Connect data, something that would allow me to view it and export it as desired. My first try was <a href="https://codeberg.org/OpenVitals/mobile-app">OpenVitals</a>, but I ran into issues with it hitting rate limits for some reason. The bug reports there implied that it was because I installed Health Connect through the Play Store (rather than having it pre-installed through the OS).</p>

<p>Then I stumbled upon <a href="https://github.com/GuyOnWifi/heartwood">Heartwood</a>, which operates purely locally. No cloud storage, no uploads, nothing. It simply allows me to look at my data and export it to either a JSON file or CSV file. This was exactly what I needed to complete the picture.</p>

<p>So now I have a smartwatch that can track my workouts, steps, heartrate, etc and seamlessly export it to a CSV or JSON that I can play with on the computer (look at trends etc). All in a privacy-respecting way (as far as I can tell).</p>

<p>I selected the Pebble Time 2 for a few reasons:</p>
<ol><li>Open source: The OS and mobile app are all open source.</li>
<li>epaper screen: The epaper screen means the battery life is insanely good compared to most normal smartwatches.</li>
<li>Private: Overall, the watch is privacy-forward. It&#39;s not perfect (analytics are enabled by default, only OAuth logins enabled for now, etc), but miles better than pretty much any other major smartwatch out there.</li>
<li>Hackable: The whole ethos around Pebble seems to be very hacker-forward, which is something I really like.</li></ol>

<p>I disabled most notifications other than communication ones (so Signal, WhatsApp, Messenger, Messages, and <a href="https://jmp.chat">Cheogram</a>) as well as Proton Calendar (I enable notification reminders for many events, so this functions as enough of an integration for now).</p>

<p>Overall, I am extremely satisfied with my new watch! There are of course rough edges (I mean, the ecosystem was dormant for 10 years!). But I expect it to only improve, and it&#39;s already more than satisfactory for my needs.</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/setting-up-the-pebble-time-2</guid>
      <pubDate>Sat, 12 Sep 2026 23:58:21 +0000</pubDate>
    </item>
    <item>
      <title>Immigration and Workers</title>
      <link>https://blog.chiraag.me/immigration-and-workers</link>
      <description>&lt;![CDATA[Whether you&#39;re on the left or on the right, at least in the US and other Western countries, the implication that immigrants are stealing our jobs is so pervasive you would be forgiven for thinking it&#39;s some sort of basic fact. But...it&#39;s just not true.&#xA;&#xA;From the US Congress to the American Business Immigration Coalition to CNBC to the Brookings Institute, analysis upon analysis repeatedly shows that immigrants are not stealing USian jobs. So why do so many people repeat it as though it&#39;s true?&#xA;&#xA;!--more--&#xA;&#xA;The obvious answer is, of course, racism and xenophobia. That explains a bunch of it, especially as the immigrants we&#39;re talking about here are by-and-large Asian or Latinx. Banging on about &#39;them&#39; stealing &#39;our&#39; jobs creates a very clear dichotomy between the people who belong (&#39;us&#39;) and the people who don&#39;t (&#39;them&#39;).&#xA;&#xA;But while that explains part of the issue, there is a very perverse incentive for companies to nominally be pro-immigration. These companies know that immigrants have less of a safety net and are generally more precarious, so they get them to work more and pay them less. There are, of course, also abuses that are enabled by the hiring of specifically undocumented workers.&#xA;&#xA;The answer, then, is not to blame immigrants for taking our jobs (which isn&#39;t even true anyway), but rather to blame corporate greed for preferring to hire precarious workers. The answer is to fight for better labor protections so that immigrant workers are not as precarious as they currently are. Above all, form a union. Fighting (and negotiating) together gives everyone a better chance at a decent livelihood.&#xA;&#xA;Remember all of this the next time you&#39;re told that immigrants are taking your jobs, and correct the record if you can.]]&gt;</description>
      <content:encoded><![CDATA[<p>Whether you&#39;re on the left or on the right, at least in the US and other Western countries, the implication that immigrants are stealing our jobs is so pervasive you would be forgiven for thinking it&#39;s some sort of basic fact. But...it&#39;s just not true.</p>

<p>From <a href="https://www.congress.gov/119/meeting/house/118767/documents/HHRG-119-JU01-20251217-SD001-U1.pdf">the US Congress</a> to the <a href="https://abic.us/facts-immigrants-arent-stealing-your-jobs-or-lowering-wages/">American Business Immigration Coalition</a> to <a href="https://www.cnbc.com/2024/09/28/are-immigrants-taking-jobs-from-us-workers-heres-what-economists-say.html">CNBC</a> to the <a href="https://www.brookings.edu/articles/do-immigrants-steal-jobs-from-american-workers/">Brookings Institute</a>, analysis upon analysis repeatedly shows that immigrants are <em>not</em> stealing USian jobs. So why do so many people repeat it as though it&#39;s true?</p>



<p>The obvious answer is, of course, racism and xenophobia. That explains a bunch of it, especially as the immigrants we&#39;re talking about here are by-and-large Asian or Latinx. Banging on about &#39;them&#39; stealing &#39;our&#39; jobs creates a very clear dichotomy between the people who belong (&#39;us&#39;) and the people who don&#39;t (&#39;them&#39;).</p>

<p>But while that explains part of the issue, there is a very perverse incentive for <em>companies</em> to nominally be pro-immigration. These companies know that immigrants have less of a safety net and are generally more precarious, so they get them to work more and pay them less. There are, of course, also <a href="https://www.stl.news/dark-side-illegal-hiring-some-employers-exploit/">abuses</a> that are enabled by the hiring of specifically <em>undocumented</em> workers.</p>

<p>The answer, then, is <strong>not</strong> to blame immigrants for taking our jobs (which isn&#39;t even true anyway), but rather to blame corporate greed for preferring to hire precarious workers. The answer is to fight for better labor protections so that immigrant workers are not as precarious as they currently are. Above all, form a union. Fighting (and negotiating) together gives everyone a better chance at a decent livelihood.</p>

<p>Remember all of this the next time you&#39;re told that immigrants are taking your jobs, and correct the record if you can.</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/immigration-and-workers</guid>
      <pubDate>Sat, 29 Aug 2026 22:14:53 +0000</pubDate>
    </item>
    <item>
      <title>How I have been consistent with exercise</title>
      <link>https://blog.chiraag.me/how-i-have-been-consistent-with-exercise</link>
      <description>&lt;![CDATA[Everyone knows they should exercise. It&#39;s so ubiquitous in our culture that --- if you have the time and money --- you feel bad if you don&#39;t work out. My own journey with this was a bit winding and starts back in school.&#xA;&#xA;Throughout elementary, middle, and high school, I would try to keep regularly active, and it was definitely helpful that we went to active summer camps relatively often. During the year we would have gym class (my least favorite class!), but until high school I didn&#39;t intentionally try to get a workout schedule (I&#39;m not even sure I knew what a workout schedule was).&#xA;&#xA;By high school, we had an elliptical at home, so I started using that a few times a week --- usually one of the pre-programmed courses. It was always a bit sporadic, but at least I was trying.&#xA;&#xA;!--more--&#xA;&#xA;By the time college rolled around, I knew I should intentionally try to get exercise into my weekly schedule. I would go for an hour at the gym, using the elliptical or the weight machines. But it was hard between classes and exams and just needing down time, to the point where it happened, but was more sporadic than I would have liked. It was definitely intentional, but I was almost never happy with my progress or consistency.&#xA;&#xA;In grad school, I mostly stuck to the same approach and it was similarly sporadic. I would go for a few months (6 months even!) and then it would eventually peter out and I&#39;d fall off the wagon. I was never unhealthy by any measure, but it felt like I was always playing catch-up.&#xA;&#xA;Then, COVID hit. We were all confined to our homes and the university gym got repurposed into a COVID testing center. I had to find something different. Out of desperation, and wanting to get some physical activity into my routine, I started doing a bodyweight HIIT routine. It was 30 minutes and brutal. Because it was only 30 minutes (and because I was working from home anyway), it was impossible for me to say I didn&#39;t have time. It felt ridiculous to pretend as though I couldn&#39;t fit half an hour into my schedule with zero prep time and zero travel time. This was, by far, my most consistent period during grad school. I stuck with it and got into a routine to the point where I felt odd if I didn&#39;t do my workout three days a week.&#xA;&#xA;At some point, though, I started hitting the limits of bodyweight workouts. It was great (and that HIIT routine was intense), but at some point it felt like I was plateauing and I wasn&#39;t able to increase the intensity to push my muscles harder. I needed some form of resistance, but we didn&#39;t have the space for a full home gym (apartments anyone?). I also had gotten so used to the at-home aspect of my workout that I didn&#39;t want to physically go to a gym to do my workout either.&#xA;&#xA;This is when I discovered resistance bands. They are amazing. They are portable and light, and they come in many different weights. I have them all the way down to 15 lbs and all the way up to 200 lbs. You can get them in short or long forms (the short ones are great for certain leg exercises and for archer moves, and the long ones are great for full-body moves).&#xA;&#xA;Ever since I switched to a resistance band HIIT workout, I have never looked back. It&#39;s a 20 minute full-body workout that I cannot ever justify skipping. It&#39;s short enough that I can do it in the morning before work and then do my normal commute. I have had the most consistent period in my workout history since I switched (there was even a period where I would take the bands with me on work trips, but I stopped doing that for various reasons). I might sometimes still take breaks (e.g. vacation or work trips), but as soon as that&#39;s done I&#39;m right back to my workout schedule. It&#39;s quick, it&#39;s intense, and I never feel like I can say I don&#39;t have time.&#xA;&#xA;If you are struggling with trying to maintain a workout, I would highly recommend giving resistance bands a try, particularly in combination with a HIIT workout (there are tons). You can either do a full-body HIIT resistance band workout or find different videos that target different sets of muscles (I prefer the former approach). The HIIT aspect makes it hard to justify skipping and the resistance bands are a relatively cheap way to significantly increase the amount of effort your muscles have to put in.&#xA;&#xA;Am I a bodybuilder? Absolutely not. But I do want to maintain a healthy weight and a healthy amount of muscle, and my HIIT resistance band workouts integrate seamlessly into my schedule.&#xA;&#xA;The only downside with bands is that even small changes in posture and grip can significantly affect the load on your muscles, meaning that it can sometimes be hard to track progress (you don&#39;t know if you&#39;re just a bit weaker today or if you messed up your grip). My rule of thumb is simply to push as much as you can (sometimes I can do a ton of banded pushups and other times I&#39;m struggling to do half of what I normally do). Especially with HIIT, even small things like the amount of hydration and sleep can affect your performance, especially if you&#39;re working out in the morning like I do.&#xA;&#xA;The following links are solely what I use. Feel free to look for other resources (there are many!). Tip on resistance bands: You want to make sure you&#39;re looking for layered bands since if a layer rips, you get advance warning before the entire thing snaps (look at the side profile of the band in photos, the layers should be visible).&#xA;&#xA;Resistance bands: Rogue Monster Bands, Rogue Shorty Monster Bands, Rogue Tube Bands.&#xA;&#xA;HIIT Resistance Band Workout: James Grage&#39;s video]]&gt;</description>
      <content:encoded><![CDATA[<p>Everyone knows they should exercise. It&#39;s so ubiquitous in our culture that —– if you have the time and money —– you feel bad if you <em>don&#39;t</em> work out. My own journey with this was a bit winding and starts back in school.</p>

<p>Throughout elementary, middle, and high school, I would try to keep regularly active, and it was definitely helpful that we went to active summer camps relatively often. During the year we would have gym class (my least favorite class!), but until high school I didn&#39;t intentionally try to get a workout schedule (I&#39;m not even sure I <em>knew</em> what a workout schedule was).</p>

<p>By high school, we had an elliptical at home, so I started using that a few times a week —– usually one of the pre-programmed courses. It was always a bit sporadic, but at least I was trying.</p>



<p>By the time college rolled around, I knew I should intentionally try to get exercise into my weekly schedule. I would go for an hour at the gym, using the elliptical or the weight machines. But it was hard between classes and exams and just needing down time, to the point where it happened, but was more sporadic than I would have liked. It was definitely intentional, but I was almost never happy with my progress or consistency.</p>

<p>In grad school, I mostly stuck to the same approach and it was similarly sporadic. I would go for a few months (6 months even!) and then it would eventually peter out and I&#39;d fall off the wagon. I was never unhealthy by any measure, but it felt like I was always playing catch-up.</p>

<p>Then, COVID hit. We were all confined to our homes and the university gym got repurposed into a COVID testing center. I had to find something different. Out of desperation, and wanting to get <em>some</em> physical activity into my routine, I started doing a bodyweight HIIT routine. It was 30 minutes and <em>brutal</em>. Because it was only 30 minutes (and because I was working from home anyway), it was impossible for me to say I didn&#39;t have time. It felt ridiculous to pretend as though I couldn&#39;t fit half an hour into my schedule with zero prep time and zero travel time. This was, by <em>far</em>, my most consistent period during grad school. I stuck with it and got into a routine to the point where I felt odd if I <em>didn&#39;t</em> do my workout three days a week.</p>

<p>At some point, though, I started hitting the limits of bodyweight workouts. It was great (and that HIIT routine was intense), but at some point it felt like I was plateauing and I wasn&#39;t able to increase the intensity to push my muscles harder. I needed some form of resistance, but we didn&#39;t have the space for a full home gym (apartments anyone?). I also had gotten so used to the at-home aspect of my workout that I didn&#39;t want to physically go to a gym to do my workout either.</p>

<p>This is when I discovered resistance bands. They are amazing. They are portable and light, and they come in many different weights. I have them all the way down to 15 lbs and all the way up to 200 lbs. You can get them in short or long forms (the short ones are great for certain leg exercises and for archer moves, and the long ones are great for full-body moves).</p>

<p>Ever since I switched to a resistance band HIIT workout, I have never looked back. It&#39;s a 20 minute full-body workout that I cannot ever justify skipping. It&#39;s short enough that I can do it in the morning before work and then do my normal commute. I have had the most consistent period in my workout history since I switched (there was even a period where I would take the bands with me on work trips, but I stopped doing that for various reasons). I might sometimes still take breaks (e.g. vacation or work trips), but as soon as that&#39;s done I&#39;m right back to my workout schedule. It&#39;s quick, it&#39;s intense, and I never feel like I can say I don&#39;t have time.</p>

<p>If you are struggling with trying to maintain a workout, I would highly recommend giving resistance bands a try, particularly in combination with a HIIT workout (there are tons). You can either do a full-body HIIT resistance band workout or find different videos that target different sets of muscles (I prefer the former approach). The HIIT aspect makes it hard to justify skipping and the resistance bands are a relatively cheap way to significantly increase the amount of effort your muscles have to put in.</p>

<p>Am I a bodybuilder? Absolutely not. But I do want to maintain a healthy weight and a healthy amount of muscle, and my HIIT resistance band workouts integrate seamlessly into my schedule.</p>

<p>The only downside with bands is that even small changes in posture and grip can significantly affect the load on your muscles, meaning that it can sometimes be hard to track progress (you don&#39;t know if you&#39;re just a bit weaker today or if you messed up your grip). My rule of thumb is simply to push as much as you can (sometimes I can do a ton of banded pushups and other times I&#39;m struggling to do half of what I normally do). Especially with HIIT, even small things like the amount of hydration and sleep can affect your performance, especially if you&#39;re working out in the morning like I do.</p>

<p>The following links are solely what <em>I</em> use. Feel free to look for other resources (there are many!). Tip on resistance bands: You want to make sure you&#39;re looking for layered bands since if a layer rips, you get advance warning before the entire thing snaps (look at the side profile of the band in photos, the layers should be visible).</p>

<p>Resistance bands: <a href="https://www.roguefitness.com/rogue-monster-bands">Rogue Monster Bands</a>, <a href="https://www.roguefitness.com/rogue-shorty-monster-bands">Rogue Shorty Monster Bands</a>, <a href="https://www.roguefitness.com/rogue-tube-bands">Rogue Tube Bands</a>.</p>

<p>HIIT Resistance Band Workout: <a href="https://www.youtube.com/watch?v=xrhMpzhz0s4">James Grage&#39;s video</a></p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/how-i-have-been-consistent-with-exercise</guid>
      <pubDate>Thu, 27 Aug 2026 02:00:39 +0000</pubDate>
    </item>
    <item>
      <title>Why I went vegan (and how you can too!)</title>
      <link>https://blog.chiraag.me/why-i-went-vegan-and-how-you-can-too</link>
      <description>&lt;![CDATA[Five years ago (and change), I finally went vegan. I say &#34;finally&#34; because I had thought about going vegan since 2014; I was in college at the time and figured I should wait until I had more control over my diet to properly switch over. I was already vegetarian (was brought up that way), so the switch was easier for me than, say, for an omnivore looking to do so.&#xA;&#xA;So what caused my change of heart? After all, the narrative I had been told from the beginning was that vegetarianism was the ethical choice (hey look, animals don&#39;t get killed because of us!), so for a long time I just...didn&#39;t think about it. I started rethinking this, though, as I learned more about the dairy and egg industries (and started thinking about how they can exist in the first place).&#xA;&#xA;!--more--&#xA;&#xA;The egg industry&#xA;&#xA;Let&#39;s start with the easy one (for me, at least). I gave up egg in 2014 once I had decided to go vegan, simply because the main reason it entered my diet was through desserts (so nutrition wasn&#39;t an issue). The reason, for me, was simple: We don&#39;t have a right to other animals&#39; eggs, full stop.&#xA;&#xA;Notice how none of this relies on the exact conditions of the chickens (free-range versus caged, their feed and living conditions, etc). All of that could serve as additional reasons, but to me those are just additional reasons. The concept of cooping up animals simply to induce them to lay eggs (as I put it, by fake-raping them) is abhorrent to me, even on its face. I just imagine how women would feel if they were treated as factories to produce eggs and the amount of trauma the chickens must experience even in the best case and it&#39;s just...gross.&#xA;&#xA;Some will argue we shouldn&#39;t anthropomorphize other animals, and that&#39;s true: we don&#39;t know the full extent of which emotions other animals feel (yet!). But we do know that reproduction is often biologically stressful (and at times traumatic) and it seems blatantly self-serving to assume that is not the case for chickens (just so we can eat their eggs).&#xA;&#xA;It&#39;s also a case of &#39;ownership&#39;, right? Who has the &#39;right&#39; to the eggs those chickens produce? And why should that be us (rather than the chickens)? Why should we get to dictate when and how other animals reproduce? It is one thing to harvest wild eggs sustainably (even that is something we cannot trust humans to do --- think of the dodo), it is another to treat chickens as egg-producing machines and fully ignore the biological reality of why those eggs are produced and the chickens which produce them.&#xA;&#xA;The dairy industry&#xA;&#xA;Dairy was trickier for me because I got a decent amount of nutrition from it (yogurt and milk were staples in my diet). This was what held up my transition for a few years as I wanted to make sure I was not losing anything nutritionally by switching away from it (spoiler: replacing it is relatively easy!). But why did I want to switch away from it?&#xA;&#xA;Well, the answer is simple: At the heart of the dairy industry is rape. Mammals only produce milk when they have given birth to young, meaning that in order to keep the milk flowing the cows must continuously give birth. Again and again and again. We know that pregnancy in mammals is a biologically stressful event (and again, sometimes traumatic), and the thought of constantly literally raping these cows so that we can have milk should be vomit-inducing. We talk about rape culture in our society (which is very real), but we don&#39;t talk about how rape underpins the dairy industry nearly enough. If the rapes stopped, the dairy would stop flowing. If you are against rape culture and rape, you should be against the dairy industry.&#xA;&#xA;There is also the secondary point that, much like with eggs, do we really have a right to the cow&#39;s milk? I mean, it produced it for its calf and we are literally stealing it. Some make the point that the cow is producing way more than the calf actually needs; if a human is producing more breastmilk than their baby needs, should we be allowed to take it without getting consent? Hopefully we can all agree that would be unethical, so why would the same not apply in the case of cows? They are living beings, not machines.&#xA;&#xA;Much like the egg industry, I could also make the points around how male calves are killed immediately and living conditions are awful and so on. And that is all true. But at its heart, as soon as we literally force the cows to constantly produce offspring just to take the milk, it&#39;s already unethical. Even if they are pasture-fed and have tons of living space and are treated nicely, that does not take away from having raped them.&#xA;&#xA;How I switched&#xA;&#xA;Nutritionally, the closest to dairy milk is soy milk, especially the kinds with only soy and water. I also make soy yogurt from whole soybeans to replace yogurt (it has somewhere between the nutrition levels of regular yogurt and Greek yogurt). Once I figured that out, switching was relatively easy --- I never had any problems giving stuff up or finding alternatives as long as I wasn&#39;t compromising myself nutritionally.&#xA;&#xA;In terms of nutrition, I switched largely to a whole-foods plant-based diet (WFPB), which emphasizes whole grains, legumes, fruits, and veggies, with some moderate amounts of nuts and seeds. The strictest adherents fully avoid salt, sugar, and oil; I still use salt (hello iodine!), but sugar and oil consumption are mostly non-existent at home.&#xA;&#xA;I tracked my nutrition for a few weeks when I first switched, mainly to make adjustments based on vitamin and mineral levels (particularly iron and calcium) as well as desired amounts of protein and total calories. Nowadays, I don&#39;t really need to track anything because I know roughly how much I should eat of different kinds of things to balance everything out.&#xA;&#xA;In short, the answer to &#34;How did you switch?&#34; is &#34;I took the plunge, tracked things, and figured it out over a few weeks&#34;. My diet has never been more nutritious, which should hopefully put to bed the lie that vegans cannot have a nutritionally-balanced diet (no folks, you don&#39;t need meat or eggs or dairy in order to meet your nutritional needs).&#xA;&#xA;One final point I want to make: Folks sometimes get up in arms, saying that veganism is expensive and that poorer people cannot afford to be vegan. The thing is, if you compare WFPB protein sources (for example) to meat, WFPB protein sources like legumes and tofu are cheaper (per gram of protein) than meat or fish. Historically, legumes are some of the cheapest protein sources around (and that still holds true today). Sure, if you go for the &#39;fake meat&#39; options, it will be more expensive, but those are not a necessity (and are also not universally available anyway). In terms of dairy alternatives, you can make alternative milks at home for a substantially cheaper price (and not a lot of effort) than buying it from the store (at the store, you&#39;re mainly paying for the convenience), and I pretty much only eat my homemade soy yogurt because the store alternatives are not as good in basically every way. The point is, if you avoid the newer fake meat and such, the stuff you&#39;re eating on a vegan diet is stuff you should be eating anyway (grains, legumes, fruits, and veggies are always good for you!), so the only difference is perhaps increased consumption of legumes (rather than buying meat).]]&gt;</description>
      <content:encoded><![CDATA[<p>Five years ago (and change), I finally went vegan. I say “finally” because I had thought about going vegan since 2014; I was in college at the time and figured I should wait until I had more control over my diet to properly switch over. I was already vegetarian (was brought up that way), so the switch was easier for me than, say, for an omnivore looking to do so.</p>

<p>So what caused my change of heart? After all, the narrative I had been told from the beginning was that vegetarianism was the ethical choice (hey look, animals don&#39;t get killed because of us!), so for a long time I just...didn&#39;t think about it. I started rethinking this, though, as I learned more about the dairy and egg industries (and started thinking about how they can exist in the first place).</p>



<h2 id="the-egg-industry">The egg industry</h2>

<p>Let&#39;s start with the easy one (for me, at least). I gave up egg in 2014 once I had decided to go vegan, simply because the main reason it entered my diet was through desserts (so nutrition wasn&#39;t an issue). The reason, for me, was simple: We don&#39;t have a right to other animals&#39; eggs, full stop.</p>

<p>Notice how none of this relies on the exact conditions of the chickens (free-range versus caged, their feed and living conditions, etc). All of that could serve as additional reasons, but to me those are just additional reasons. The concept of cooping up animals simply to induce them to lay eggs (as I put it, by fake-raping them) is <em>abhorrent</em> to me, even on its face. I just imagine how women would feel if they were treated as factories to produce eggs and the amount of trauma the chickens must experience <em>even in the best case</em> and it&#39;s just...gross.</p>

<p>Some will argue we shouldn&#39;t anthropomorphize other animals, and that&#39;s true: we don&#39;t know the full extent of which emotions other animals feel (yet!). But we do know that reproduction is often biologically stressful (and at times traumatic) and it seems blatantly self-serving to assume that is not the case for chickens (just so we can eat their eggs).</p>

<p>It&#39;s also a case of &#39;ownership&#39;, right? Who has the &#39;right&#39; to the eggs those chickens produce? And why should that be us (rather than the chickens)? Why should <em>we</em> get to dictate when and how other animals reproduce? It is one thing to harvest wild eggs sustainably (even that is something we cannot trust humans to do —– think of the dodo), it is another to treat chickens as egg-producing <em>machines</em> and fully ignore the biological reality of why those eggs are produced and the chickens which produce them.</p>

<h2 id="the-dairy-industry">The dairy industry</h2>

<p>Dairy was trickier for me because I got a decent amount of nutrition from it (yogurt and milk were staples in my diet). This was what held up my transition for a few years as I wanted to make sure I was not losing anything nutritionally by switching away from it (spoiler: replacing it is relatively easy!). But <em>why</em> did I want to switch away from it?</p>

<p>Well, the answer is simple: At the heart of the dairy industry is rape. Mammals only produce milk when they have given birth to young, meaning that in order to keep the milk flowing the cows must continuously give birth. Again and again and again. We <em>know</em> that pregnancy in mammals is a biologically stressful event (and again, sometimes traumatic), and the thought of constantly literally raping these cows so that we can have milk should be vomit-inducing. We talk about rape culture in our society (which is very real), but we don&#39;t talk about how rape underpins the dairy industry <em>nearly</em> enough. If the rapes stopped, the dairy would stop flowing. If you are against rape culture and rape, you should be against the dairy industry.</p>

<p>There is also the secondary point that, much like with eggs, do we really have a right to the cow&#39;s milk? I mean, it produced it for its calf and we are literally stealing it. Some make the point that the cow is producing way more than the calf actually needs; if a human is producing more breastmilk than their baby needs, should we be allowed to take it without getting consent? Hopefully we can all agree that would be unethical, so why would the same not apply in the case of cows? They are living beings, not machines.</p>

<p>Much like the egg industry, I could also make the points around how male calves are killed immediately and living conditions are awful and so on. And that is all true. But at its heart, as soon as we literally <em>force</em> the cows to constantly produce offspring just to take the milk, it&#39;s already unethical. Even if they are pasture-fed and have tons of living space and are treated nicely, that does not take away from having raped them.</p>

<h2 id="how-i-switched">How I switched</h2>

<p>Nutritionally, the closest to dairy milk is soy milk, especially the kinds with only soy and water. I also make soy yogurt from whole soybeans to replace yogurt (it has somewhere between the nutrition levels of regular yogurt and Greek yogurt). Once I figured that out, switching was relatively easy —– I never had any problems giving stuff up or finding alternatives as long as I wasn&#39;t compromising myself nutritionally.</p>

<p>In terms of nutrition, I switched largely to a whole-foods plant-based diet (WFPB), which emphasizes whole grains, legumes, fruits, and veggies, with some moderate amounts of nuts and seeds. The strictest adherents fully avoid salt, sugar, and oil; I still use salt (hello iodine!), but sugar and oil consumption are mostly non-existent at home.</p>

<p>I tracked my nutrition for a few weeks when I first switched, mainly to make adjustments based on vitamin and mineral levels (particularly iron and calcium) as well as desired amounts of protein and total calories. Nowadays, I don&#39;t really need to track anything because I know roughly how much I should eat of different kinds of things to balance everything out.</p>

<p>In short, the answer to “How did you switch?” is “I took the plunge, tracked things, and figured it out over a few weeks”. My diet has never been more nutritious, which should hopefully put to bed the lie that vegans cannot have a nutritionally-balanced diet (no folks, you don&#39;t <em>need</em> meat or eggs or dairy in order to meet your nutritional needs).</p>

<p>One final point I want to make: Folks sometimes get up in arms, saying that veganism is expensive and that poorer people cannot afford to be vegan. The thing is, if you compare WFPB protein sources (for example) to meat, WFPB protein sources like legumes and tofu are <em>cheaper</em> (per gram of protein) than meat or fish. Historically, legumes are some of the cheapest protein sources around (and that still holds true today). Sure, if you go for the &#39;fake meat&#39; options, it will be more expensive, but those are not a necessity (and are also not universally available anyway). In terms of dairy alternatives, you can make alternative milks at home for a substantially cheaper price (and not a lot of effort) than buying it from the store (at the store, you&#39;re mainly paying for the convenience), and I pretty much only eat my homemade soy yogurt because the store alternatives are not as good in basically every way. The point is, if you avoid the newer fake meat and such, the stuff you&#39;re eating on a vegan diet is stuff you should be eating <em>anyway</em> (grains, legumes, fruits, and veggies are <em>always</em> good for you!), so the only difference is perhaps increased consumption of legumes (rather than buying meat).</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/why-i-went-vegan-and-how-you-can-too</guid>
      <pubDate>Fri, 31 Jul 2026 13:58:30 +0000</pubDate>
    </item>
    <item>
      <title>How I set up my self-hosted services</title>
      <link>https://blog.chiraag.me/how-i-set-up-my-self-hosted-services</link>
      <description>&lt;![CDATA[I want to expand on my previous post a little bit to explain the steps I took to setup PeerTube, Ente, and WriteFreely.&#xA;&#xA;Prerequisites&#xA;&#xA;I set everything up on two different VPSs. PeerTube was on a new domain, so I used an Ionos VPS. Ente and WriteFreely are on my main VPS (powering this website) since they were on subdomains of this domain.&#xA;&#xA;All intensive storage (photos and videos) happens on Backblaze B2. I love Backblaze for its reliably cheap storage and excellent APIs (including, crucially for this use-case, S3-compatible APIs).&#xA;&#xA;!--more--&#xA;&#xA;PeerTube&#xA;&#xA;I first followed the steps here to do the basic setup. I followed all of those instructions (including setting up the reverse proxy and systemd service. Because this is a fresh VPS, I did not have any port conflicts (this was not the case with the others as will be clear) and I could use the support reverse proxy (nginx).&#xA;&#xA;Then, it was time to setup the object storage according to this page. I went to Backblaze B2, created a new bucket for PeerTube, and made it public. Then, I generated an application key (restricted only to that bucket), ensuring that the key had the ability to list all buckets (necessary for an S3-compatible key). Then, all I had to do was fill in all of the information in config/production.yaml according to the documentation, restart PeerTube (systemctl restart peertube), and I was good to go!&#xA;&#xA;Initially, I had disabled transcoding, opting only to keep one resolution of the video (effectively just the original file). I later enabled HLS transcoding and manually ran the HLS transcoding jobs on the uploaded videos (possible through the admin interface). Everything went smoothly and the existing videos were (slowly) transcoded. I say slowly simply because the VPS only has 2 cores, so I can&#39;t really run transcoding jobs in parallel.&#xA;&#xA;I initially had tried to setup a remote runner, but it was having trouble with transcoding large files, so I disabled it for now. I will probably retry the runner with the next upload and see how it goes.&#xA;&#xA;Ente&#xA;&#xA;I had initially tried self-hosting Ente a few months ago when I first heard about it after asking for a self-hosted gallery with object storage support over on Mastodon. However, while I was able to get it up and running, I was running into issues completing the registration and getting the object storage backend up and running, so I gave up.&#xA;&#xA;Then, about a week ago, I decided to try again and actually got it working. I followed the self-hosting directions and got it installed, but I kept running into CORS issues when I attempted to register (the same issue I ran into earlier).&#xA;&#xA;I then realized that I had to set the environment block in compose.yaml to the IP address (rather than localhost), and that was enough to get it working. I then similarly set up a bucket in B2 for Ente and set up the object storage backend. I then tried a few test uploads and it worked!&#xA;&#xA;When I went to configure the reverse-proxy, I had to set it up with apache instead of nginx because apache was already being used for my main web server. There are numerous guides for doing it, so I won&#39;t elaborate here, but it&#39;s pretty straightforward.&#xA;&#xA;What I also hadn&#39;t realized originally was that I needed to enable all of the components on subdomains. For example, the main Ente domain is https://photos.chiraag.me, and all of the sub-components needed to be hosted on subdomains of that (e.g. https://api.photos.chiraag.me and so on --- I just used the standard subdomain names given in the documentation). Once I had configured this, added all of the subdomain reverse proxy entries, and used cerbot --apache to generate the SSL certificates (or, more accurately, expand the existing one to cover the new subdomains), everything worked great. Everything is automatically encrypted client-side, then uploaded to my B2 bucket. Then I can create public albums and share them (like at https://chiraag.me/albums).&#xA;&#xA;WriteFreely&#xA;&#xA;There&#39;s honestly not a lot to write about here. It&#39;s a static binary that I just downloaded and configured with the wizard. Everything just worked (I used the SQLite backend rather than MySQL) and it has everything I want and nothing that I don&#39;t.&#xA;&#xA;Conclusion&#xA;&#xA;This is honestly just a plug for the different services I&#39;ve setup. Our PeerTube is here. Albums shared through Ente can be found here. And, of course, you&#39;re already on the blog!]]&gt;</description>
      <content:encoded><![CDATA[<p>I want to expand on my previous post a little bit to explain the steps I took to setup PeerTube, Ente, and WriteFreely.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>I set everything up on two different VPSs. PeerTube was on a new domain, so I used an Ionos VPS. Ente and WriteFreely are on my main VPS (powering this website) since they were on subdomains of this domain.</p>

<p>All intensive storage (photos and videos) happens on <a href="https://www.backblaze.com/cloud-storage">Backblaze B2</a>. I love Backblaze for its reliably cheap storage and excellent APIs (including, crucially for this use-case, S3-compatible APIs).</p>



<h2 id="peertube">PeerTube</h2>

<p>I first followed the steps <a href="https://docs.joinpeertube.org/install/any-os">here</a> to do the basic setup. I followed all of those instructions (including setting up the reverse proxy and <code>systemd</code> service. Because this is a fresh VPS, I did not have any port conflicts (this was not the case with the others as will be clear) and I could use the support reverse proxy (<code>nginx</code>).</p>

<p>Then, it was time to setup the object storage according to <a href="https://docs.joinpeertube.org/maintain/remote-storage">this page</a>. I went to Backblaze B2, created a new bucket for PeerTube, and made it public. Then, I generated an application key (restricted only to <em>that bucket</em>), ensuring that the key had the ability to list all buckets (necessary for an S3-compatible key). Then, all I had to do was fill in all of the information in <code>config/production.yaml</code> according to the documentation, restart PeerTube (<code>systemctl restart peertube</code>), and I was good to go!</p>

<p>Initially, I had disabled transcoding, opting only to keep one resolution of the video (effectively just the original file). I later enabled HLS transcoding and manually ran the HLS transcoding jobs on the uploaded videos (possible through the admin interface). Everything went smoothly and the existing videos were (slowly) transcoded. I say slowly simply because the VPS only has 2 cores, so I can&#39;t really run transcoding jobs in parallel.</p>

<p>I initially had tried to setup a <a href="https://docs.joinpeertube.org/admin/remote-runners">remote runner</a>, but it was having trouble with transcoding large files, so I disabled it for now. I will probably retry the runner with the next upload and see how it goes.</p>

<h2 id="ente">Ente</h2>

<p>I had initially tried self-hosting Ente a few months ago when I first heard about it after asking for a self-hosted gallery with object storage support over on Mastodon. However, while I was able to get it up and running, I was running into issues completing the registration and getting the object storage backend up and running, so I gave up.</p>

<p>Then, about a week ago, I decided to try again and actually got it working. I followed the <a href="https://ente.com/help/self-hosting/installation/quickstart">self-hosting directions</a> and got it installed, but I kept running into CORS issues when I attempted to register (the same issue I ran into earlier).</p>

<p>I then realized that I had to set the <code>environment</code> block in <code>compose.yaml</code> to the IP address (rather than <code>localhost</code>), and that was enough to get it working. I then similarly set up a bucket in B2 for Ente and set up the <a href="https://ente.com/help/self-hosting/administration/object-storage">object storage backend</a>. I then tried a few test uploads and it worked!</p>

<p>When I went to configure the reverse-proxy, I had to set it up with <code>apache</code> instead of <code>nginx</code> because <code>apache</code> was already being used for my main web server. There are numerous guides for doing it, so I won&#39;t elaborate here, but it&#39;s pretty straightforward.</p>

<p>What I also hadn&#39;t realized originally was that I needed to enable all of the components on <em>sub</em>domains. For example, the main Ente domain is <a href="https://photos.chiraag.me">https://photos.chiraag.me</a>, and all of the sub-components needed to be hosted on subdomains of that (e.g. <a href="https://api.photos.chiraag.me">https://api.photos.chiraag.me</a> and so on —– I just used the standard subdomain names given in the documentation). Once I had configured this, added all of the subdomain reverse proxy entries, and used <code>cerbot --apache</code> to generate the SSL certificates (or, more accurately, expand the existing one to cover the new subdomains), everything worked great. Everything is automatically encrypted client-side, then uploaded to my B2 bucket. Then I can create public albums and share them (like at <a href="https://chiraag.me/albums">https://chiraag.me/albums</a>).</p>

<h2 id="writefreely">WriteFreely</h2>

<p>There&#39;s honestly not a lot to write about here. It&#39;s a static binary that I just downloaded and configured with the wizard. Everything just worked (I used the SQLite backend rather than MySQL) and it has everything I want and nothing that I don&#39;t.</p>

<h2 id="conclusion">Conclusion</h2>

<p>This is honestly just a plug for the different services I&#39;ve setup. Our PeerTube is <a href="https://%E0%B2%AE%E0%B2%BF%E0%B2%B2%E0%B2%A8.net">here</a>. Albums shared through Ente can be found <a href="https://chiraag.me/albums">here</a>. And, of course, you&#39;re already on the blog!</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/how-i-set-up-my-self-hosted-services</guid>
      <pubDate>Sat, 25 Apr 2026 22:35:55 +0000</pubDate>
    </item>
    <item>
      <title>My self-hosting journey</title>
      <link>https://blog.chiraag.me/my-self-hosting-journey</link>
      <description>&lt;![CDATA[Not too long ago, I was not self-hosting anything (other than building my website from scratch). It&#39;s not because I couldn&#39;t (I have enough GNU/Linux knowledge and I&#39;ve programmed in a fair bunch of languages), but because it felt too complicated and involved.&#xA;&#xA;All of that changed about a week ago.&#xA;&#xA;!--more--&#xA;&#xA;I had been thinking of self-hosting stuff for a while (an image gallery, a blog, and perhaps even a site for videos). The main problem I kept running into is that storage on VPSs is quite expensive, so I needed software with object storage support (I prefer Backblaze B2). A lot of image gallery software, for example, handles local images fine but doesn&#39;t have built-in support for S3-type storage.&#xA;&#xA;Ironically enough, I started with PeerTube. It&#39;s the most storage-intensive of the services I have started hosting, but it has object storage support so I set it up with a B2 bucket. Setting it up was relatively easy and things magically show up across the Fediverse (it&#39;s still amazing to me how seamlessly it happens). I still need to setup transcoding, but that&#39;s the last bit.&#xA;&#xA;The next one was Ente. Interestingly, I had started configuring this a while ago, ran into problems with the object storage configuration, and gave up. I decided to give it another go and actually got everything set up this time! It&#39;s a little complicated because they have several different services that should be run on separate subdomains (the docs do a decent job of explaining it), but after a bit of fiddling I have the main interface (for authorized users to upload photos), the albums subdomain (for public albums), and the embed subdomain (for embedding public albums in other pages) and everything works.&#xA;&#xA;The final bit was actually easiest: this blog (through WriteFreely. I imported my old blog posts (from my previous WordPress-powered blog) and everything pretty much worked without a hitch.&#xA;&#xA;The coolest part is that uploaded videos and blog posts (like this) automatically federate with the rest of the Fediverse. I have a Mastodon account, so you can reach out to me there about my posts (WriteFreely currently does not have comments, so the easiest way to discuss it is to tag my Mastodon profile in your replies to this post).&#xA;&#xA;I am more than happy to discuss how I set these services up. Everything is on VPSs (WriteFreely and Ente are on the VPS for this website, PeerTube is on a different VPS for the other domain) and most stuff is relatively minimal in terms of resource footprint (PeerTube is relatively heavy and needs... 2 GB of RAM and 2 cores!). It&#39;s way more accessible than I had thought, and I am definitely glad I bit the bullet and looked into this.&#xA;&#xA;Take control of your digital life!]]&gt;</description>
      <content:encoded><![CDATA[<p>Not too long ago, I was not self-hosting anything (other than building my website from scratch). It&#39;s not because I couldn&#39;t (I have enough GNU/Linux knowledge and I&#39;ve programmed in a fair bunch of languages), but because it <em>felt</em> too complicated and involved.</p>

<p>All of that changed about a week ago.</p>



<p>I had been thinking of self-hosting stuff for a while (an image gallery, a blog, and perhaps even a site for videos). The main problem I kept running into is that storage on VPSs is quite expensive, so I needed software with object storage support (I prefer Backblaze B2). A lot of image gallery software, for example, handles local images fine but doesn&#39;t have built-in support for S3-type storage.</p>

<p>Ironically enough, I started with <a href="https://joinpeertube.org">PeerTube</a>. It&#39;s <em>the</em> most storage-intensive of the services I have started hosting, but it has object storage support so I set it up with a B2 bucket. Setting it up was relatively easy and things magically show up across the Fediverse (it&#39;s still amazing to me how seamlessly it happens). I still need to setup transcoding, but that&#39;s the last bit.</p>

<p>The next one was <a href="https://ente.io">Ente</a>. Interestingly, I had started configuring this a while ago, ran into problems with the object storage configuration, and gave up. I decided to give it another go and actually got everything set up this time! It&#39;s a little complicated because they have several different services that should be run on separate subdomains (the docs do a decent job of explaining it), but after a bit of fiddling I have the main interface (for authorized users to upload photos), the albums subdomain (for public albums), and the embed subdomain (for embedding public albums in other pages) and everything works.</p>

<p>The final bit was actually easiest: this blog (through <a href="https://writefreely.org">WriteFreely</a>. I imported my old blog posts (from my previous WordPress-powered blog) and everything pretty much worked without a hitch.</p>

<p>The coolest part is that uploaded videos and blog posts (like this) automatically federate with the rest of the Fediverse. I have a <a href="https://mastodon.online/@chiraag">Mastodon</a> account, so you can reach out to me there about my posts (WriteFreely currently does not have comments, so the easiest way to discuss it is to tag my Mastodon profile in your replies to this post).</p>

<p>I am more than happy to discuss how I set these services up. Everything is on VPSs (WriteFreely and Ente are on the VPS for this website, PeerTube is on a different VPS for the other domain) and most stuff is relatively minimal in terms of resource footprint (PeerTube is relatively heavy and needs... 2 GB of RAM and 2 cores!). It&#39;s way more accessible than I had thought, and I am definitely glad I bit the bullet and looked into this.</p>

<p>Take control of your digital life!</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/my-self-hosting-journey</guid>
      <pubDate>Fri, 24 Apr 2026 22:32:24 +0000</pubDate>
    </item>
    <item>
      <title>Rethinking the Calendar and Our Measures of Time</title>
      <link>https://blog.chiraag.me/rethinking-the-calendar-and-our-measures-of-time</link>
      <description>&lt;![CDATA[We all know the Gregorian calendar, right? It&#39;s the &#34;standard&#34; one, with 12 months, each one with a variable number of days from 28 to 31. And we may not love it, but we use it. But what if...there were a better way?&#xA;&#xA;I started thinking about this at first when I watched Kurzgesagt&#39;s a href=&#34;https://www.youtube.com/watch?v=czgOWmtGVGs&#34;video/a, which argues that we should find a new year &#34;0&#34; that better reflects the sheer magnitude of all that we have accomplished as a species. They end up settling on 10000 BC/BCE as the appropriate year &#34;0&#34;, for reasons that they describe in the video. In practice, in order to use the Human Era system, we just tack on an extra &#34;1&#34; at the beginning of the year. So the year 2020 AD/CE becomes the year 12,020 HE (Human Era).&#xA;&#xA;That got me thinking, though, that there must be a better way to distribute the days of the year. I mean, the sheer madness that is the Gregorian calendar would be hilarious if it weren&#39;t so ingrained into us. Instead of each month having a fixed number of days (possibly with some minor adjustment at the end to account for imperfections), we end up with a monstrosity where you have to memorize the number of days in each month. Of course, this happened because the calendar was iteratively refined due to increased knowledge about exactly how long one revolution around the sun takes, adding/subtracting months to please Roman emperors, and so on. But if we were to design a calendar from scratch, what might it look like?&#xA;&#xA;!--more--&#xA;&#xA;Well, a standard year (ignoring leap years for a second) has 365 days. The prime factors of 365 are 73 and 5, so let&#39;s assign 5 days to a week, instead of the current 7. This leaves us with a year that has 73 full weeks. Now, unfortunately 73 is prime, but 72 --- 72 is a number we can work very nicely with. 72 gives us prime factors of 3,3,2,2,2. This means that we can have 18 months with 4 weeks each, 9 months with 8 weeks each, or even 36 months with 2 weeks each if we want. Let&#39;s go with 9 months of 8 weeks each for now. This leaves the last week --- the leap week, as it were --- by itself. We can call that the 10th month or leave it by itself --- either way, it just hangs out at the end of the year. &#xA;&#xA;What happens in a leap year? Just tack on the leap day to the end of the leap week. This design ensures that all of the first 9 months are completely untouched every single year. The same date falls on the same day of the year, every single year. No shifting dates. No memorizing how many days a month has. It&#39;s nice and simple.&#xA;&#xA;We can do a similar thing with time, too. Why exactly do we have 24 hours in a day, with 60 minutes per hour and 60 seconds per minute? Why not have nice, round, powers of 10 for each of those conversions? In this case, however, we will have to redefine the second. Let us define that 1 day has 100,000 seconds. If we set reasonable conversions of 100 seconds per minute and 100 minutes per hour, this gets us a nice, even 10 hours per day.&#xA;&#xA;Unfortunately, this means that a second under this system is quite a bit shorter than a second in the current system. To be exact, one new second is 0.864 current seconds. That is, unlike the new calendar system which is day-for-day compatible with the current calendar system, this new system of measuring time has conversion factors.&#xA;&#xA;In summary, here is the new system I am proposing (and have implemented on my laptop):&#xA;&#xA;ul&#xA;li100 seconds per minute/li&#xA;li100 minutes per hour/li&#xA;li10 hours per day/li&#xA;li5 days per week/li&#xA;li8 weeks per month/li&#xA;li9 months per year with a leap week to round out the year (so effectively 9.125 months or 10 months where the 10th month is highly irregular, whichever you prefer)/li&#xA;liOn leap years, the leap week gets a leap day/li&#xA;liAdd 10000 to the current year to utilize Human Era years/li&#xA;/ul&#xA;&#xA;Also, days and months should be 0-indexed as our hours (in 24-hour time), minutes, seconds, and years are. So month numbers go from 0 to 8 (or 9 if you could the last week as a month) and day numbers go from 0 to 39.&#xA;&#xA;This is certainly a change from our current way of measuring and dealing with time. But I tend to view this as a much more rational approach, one that better incorporates the additional knowledge we now have. Additionally, it makes the calendar as regular as humanly possible. The same holds true for the new time system --- indeed, it&#39;s far more regular than even the new calendar system. It takes adjustment, but so does emany/em new system. That&#39;s what happens when everyone is brought up on a particular system. It&#39;s why transitioning between operating systems can be so painful, or daring to dream big about systemic change can feel scary. We find comfort in the familiar but sometimes...the familiar just emreally/em sucks.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>We all know the Gregorian calendar, right? It&#39;s the “standard” one, with 12 months, each one with a variable number of days from 28 to 31. And we may not love it, but we use it. But what if...there were a better way?</p>

<p>I started thinking about this at first when I watched Kurzgesagt&#39;s <a href="https://www.youtube.com/watch?v=czgOWmtGVGs">video</a>, which argues that we should find a new year “0” that better reflects the sheer magnitude of all that we have accomplished as a species. They end up settling on 10000 BC/BCE as the appropriate year “0”, for reasons that they describe in the video. In practice, in order to use the Human Era system, we just tack on an extra “1” at the beginning of the year. So the year 2020 AD/CE becomes the year 12,020 HE (Human Era).</p>

<p>That got me thinking, though, that there must be a better way to distribute the days of the year. I mean, the sheer madness that is the Gregorian calendar would be hilarious if it weren&#39;t so ingrained into us. Instead of each month having a fixed number of days (possibly with some minor adjustment at the end to account for imperfections), we end up with a monstrosity where you have to memorize the number of days in each month. Of course, this happened because the calendar was iteratively refined due to increased knowledge about exactly how long one revolution around the sun takes, adding/subtracting months to please Roman emperors, and so on. But if we were to design a calendar from scratch, what might it look like?</p>



<p>Well, a standard year (ignoring leap years for a second) has 365 days. The prime factors of 365 are 73 and 5, so let&#39;s assign 5 days to a week, instead of the current 7. This leaves us with a year that has 73 full weeks. Now, unfortunately 73 is prime, but 72 —– 72 is a number we can work very nicely with. 72 gives us prime factors of 3,3,2,2,2. This means that we can have 18 months with 4 weeks each, 9 months with 8 weeks each, or even 36 months with 2 weeks each if we want. Let&#39;s go with 9 months of 8 weeks each for now. This leaves the last week —– the leap week, as it were —– by itself. We can call that the 10th month or leave it by itself —– either way, it just hangs out at the end of the year.</p>

<p>What happens in a leap year? Just tack on the leap day to the end of the leap week. This design ensures that all of the first 9 months are completely untouched every single year. The same date falls on the same day of the year, every single year. No shifting dates. No memorizing how many days a month has. It&#39;s nice and simple.</p>

<p>We can do a similar thing with time, too. Why exactly do we have 24 hours in a day, with 60 minutes per hour and 60 seconds per minute? Why not have nice, round, powers of 10 for each of those conversions? In this case, however, we will have to redefine the second. Let us define that 1 day has 100,000 seconds. If we set reasonable conversions of 100 seconds per minute and 100 minutes per hour, this gets us a nice, even 10 hours per day.</p>

<p>Unfortunately, this means that a second under this system is quite a bit shorter than a second in the current system. To be exact, one new second is 0.864 current seconds. That is, unlike the new calendar system which is day-for-day compatible with the current calendar system, this new system of measuring time has conversion factors.</p>

<p>In summary, here is the new system I am proposing (and have implemented on my laptop):</p>

<ul><li>100 seconds per minute</li>
<li>100 minutes per hour</li>
<li>10 hours per day</li>
<li>5 days per week</li>
<li>8 weeks per month</li>
<li>9 months per year with a leap week to round out the year (so effectively 9.125 months or 10 months where the 10th month is highly irregular, whichever you prefer)</li>
<li>On leap years, the leap week gets a leap day</li>
<li>Add 10000 to the current year to utilize Human Era years</li></ul>

<p>Also, days and months should be 0-indexed as our hours (in 24-hour time), minutes, seconds, and years are. So month numbers go from 0 to 8 (or 9 if you could the last week as a month) and day numbers go from 0 to 39.</p>

<p>This is certainly a change from our current way of measuring and dealing with time. But I tend to view this as a much more rational approach, one that better incorporates the additional knowledge we now have. Additionally, it makes the calendar as regular as humanly possible. The same holds true for the new time system —– indeed, it&#39;s far more regular than even the new calendar system. It takes adjustment, but so does <em>any</em> new system. That&#39;s what happens when everyone is brought up on a particular system. It&#39;s why transitioning between operating systems can be so painful, or daring to dream big about systemic change can feel scary. We find comfort in the familiar but sometimes...the familiar just <em>really</em> sucks.</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/rethinking-the-calendar-and-our-measures-of-time</guid>
      <pubDate>Sun, 18 Oct 2020 07:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Managing multiple email accounts with Mutt and Fetchmail</title>
      <link>https://blog.chiraag.me/managing-multiple-email-accounts-with-mutt-and-fetchmail</link>
      <description>&lt;![CDATA[Recently, I switched to a href=&#34;https://protonmail.com&#34;ProtonMail/a as a way of increasing my privacy online and moving away from the &#34;data as currency&#34; model of Google and Facebook (as part of this same effort, I closed my Facebook in favor of creating this blog!). However, most of what I describe here has been my setup for a while due to my penchant for two things:&#xA;ol&#xA;  liWanting to keep my emails backed up (and a local copy always at hand)./li&#xA;  liWanting a simple but powerful email reader so that it gets out of the way while enabling as much customization as needed./li&#xA;/ol&#xA;At the same time, I wanted a system where I could easily add and remove accounts while adding/removing as little configuration as possible, and this informs the way I partition my configuration files (as will be apparent).&#xA;&#xA;As the title suggests, there are two different parts to this setup: kbdfetchmail/kbd and kbdmutt/kbd.&#xA;&#xA;!--more--&#xA;&#xA;Since kbdfetchmail/kbd does not natively provide for encryption of the configuration file (and the file contains sensitive information), I wrote a wrapper around it which decrypts the file and passes it to kbdfetchmail/kbd via kbdstdin/kbd. That part will not be discussed here and can be set up after glancing at the kbdfetchmail/kbd manual page (in short, do something like kbdgpg -d -o - /path/to/encrypted/config | fetchmail -d &amp;lt;n&amp;gt; -f -/kbd).&#xA;&#xA;As for the configuration file itself, this should serve as a good template:&#xA;precodeset postmaster &#34;&amp;lt;local username&amp;gt;&#34;&#xA;set bouncemail&#xA;set no spambounce&#xA;set softbounce&#xA;set properties &#34;&#34;&#xA;poll &amp;lt;imap server&amp;gt; with proto IMAP&#xA;       user &#39;username&#39; there with password &#39;password&#39; is &#39;&amp;lt;local username&amp;gt;&#39; here&#xA;       options keep ssl sslproto &#34;TLS1+&#34; mda &#34;&amp;lt;mda&amp;gt; $HOME/.local/mail/Gmail/&#34;&#xA;  folder &#34;&amp;lt;folder&amp;gt;&#34;&#xA;/code/pre&#xA;You can replicate the last bit (kbdpoll ...folder &#34;&amp;lt;folder&amp;gt;&#34;/kbd) as many times as you need to add multiple accounts. kbd&amp;lt;local username&amp;gt;/kbd is the username you want mail to be delivered under (I recommend running kbdfetchmail/kbd as emyour user/em unless there are extenuating circumstances). kbdusername/kbd and kbdpassword/kbd are self-explanatory. The exact structure of kbd&amp;lt;folder&amp;gt;/kbd can differ based on the server (for example, with Gmail, some folders require a prefix of kbd[Gmail]/kbd), but usually kbdInbox/kbd will work without any prefix. Oh, and kbd/kbd is a Mail Delivery Agent — you&#39;ll want one that delivers to a emmaildir/em. The one I use is the stand-alone MDA from kbdgetmail/kbd called kbdgetmailmaildir/kbd and requires no configuration.&#xA;&#xA;embA special note for Protonmail Bridge users/b/em: In the kbdoptions/kbd section, you&#39;ll want kbdkeep no sslcertck sslfingerprint &#34;48:63:2E:30:62:FC:23:B3:9A:42:CD:02:1E:FF:F8:52&#34;/kbd since otherwise kbdfetchmail/kbd will throw an error as the Bridge&#39;s certificate isn&#39;t trusted.&#xA;&#xA;At this point, kbdfetchmail/kbd should be good to go. Before you try running it, you should create the maildirs you setup in the kbdfetchmail/kbd config. This is really easy; if the kbdmaildir/kbd is kbd$DIR/kbd, you can just run kbdmkdir -p $DIR/{cur,tmp,new}/kbd and you&#39;re done. Now, you can try running kbdfetchmail -f /path/to/config/file/kbd. If all goes well and you don&#39;t have any unread emails, kbdfetchmail/kbd should exit normally without downloading any emails. At this point, I&#39;d run kbdfetchmail -a -f /path/to/config/file/kbd to get a copy of emall/em emails, read or not. Note that kbdfetchmail/kbd uses whether an email is read to determine whether or not to download it.&#xA;&#xA;The next piece of the puzzle is kbdmutt/kbd. All of my kbdmutt/kbd configuration goes in kbd~/.config/mutt/muttrc/kbd. I have a master RC file that looks something like this (along with many other variables that I won&#39;t go into here):&#xA;precodeset folder=&#34;~/.local/mail&#34;&#xA;&#xA;mailboxes &#34;+Gmail&#34; &#34;+Brown&#34; &#34;+CaltechAlumni&#34; &#34;+ProtonMail&#34; &#34;+ProtonMail-Custom&#34;&#xA;&#xA;folder-hook Brown &#39;source ~/.config/mutt/muttrc/muttrc.localb; macro index cb &#39;&#xA;folder-hook Gmail &#39;source ~/.config/mutt/muttrc/muttrc.localg; macro index cg &#39;&#xA;folder-hook CaltechAlumni &#39;source ~/.config/mutt/muttrc/muttrc.localca; macro index ca &#39;&#xA;folder-hook ProtonMail &#39;source ~/.config/mutt/muttrc/muttrc.localp; macro index cp &#39;&#xA;folder-hook ProtonMail-Custom &#39;source ~/.config/mutt/muttrc/muttrc.localpc; macro index cq &#39;&#xA;&#xA;source ~/.config/mutt/muttrc/muttrc.macros&#xA;/code/pre&#xA;In my case, I store all of my email in kbd~/.local/mail/kbd, so I set that as the &#34;base&#34; location, if you will, by setting the kbdfolder/kbd variable. Then, kbd+Gmail/kbd expands to kbd~/.local/mail/Gmail/kbd. In this way, I don&#39;t need to spell out the full location for each mailbox.&#xA;&#xA;Additionally, when I switch mailboxes, I load a mailbox-specific config file. For example, the Gmail one looks like this:&#xA;precodeset spoolfile=&#34;~/.local/mail/Gmail&#34;&#xA;&#xA;set smtpurl=&#34;smtps://chiraag.nataraj\@gmail.com@smtp.gmail.com/&#34;&#xA;set from=&#34;ಚಿರಾಗ್ ನಟರಾಜ್ &amp;lt;chiraag.nataraj@gmail.com&amp;gt;&#34;&#xA;set realname=&#34;ಚಿರಾಗ್ ಮಂಜುನಾಥ ನಟರಾಜ್&#34;&#xA;set imapuser=chiraag.nataraj@gmail.com&#xA;set record=&#34;^&#34;&#xA;&#xA;set signature=&#34;~/.config/mutt/signatures/signature.home&#34;&#xA;set headercache=~/.cache/mutt/muttcache.gmail&#xA;&#xA;send-hook . &#34;source &#39;gpg -d ~/.config/mutt/muttsecure/gmail.password.gpg |&#39;&#34;&#xA;&#xA;source ~/.config/mutt/muttrc/muttrc.macros&#xA;source ~/.config/mutt/muttrc/muttrc.autocrypt&#xA;/code/pre&#xA;In other words, I set the SMTP URL (for sending email from this mailbox), name, signature, and so on. Additionally, I tell it to decrypt the file containing the password for my Gmail account before opening up my editor to compose an email. This means I don&#39;t need to needlessly decrypt the file until necessary.&#xA;&#xA;You might notice this kbdmutt.macros/kbd thing lying around. That file looks like this:&#xA;precodemacro index ca &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/mutt/muttrc/muttrc.localca&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;&#xA;macro index cb &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/mutt/muttrc/muttrc.localb&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;&#xA;macro index cg &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/mutt/muttrc/muttrc.localg&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;&#xA;macro index cp &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/mutt/muttrc/muttrc.localp&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;&#xA;/code/pre&#xA;This is just an easy way for me to switch between different mailboxes. Each of my mailbox-specific config files sources this file. In the kbdfolder-hook/kbd, I then &#39;reset&#39; the macro for the emcurrent/em mailbox to simply refresh the screen (basically a no-op).&#xA;&#xA;This system means that if I want to add a new mailbox to kbdmutt/kbd, I do the following:&#xA;ol&#xA; &#x9;liCreate a new mailbox-specific config file with the necessary details./li&#xA; &#x9;liAdd the mailbox to my master configuration file./li&#xA; &#x9;liAdd a keybinding for switching to that mailbox to kbdmutt.macros/kbd./li&#xA;/ol&#xA;In addition, I need to do silly things like creating a mailbox-specific signature and stuff, but that&#39;s not too bad.&#xA;&#xA;With some work, I could probably even automate the current system for adding a mailbox, but I am fairly satisfied with how the system currently works.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>Recently, I switched to <a href="https://protonmail.com">ProtonMail</a> as a way of increasing my privacy online and moving away from the “data as currency” model of Google and Facebook (as part of this same effort, I closed my Facebook in favor of creating this blog!). However, most of what I describe here has been my setup for a while due to my penchant for two things:
<ol>  <li>Wanting to keep my emails backed up (and a local copy always at hand).</li>
  <li>Wanting a simple but powerful email reader so that it gets out of the way while enabling as much customization as needed.</li></ol>
At the same time, I wanted a system where I could easily add and remove accounts while adding/removing as little configuration as possible, and this informs the way I partition my configuration files (as will be apparent).</p>

<p>As the title suggests, there are two different parts to this setup: fetchmail and mutt.</p>



<p>Since fetchmail does not natively provide for encryption of the configuration file (and the file contains sensitive information), I wrote a wrapper around it which decrypts the file and passes it to fetchmail via stdin. That part will not be discussed here and can be set up after glancing at the fetchmail manual page (in short, do something like gpg -d -o – /path/to/encrypted/config | fetchmail -d &lt;n&gt; -f -).</p>

<p>As for the configuration file itself, this should serve as a good template:
<pre><code>set postmaster “&lt;local username&gt;“
set bouncemail
set no spambounce
set softbounce
set properties “”
poll &lt;imap server&gt; with proto IMAP
       user &#39;username&#39; there with password &#39;password&#39; is &#39;&lt;local username&gt;&#39; here
       options keep ssl sslproto “TLS1+” mda “&lt;mda&gt; $HOME/.local/mail/Gmail/”
  folder “&lt;folder&gt;“
</code></pre>
You can replicate the last bit (poll ...folder “&lt;folder&gt;“) as many times as you need to add multiple accounts. &lt;local username&gt; is the username you want mail to be delivered under (I recommend running fetchmail as <em>your user</em> unless there are extenuating circumstances). username and password are self-explanatory. The exact structure of &lt;folder&gt; can differ based on the server (for example, with Gmail, some folders require a prefix of [Gmail]), but usually Inbox will work without any prefix. Oh, and  is a Mail Delivery Agent — you&#39;ll want one that delivers to a <em>maildir</em>. The one I use is the stand-alone MDA from getmail called getmail_maildir and requires no configuration.</p>

<p><em><b>A special note for Protonmail Bridge users</b></em>: In the options section, you&#39;ll want keep no sslcertck sslfingerprint “48:63:2E:30:62:FC:23:B3:9A:42:CD:02:1E:FF:F8:52” since otherwise fetchmail will throw an error as the Bridge&#39;s certificate isn&#39;t trusted.</p>

<p>At this point, fetchmail should be good to go. Before you try running it, you should create the maildirs you setup in the fetchmail config. This is really easy; if the maildir is $DIR, you can just run mkdir -p $DIR/{cur,tmp,new} and you&#39;re done. Now, you can try running fetchmail -f /path/to/config/file. If all goes well and you don&#39;t have any unread emails, fetchmail should exit normally without downloading any emails. At this point, I&#39;d run fetchmail -a -f /path/to/config/file to get a copy of <em>all</em> emails, read or not. Note that fetchmail uses whether an email is read to determine whether or not to download it.</p>

<p>The next piece of the puzzle is mutt. All of my mutt configuration goes in ~/.config/mutt/muttrc. I have a master RC file that looks something like this (along with many other variables that I won&#39;t go into here):
<pre><code>set folder=”~/.local/mail”</p>

<p>mailboxes “+Gmail” “+Brown” “+CaltechAlumni” “+ProtonMail” “+ProtonMail-Custom”</p>

<p>folder-hook Brown &#39;source ~/.config/mutt/muttrc/muttrc.localb; macro index cb &#39;
folder-hook Gmail &#39;source ~/.config/mutt/muttrc/muttrc.localg; macro index cg &#39;
folder-hook CaltechAlumni &#39;source ~/.config/mutt/muttrc/muttrc.localca; macro index ca &#39;
folder-hook ProtonMail &#39;source ~/.config/mutt/muttrc/muttrc.localp; macro index cp &#39;
folder-hook ProtonMail-Custom &#39;source ~/.config/mutt/muttrc/muttrc.localpc; macro index cq &#39;</p>

<p>source ~/.config/mutt/muttrc/muttrc.macros
</code></pre>
In my case, I store all of my email in ~/.local/mail, so I set that as the “base” location, if you will, by setting the folder variable. Then, +Gmail expands to ~/.local/mail/Gmail. In this way, I don&#39;t need to spell out the full location for each mailbox.</p>

<p>Additionally, when I switch mailboxes, I load a mailbox-specific config file. For example, the Gmail one looks like this:
<pre><code>set spoolfile=”~/.local/mail/Gmail”</p>

<p>set smtp<em>url=“smtps://chiraag.nataraj\<a href="https://blog.chiraag.me/@/gmail.com@smtp.gmail.com" class="u-url mention">@<span>gmail.com@smtp.gmail.com</span></a>/”
set from=“ಚಿರಾಗ್ ನಟರಾಜ್ &lt;chiraag.nataraj@gmail.com&gt;“
set realname=“ಚಿರಾಗ್ ಮಂಜುನಾಥ ನಟರಾಜ್”
set imap</em>user=chiraag.nataraj@gmail.com
set record=“^”</p>

<p>set signature=”~/.config/mutt/signatures/signature.home”
set header<em>cache=~/.cache/mutt/mutt</em>cache.gmail</p>

<p>send-hook . “source &#39;gpg -d ~/.config/mutt/mutt_secure/gmail.password.gpg |&#39;”</p>

<p>source ~/.config/mutt/muttrc/muttrc.macros
source ~/.config/mutt/muttrc/muttrc.autocrypt
</code></pre>
In other words, I set the SMTP URL (for sending email from this mailbox), name, signature, and so on. Additionally, I tell it to decrypt the file containing the password for my Gmail account before opening up my editor to compose an email. This means I don&#39;t need to needlessly decrypt the file until necessary.</p>

<p>You might notice this mutt.macros thing lying around. That file looks like this:
<pre><code>macro index ca &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.config/mutt/muttrc/muttrc.localca&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;
macro index cb &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.config/mutt/muttrc/muttrc.localb&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;
macro index cg &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.config/mutt/muttrc/muttrc.localg&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;
macro index cp &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.config/mutt/muttrc/muttrc.localp&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;
</code></pre>
This is just an easy way for me to switch between different mailboxes. Each of my mailbox-specific config files sources this file. In the folder-hook, I then &#39;reset&#39; the macro for the <em>current</em> mailbox to simply refresh the screen (basically a no-op).</p>

<p>This system means that if I want to add a new mailbox to mutt, I do the following:
<ol>    <li>Create a new mailbox-specific config file with the necessary details.</li>
    <li>Add the mailbox to my master configuration file.</li>
    <li>Add a keybinding for switching to that mailbox to mutt.macros.</li></ol>
In addition, I need to do silly things like creating a mailbox-specific signature and stuff, but that&#39;s not too bad.</p>

<p>With some work, I could probably even automate the current system for adding a mailbox, but I am fairly satisfied with how the system currently works.</p>
]]></content:encoded>
      <guid>https://blog.chiraag.me/managing-multiple-email-accounts-with-mutt-and-fetchmail</guid>
      <pubDate>Wed, 21 Aug 2019 07:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>