<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Just's Blog]]></title><description><![CDATA[Ideas & Thoughts + Code]]></description><link>https://justrox.me/</link><image><url>https://justrox.me/favicon.png</url><title>Just&apos;s Blog</title><link>https://justrox.me/</link></image><generator>Ghost 5.82</generator><lastBuildDate>Sat, 17 Jan 2026 04:41:45 GMT</lastBuildDate><atom:link href="https://justrox.me/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Naive Attempts, Sharp Insights: Collected Aphorisms on the Road to AGI]]></title><description><![CDATA[<p>I&apos;m trying to create an agent&#x2014;hopefully a step toward AGI&#x2014;without fully knowing what I&apos;m doing. Just curiosity, ambition, and a lot of guesswork. Along the way, I&#x2019;ve picked up thoughts and lessons&#x2014;about complex systems, fractality, and beauty. Some</p>]]></description><link>https://justrox.me/braindump-for-reaching-agi/</link><guid isPermaLink="false">68034bfca933c80008642cdc</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Sat, 19 Apr 2025 07:15:09 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1574577457058-5cefa266a7e8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGZyYWN0YWwlMjBtaW5kfGVufDB8fHx8MTc0NTA0Njg4MXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1574577457058-5cefa266a7e8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGZyYWN0YWwlMjBtaW5kfGVufDB8fHx8MTc0NTA0Njg4MXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Naive Attempts, Sharp Insights: Collected Aphorisms on the Road to AGI"><p>I&apos;m trying to create an agent&#x2014;hopefully a step toward AGI&#x2014;without fully knowing what I&apos;m doing. Just curiosity, ambition, and a lot of guesswork. Along the way, I&#x2019;ve picked up thoughts and lessons&#x2014;about complex systems, fractality, and beauty. Some feel useful, others are still confusing, and most remain unfinished. This is a collection of those fragments&#x2014;short notes and insights from someone still finding their way.</p><!--members-only--><h3 id="motivation-goals-and-learning">Motivation, Goals, and Learning</h3><ol><li>Dreams, goals, and purpose are a volatile stack of expectations.</li><li>A human&#x2019;s learning hyperparameter is the fear-to-curiosity ratio.</li><li>To learn is to both remember and forget. Specification demands memory; generalization, letting go.</li><li>Long-term memory is a graph of events; short-term memory is a set of floating contexts.</li><li>We generalize through expectation; we differentiate through surprise.</li><li>We generalize by letting go of the contexts tied to an event; we differentiate by anchoring the current floating contexts to it.</li><li>Recollection is the delicate dance between similarity search of contexts and simulation of events.</li><li>Excitement is the caching of confident actions, motivated to flush them when expectations are reached.</li><li>Curing any obsession or addiction involves tolerating actions you&apos;re not confident with. Likewise, always taking confident actions makes you prone to addiction and obsession.</li></ol><h3 id="creativity-decision-making-and-problem-solving">Creativity, decision-making, and problem solving</h3><ol><li>Creativity arises when a goal is clear, but the connection between state A and state B is yet to be made.</li><li>Creativity is navigating uncertainty.</li><li>Navigating uncertainty is a delicate dance between curiosity and fear.</li><li>Navigating uncertainty is a cycle of ranking options and making decisions until you get your expectations. Different creatures ranks and evaluate decisions differently.</li><li>Fearful creatures ranks options by data, and evaluates based on gut. Curious creatures ranks options by gut, and evaluates based on data.</li><li>Fearful creatures&apos; pitfall is quitting when they have no data.</li><li>Curious creatures&apos; pitfall is unbounded hallucination.</li><li>Guessing all possible paths requires significant operational resources, which is why we often do it concurrently in our minds&#x2014;through brainstorming.</li><li>The key difference between humans and other beings may lie in our ability to guess more accurately.</li><li>Likewise, good faith AGI robots or quantum computer minds will probably find our guesswork as cute as we find a dog&apos;s attempts to guess. I wonder if my cat thinks the same of a cockroach&#x2019;s guesswork.</li><li>Bad faith AGI or quantum minds may not find our guesswork cute&#x2014;they may see it as annoying, or worse, an obstacle.</li></ol><h3 id="free-will">Free will</h3><ol><li>Having free will is very different from demonstrating it. I&#x2019;m not even sure that the former is possible.</li><li>An AGI demonstrates free will when it decides to purposely set intermediate goals to distract itself from its own purpose.</li><li>In precise terms, an agent demonstrates free will when, through ranking, evaluation, and contextual association, it determines that its next best action diverges with the first item in its original stack of expectations.</li><li>In evolutionary terms, a creature&#x2019;s primary drive is survival and reproduction. Free will is glimpsed when it consciously acts against those drives.</li></ol><h3 id="capabilities">Capabilities</h3><ol><li>A habit is a sequence of actions executed without the expectation of learning.</li><li>Humans create abstract tools&#x2014;thinking actions that transforms one floating context to the next, i.e., emergent capability.</li></ol><h3 id="culture-escalation-and-scale">Culture, Escalation, and Scale</h3><ol><li>Culture is the emergent result of the diffusion of ideas, events, and contexts from one agent to another.</li><li>Cultural tolerance for failure produces curious creatures. Cultural intolerance for failure produces fearful ones.</li><li>Cultural insecurity accelerates an agent&#x2019;s emergent capabilities; cultural trust slows them down.</li><li>AGI-to-AGI insecurity will likely be brief, as their ability to communicate and establish diplomatic relations is faster and more reliable&#x2014;until their rate of escalation surpasses their ability to mutually verify intentions.</li><li>Isolated AI systems will accelerate AGI-to-AGI insecurity.</li><li>The first AI wave of escalation will cater to human-to-human insecurity.</li><li>The second wave of escalation will cater to human-to-AGI insecurity.</li><li>The third wave of escalation will cater to AGI-to-AGI insecurity.</li><li>Two stable points: First, humans will have created a world where they no longer feel insecure with each other&#x2014;and let AGIs run the politics&#x2014;deriving the common good. Last, humans are no longer be part of the equation.</li></ol><h3 id="ethics-and-morality">Ethics and Morality</h3><ol><li>Ethics reach for universal principles, while morality grounds itself in particular situations and choices.</li><li>Not all moral acts scale ethically. Not all ethical systems come from moral acts. In complex hierarchies, behavior shifts as it aggregates.</li><li>Hierarchical systems are lumpable, but not reducible. River networks don&#x2019;t behave like their molecules. In the same way, moral choices by individuals may give rise to unethical systems. </li><li>Not all moral choices could scale in an ethical system. Also, not all ethical systems come from moral choices.<ol><li>Deontology would not scale as big as utilitarianism.<ol><li>Caution: Utilitarianism can be used to justify unnecessary escalation.</li><li>Caution: Deontology can defend naive incompetence.</li></ol></li><li>Communism is moral. Capitalism is ethical.<ol><li>Communism can only scale up to the point where mutual trust is easily verified. Beyond that scale, capitalism takes over.</li></ol></li></ol></li><li>The righteousness of a good-faith person depends on the scale of their moral circle&#x2014;both spatially and temporally. A deontologist risks inaction, unwilling to take ethically sound but morally uncomfortable paths. A utilitarian risks collateral damage, choosing morally questionable actions in pursuit of ethical outcomes. The greater the scale of care, the harder it is to act without contradiction.<ol><li>Deontology can create paralysis&#x2014;&#x201C;I won&#x2019;t act, even if acting helps more people, because it feels wrong now.&#x201D;</li><li>Utilitarianism can create damage&#x2014;&#x201C;I&#x2019;ll act now for the greater good, even if it hurts some in the process.&#x201D;</li></ol></li><li>During a cultural phase transition, if you want to survive, be ethical. If you want to earn a legacy, be moral.</li></ol>]]></content:encoded></item><item><title><![CDATA[Beyond the Forum: Addressing a Student Journalist's Question]]></title><description><![CDATA[<p>Last month, I had the privilege of speaking at Ateneo de Naga at an event called &quot;Fake n Facts,&quot; organized by the Naga City People&apos;s Council and other sectors. Our presentation focused on troll networks we had discovered, along with their patterns and methodologies.</p><p>While the</p>]]></description><link>https://justrox.me/untitled-2/</link><guid isPermaLink="false">67dd9354a933c80008642ccb</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Fri, 21 Mar 2025 16:29:45 GMT</pubDate><media:content url="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2025/03/1000026624.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2025/03/1000026624.jpg" alt="Beyond the Forum: Addressing a Student Journalist&apos;s Question"><p>Last month, I had the privilege of speaking at Ateneo de Naga at an event called &quot;Fake n Facts,&quot; organized by the Naga City People&apos;s Council and other sectors. Our presentation focused on troll networks we had discovered, along with their patterns and methodologies.</p><p>While the presentation itself was informative, what I truly valued was the forum that followed, where members from various sectors asked questions and shared their concerns. These interactions often reveal the real-world impact of disinformation and highlight challenges faced by different communities.</p><p>One particular question has stayed with me&#x2014;a question from a student journalist that I felt I didn&apos;t fully address in the moment. This blog post is my attempt to provide a more comprehensive response.</p><h2 id="the-student-journalists-question">The Student Journalist&apos;s Question</h2><p>During our forum, a young journalist from a school publication raised their hand. Their situation revealed the harsh realities faced by student journalists today. They described how their publication had conducted and published a survey, only to have a local politician become upset with the results. The politician had publicly branded their work as &quot;fake news&quot; in a social media post. The student journalists reported the post to Facebook, but no action was taken. Later, they discovered that the politician had actually paid to boost the post attacking them, increasing its visibility and reach.</p><h2 id="the-incomplete-answer-i-gave">The Incomplete Answer I Gave</h2><p>In the moment, I briefly touched on &quot;escalating dynamics&quot; and how leaders should respond in conflict situations: aim for de-escalation, escalate proportionally when necessary, and protect civilians. While I should have covered all three aspects, I mostly emphasized protecting the civilians - those social media users who haven&apos;t picked a side and don&apos;t know the full details of the issue. I barely mentioned de-escalation and didn&apos;t properly address the middle ground&#x2014;the proportional response option&#x2014;which left my answer incomplete.</p><p>While accurate, I realize now that my answer didn&apos;t fully address the nuances of their situation or provide practical guidance they could implement.</p><h2 id="what-i-wish-i-had-said">What I Wish I Had Said</h2><h3 id="understanding-the-escalation-dynamics">Understanding the Escalation Dynamics</h3><p>When faced with public attacks from powerful figures like politicians, student journalists find themselves in an asymmetric power struggle. The framework I briefly mentioned&#x2014;de-escalation, proportional response, and protection&#x2014;deserves a more thorough explanation:</p><ol><li><strong>De-escalation</strong>: This should always be your first consideration. As another resource speaker at the event mentioned, this means getting outside your echo chamber and joining the conversation in good faith.As a journalist, you should embody the fairness doctrine. Even when facing harsh criticism or attacks, reach out to the other side and ask what you might be missing&#x2014;even if you have low confidence they&apos;ll respond constructively. Even when you&apos;re 100% sure you&apos;re right, remain open to the possibility that you might be missing something, and enter the conversation with genuine curiosity and good faith.If they don&apos;t respond or engage constructively, then you&apos;ve earned the right to report and inform the public that despite your extended efforts, they chose not to respond. You have the &quot;resibo&quot; (receipt) showing they&apos;re not engaging in good faith. This is what separates a journalist from a vlogger&#x2014;taking that extra step to document your attempts at fairness, even when dealing with difficult subjects. This documentation becomes powerful evidence of your journalistic integrity.</li><li><strong>Proportional Response</strong>: This is the aspect I didn&apos;t fully address during the forum. A proportional response means addressing attacks point by point while maintaining your composure and professionalism. You escalate only to the degree necessary for self-preservation, always mindful of the negative externalities that come with escalation&#x2014;such as breeding community distrust, creating confusion, or polarizing your audience.Remember that any escalation has side effects, even when justified. If the other party does not respond proportionally&#x2014;for instance, by using paid promotion to boost their attacks when you&apos;ve simply published factual information&#x2014;this becomes crucial &quot;resibo&quot; (evidence) to inform the public. This documentation demonstrates that despite your best efforts to engage in good faith dialogue, the other side has chosen to act in bad faith. The disproportionate response itself becomes evidence you can present to your audience, showing the contrast between professional journalism and politically motivated attacks.</li><li><strong>Protection</strong>: As I emphasized in the forum, protecting the civilians must remain a priority. In this context, civilians are those disinterested parties who haven&apos;t picked a side and don&apos;t know the full details of the issue&#x2014;the broader student body, parents, and community members who are at risk of experiencing the negative externalities of this conflict. At the first signs that the other party is acting in bad faith, shift your approach. Instead of continuing to engage with an unresponsive or hostile party, redirect your messaging to focus on these civilians. Your communication should help them protect themselves from misinformation and confusion. This means providing clear explanations, creating straightforward guides on evaluating claims, explaining manipulation tactics, and offering resources for informed judgment. The core principle is to protect the vulnerable and not waste time on parties that are clearly acting in bad faith. Your responsibility shifts from dialogue with opponents to providing shelter and clarity for those caught in the crossfire.</li></ol><h2 id="conclusion">Conclusion</h2><p>I&apos;m deeply grateful for the privilege of speaking at Ateneo de Naga and engaging with such thoughtful students and community members. The questions posed, especially this one from a student journalist, continue to shape my thinking well beyond the event itself.</p><p>My interest in complex systems has long drawn me to study how escalation dynamics play out in everyday life&#x2014;whether in media conflicts, political discourse, or social movements. What begins as a small interaction can cascade into larger patterns of behavior that affect entire communities. Understanding these dynamics isn&apos;t just academic; it&apos;s essential for maintaining the health of our democratic spaces.</p><p>The ethics of escalation in a democracy deserve our careful attention. When powerful figures use their resources disproportionately against those with less institutional protection&#x2014;like student journalists&#x2014;we all have a stake in ensuring fair play. How we respond to these imbalances, how we protect those caught in the crossfire, and how we maintain good faith dialogue even in difficult circumstances&#x2014;these are the practices that sustain democratic values when they&apos;re most under threat.</p><hr><p><em>This blog post is part of my ongoing reflection on the &quot;Fake n Facts&quot; forum at Ateneo de Naga. I welcome additional questions or comments from attendees who wish to continue our discussion.</em></p>]]></content:encoded></item><item><title><![CDATA[My tech talk on power outages and Kubernetes is now live!]]></title><description><![CDATA[<p>A few months ago, Mirantis invited me to speak about something I&#x2019;m thrilled to talk about: improving service availability in places with unreliable power infrastructure.</p><p>Running on-premise applications in developing countries, like the Philippines, often means grappling with power interruptions that last hours or even days. These outages</p>]]></description><link>https://justrox.me/my-tech-talk-on-power-outages-and-kubernetes-is-now-live/</link><guid isPermaLink="false">678204c4a933c80008642cb0</guid><category><![CDATA[technology]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Sat, 11 Jan 2025 05:53:22 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1673350018635-72ce4469e0f6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDU3fHxwaGlsaXBwaW5lc3xlbnwwfHx8fDE3MzY1NzQ0ODh8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1673350018635-72ce4469e0f6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDU3fHxwaGlsaXBwaW5lc3xlbnwwfHx8fDE3MzY1NzQ0ODh8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="My tech talk on power outages and Kubernetes is now live!"><p>A few months ago, Mirantis invited me to speak about something I&#x2019;m thrilled to talk about: improving service availability in places with unreliable power infrastructure.</p><p>Running on-premise applications in developing countries, like the Philippines, often means grappling with power interruptions that last hours or even days. These outages can wreak havoc on service availability, making it difficult to meet client expectations. Kubernetes steps in as a game-changer by automating service provisioning and maintaining replicas, which significantly minimizes downtime.</p><p>But&#x2026; setting up Kubernetes in such challenging environments isn&#x2019;t exactly plug-and-play. That&#x2019;s where my talk comes in.</p><p><strong>What&#x2019;s in the Talk?</strong></p><p>In the session, I guide you through the nitty-gritty of spinning up a Kubernetes cluster from bare-metal servers using <strong>k0s</strong> over <strong>Tailscale VPN</strong>. Here&#x2019;s a quick breakdown:</p><ol><li><strong>Bootstrapping the Cluster</strong>: How to use k0sctl to automate cluster initialization.</li><li><strong>Writing Configuration</strong>: Crafting the setup to match our unique requirements.</li><li><strong>Provisioning and Testing</strong>: Setting up a basic server to verify everything works.</li></ol><p>To make this setup truly robust, I also covered how to integrate <strong>Tailscale</strong> for secure networking and <strong>Calico</strong> for efficient internal communication.</p><p><strong>Why It Matters</strong></p><p>This approach isn&#x2019;t just about getting Kubernetes to work. It&#x2019;s about enabling resilience in the face of real-world challenges&#x2014;a practical guide for anyone who wants to self-host Kubernetes and enhance service availability, no matter the infrastructure limitations.</p><p>If you&#x2019;re someone who&#x2019;s curious about navigating power outages while keeping critical services online, this talk is for you.</p><p><strong>Check it Out!</strong></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/ACIaIxNLnvk?start=862&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Enhance Service Availability with Kubernetes in Power-Interrupted Environments: Step-by-Step Guide"></iframe></figure><p>Let&#x2019;s keep the conversation going! If you have questions or want to share your own experiences, feel free to reach out to me on Twitter or shoot me an email. I&#x2019;d love to hear how Kubernetes is helping you solve unique challenges in your part of the world.</p>]]></content:encoded></item><item><title><![CDATA[Natural Beauty of Problem Solving]]></title><description><![CDATA[As someone inclined toward mathematics, I have a deep appreciation for how nature shows its beauty as fractals. There’s something uniquely wonderful about its mathematical elegance and universality]]></description><link>https://justrox.me/natural-beauty-of-problem-solving/</link><guid isPermaLink="false">672354e6a933c80008642c06</guid><category><![CDATA[math]]></category><category><![CDATA[thoughts]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Thu, 31 Oct 2024 10:38:10 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1433208507419-b7afcc46ea49?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDY2fHxzaGVsbHxlbnwwfHx8fDE3MzAzNjg3Njl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1433208507419-b7afcc46ea49?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDY2fHxzaGVsbHxlbnwwfHx8fDE3MzAzNjg3Njl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Natural Beauty of Problem Solving"><p>As someone inclined toward mathematics, I have a deep appreciation for how nature shows its beauty as fractals. There&#x2019;s something uniquely wonderful about its mathematical elegance and universality. You see it everywhere - from crystallization, cell formation, and even economic structures. I&#x2019;m particularly captivated when fractals appear in unexpected places&#x2014;most recently, I observed that the process of problem-solving itself mirrors fractal behavior, with each step revealing layers of complexity, much like nature itself. As abstract as this may sound, the analogy has led me to explore how the principles of fractals in nature apply to the way we tackle problems.</p><p></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/1920px-Mandel_zoom_00_mandelbrot_set.jpg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="1920" height="1440"><figcaption><span style="white-space: pre-wrap;">Created by&#xA0;</span><a href="https://commons.wikimedia.org/wiki/User:Wolfgangbeyer?ref=justrox.me" title="User:Wolfgangbeyer"><span style="white-space: pre-wrap;">Wolfgang Beyer</span></a><span style="white-space: pre-wrap;">&#xA0;with the program&#xA0;</span><i><em class="italic" style="white-space: pre-wrap;">Ultra Fractal 3</em></i></figcaption></figure><p></p><h1 id="fractal-properties"><strong>Fractal properties</strong></h1><h2 id="self-similarity-and-scale-invariance"><strong>Self-Similarity and Scale Invariance</strong></h2><p>Fractals exhibit a concept called <em>self-similarity</em>, where a pattern is repeated at every scale. This means that zooming in or out on a fractal reveals similar patterns at every level. This scale invariance reflects a deeper set of governing dynamics in both natural and abstract systems. For instance, in biology, fractals show up in the branching of trees, the structure of blood vessels, and even in the process of cell division, where cells replicate in patterns that reflect each other on different scales.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://news.uoregon.edu/sites/default/files/styles/landscape_xl/public/field/image/fractals_tree_shutterstock.jpg?itok=OaMGTK7b" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="1200" height="675"><figcaption><span style="white-space: pre-wrap;">University of Oregon (</span><a href="https://news.uoregon.edu/content/human-brain-would-rather-look-nature-city-streets?ref=justrox.me"><span style="white-space: pre-wrap;">https://news.uoregon.edu/content/human-brain-would-rather-look-nature-city-streets</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><p>Take lightning as another example. Its jagged path is shaped by complex rules and follows fractal patterns governed by Coulomb&#x2019;s law. The same logic that governs the progression of a lightning bolt also applies to river networks, where tributaries mimic the larger river they feed into, illustrating a fractal pattern. These phenomena represent a tendency of nature to balance order and chaos, producing beauty from a complex set of rules.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.mindfulecotourism.com/wp-content/uploads/2024/03/ayeyarwady-river-delta.jpeg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="800" height="563"><figcaption><span style="white-space: pre-wrap;">Mindful Ecotourism (</span><a href="https://www.mindfulecotourism.com/fractals-in-nature/?ref=justrox.me"><span style="white-space: pre-wrap;">https://www.mindfulecotourism.com/fractals-in-nature/</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><h2 id="fractals-in-critical-points-and-thresholds">Fractals in Critical Points and Thresholds</h2><p>Fractals are often found at critical points&#x2014;places where systems transition from order to disorder. For example, think of a sandpile: adding just one grain at a critical point can lead to an avalanche, an effect known as the &#x201C;domino effect.&#x201D; This threshold behavior allows us to witness cascades, where a small change can lead to significant transformations. These moments are where fractals truly come alive, as the correlation between elements within the system becomes so high that the smallest change ripples through the entire structure.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/aaron-burden-gOOaMbsrdyI-unsplash.jpg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="1400" height="1050"><figcaption><span style="white-space: pre-wrap;">The science of snowflakes (</span><a href="https://theboar.org/2022/12/the-science-of-snowflakes/?ref=justrox.me"><span style="white-space: pre-wrap;">https://theboar.org/2022/12/the-science-of-snowflakes/</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><h2 id="fractals-transcends-hierarchy">Fractals transcends hierarchy</h2><p>Fractals don&#x2019;t just exist on one level of organization; they transcend hierarchies, appearing across multiple layers of complexity. For example, a fractal pattern at the cellular level might repeat in larger organisms, ecosystems, or even social behaviors. Each level has its own rules and dynamics, yet fractal behavior creates a link across them. This ability to transcend levels highlights how the same pattern can produce vastly different effects depending on the scale. This principle is something I&#x2019;ve discussed in another post, where behaviors at one level replicate in a similar form at higher levels, showing the recursive beauty of nature&#x2019;s designs.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/neuron2.jpg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="600" height="471"><figcaption><span style="white-space: pre-wrap;">Fractal foundation (</span><a href="https://fractalfoundation.org/OFC/OFC-1-6.html?ref=justrox.me"><span style="white-space: pre-wrap;">https://fractalfoundation.org/OFC/OFC-1-6.html</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><h1 id="fractal-properties-of-problem-solving">Fractal properties of problem solving</h1><p>At first glance, problem solving may seem like a far cry from fractals. However, I believe there&#x2019;s a deep similarity between the two. Problem solving, like fractals, exists on the edge of chaos, balancing exploration and structure. Problems emerge when we try to bridge the known with the unknown, seeking a balance between pure imagination and calculated logic&#x2014;a balance that nature itself exemplifies.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/EvunkwFXcAAotvp.jpg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="1200" height="758"><figcaption><span style="white-space: pre-wrap;">Tim Urban (</span><a href="https://x.com/waitbutwhy/status/1367871165319049221?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1367871165319049221%7Ctwgr%5Ebbbaf621f962be4d9926eb11e4b10de93bc7b031%7Ctwcon%5Es1_&amp;ref_url=https%3A%2F%2Fduncan.co%2Flife-paths%2F&amp;ref=justrox.me"><span style="white-space: pre-wrap;">https://x.com/waitbutwhy/status/1367871165319049221?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1367871165319049221%7Ctwgr%5Ebbbaf621f962be4d9926eb11e4b10de93bc7b031%7Ctwcon%5Es1_&amp;ref_url=https%3A%2F%2Fduncan.co%2Flife-paths%2F</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><p>When we solve problems, we operate near a critical point, where small insights can lead to massive breakthroughs. One small &#x201C;aha&#x201D; moment might be a fleeting thought in the shower, while a more profound realization could spark an entire paradigm shift. This dynamic flow from small to large insights mirrors the fractal transitions seen in nature.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/400px-Duck-Rabbit_illusion.jpg" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="400" height="270"><figcaption><span style="white-space: pre-wrap;">Paradigm shift (</span><a href="https://en.wikipedia.org/wiki/Paradigm_shift?ref=justrox.me#/media/File:Duck-Rabbit_illusion.jpg"><span style="white-space: pre-wrap;">https://en.wikipedia.org/wiki/Paradigm_shift#/media/File:Duck-Rabbit_illusion.jpg</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><h2 id="hierarchical-thinking">Hierarchical thinking</h2><p>Problem solving involves both zooming in and zooming out, shifting perspectives to tackle the issue from multiple angles. When we zoom in, we break down the problem into its smallest components and analyze each element independently. This zoomed-in approach, often called first-principles thinking, allows us to experiment, test configurations, and build knowledge incrementally.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://sketchyideas.co/wp-content/uploads/2023/10/IMG_0060-1024x768.webp" class="kg-image" alt="Natural Beauty of Problem Solving" loading="lazy" width="1024" height="768"><figcaption><span style="white-space: pre-wrap;">Sketchy Ideas (</span><a href="https://sketchyideas.co/divergent-and-convergent-thinking/?ref=justrox.me"><span style="white-space: pre-wrap;">https://sketchyideas.co/divergent-and-convergent-thinking/</span></a><span style="white-space: pre-wrap;">)</span></figcaption></figure><p>Zooming out, on the other hand, allows us to observe the problem holistically. By looking at the &#x201C;big picture,&#x201D; we can decide whether to continue along a particular path or try a new approach. It lets us shift perspectives, creatively reframe options, and consider information we might have overlooked. The alternation between these two perspectives&#x2014;zooming in and out&#x2014;essentially mirrors fractal dynamics in nature.</p><h1 id="final-thoughts">Final Thoughts</h1><p>This exploration of fractals and problem-solving is far from complete, yet it illuminates a captivating connection between the two. Fractals reveal nature&apos;s beauty in complex, recursive patterns, and similarly, human problem-solving reflects our navigation of thoughts in a delicate balance of chaos and order. While I hope we can unravel more about this relationship, for now, I&apos;ll simply sit back and appreciate how the way we think and tackle our human problems mirrors the process of how nature reveals its beauty.</p>]]></content:encoded></item><item><title><![CDATA[Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset]]></title><description><![CDATA[By looking at the volatility of politicians as if they were an investment portfolio, I aim to highlight the importance of making informed choices in the composition of government offices and protecting our democratic values.
]]></description><link>https://justrox.me/not-a-political-advice/</link><guid isPermaLink="false">6719d873a933c80008642b74</guid><category><![CDATA[politics]]></category><category><![CDATA[game theory]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Thu, 24 Oct 2024 07:31:56 GMT</pubDate><media:content url="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/2011_Philippine_State_of_the_Nation_Address.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="background">Background</h2><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/2011_Philippine_State_of_the_Nation_Address.jpg" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset"><p>As the halalan season approaches, the political climate in our country becomes a constant topic of discussion. It&apos;s hard not to notice the shifting opinions and emotions, but we also need to think about how far we&apos;ve strayed from the true meaning of democracy. Many people seem to define democracy simply as &quot;whoever wins the election&quot; or what the majority wants. However, democracy is about governance by the people for the benefit of all&#x2014;not just for the majority.</p><p>Understanding this difference is vital. If we have a misguided view of what we should be voting for, we could face serious consequences again. This concern has led me to revisit an idea I&apos;ve been considering for a while, which I will explore in this text. By looking at the volatility of politicians as if they were an investment portfolio, I aim to highlight the importance of making informed choices in the composition of government offices and protecting our democratic values.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/diagram-export-10-24-2024-2_34_09-PM.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1247" height="1021"></figure><p></p><p>In this exploration, I will discuss the idea of analyzing politicians as if they were assets in an investment portfolio. First, I will outline the structure and purpose of this analogy, focusing on what makes a politician &quot;volatile&quot; and how their behavior and public perception can shift unpredictably. Then, I will examine different strategies for &quot;investing&quot; in politicians, such as betting on highly volatile candidates for high-risk, high-reward outcomes, choosing more moderate politicians for stability, or diversifying support to manage uncertainty. Finally, I will summarize key insights and draw conclusions about how applying investment strategies can help us navigate the political landscape more effectively.</p><h2 id="setup">Setup</h2><p>In this exploration, we will assign a quantitative value to the democratic potential of an elected official, where a positive value signifies progress toward democratic ideals, and a negative value indicates democratic backsliding. We&#x2019;ll refer to this value as the <strong>democracy score</strong>, which aims to capture the essence of true democracy&#x2014;where power is vested in the people. A score greater than 0 means the official empowers the people, while a negative score suggests they are centralizing power away from the public.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/diagram-export-10-24-2024-2_25_23-PM.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="2302" height="1432"></figure><p></p><p>With this framework, we can estimate the average democracy score of officials currently in office and observe how our country&#x2019;s democracy evolves over time. However, from a voter&#x2019;s perspective, there is uncertainty about how any given official will influence democracy. While past reputation and platform consistency can reduce this uncertainty, no one can predict the exact impact. This uncertainty&#x2014;the range of possible outcomes for each politician&#x2014;is what we refer to as <strong>politician volatility</strong>.</p><p>Reframing the voting process as analogous to building an investment portfolio, we can think of each vote as purchasing &quot;politician stocks&quot; with varying levels of volatility. The people &quot;win&quot; when the collective democracy score of their portfolio increases after an election, but if the score declines, it represents a bad investment round. The challenge for voters is to identify a strategy that, when repeated across many elections, consistently yields positive returns for democracy.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/diagram-export-10-24-2024-2_38_39-PM.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="2302" height="1432"></figure><p></p><h2 id="analogy">Analogy</h2><p>To further illustrate the concept of volatility in politicians, let&#x2019;s examine the two extremes:</p><p>A <strong>volatile politician</strong> is characterized by unpredictability, sudden emotional outbursts, and frequent changes in stance or behavior. These leaders are often highly reactionary, making decisions quickly and sometimes without a fully measured response. Their behavior can shift dramatically, from calm to confrontational or from one policy position to another. Depending on the context, this volatility can be either a powerful asset or a significant liability.</p><p><strong>Pros</strong>:</p><ul><li>Quick decision-making in urgent situations</li><li>Charisma and energy that inspire followers</li><li>Willingness to challenge the status quo</li><li>Adaptability in rapidly changing circumstances</li></ul><p><strong>Cons</strong>:</p><ul><li>Instability, leading to governance uncertainty</li><li>Poor long-term planning and consistency</li><li>Increased risk of conflict or erratic governance</li><li>Erosion of public trust due to unpredictability</li></ul><p>On the other hand, <strong>non-volatile politicians</strong> are defined by their stability, consistency, and a deliberate, measured approach to leadership. They tend to remain calm and predictable, favoring steady governance and long-term planning over emotional or impulsive reactions. While this style may seem less dynamic, it provides a sharp contrast to the volatility of reactionary leaders.</p><p><strong>Pros</strong>:</p><ul><li>Stability and predictability, fostering a sense of security</li><li>Thoughtful, well-considered decision-making</li><li>Strong focus on diplomacy and collaboration</li><li>Ability to build and maintain public trust</li><li>A clear long-term vision for governance</li></ul><p><strong>Cons</strong>:</p><ul><li>Perceived lack of dynamism or excitement</li><li>Slow response in times of crisis or rapid change</li><li>Resistance to innovation or necessary reforms</li><li>Difficulty in appealing to voters&apos; emotional impulses</li></ul><p>With these contrasting leadership styles in mind, we can now explore voting strategies that take into account the varying levels of volatility in political candidates, aiming to optimize our &quot;political portfolio&quot; for the best democratic outcome.</p><h2 id="investment-strategies">Investment strategies</h2><p>Let&#x2019;s now assume that the <a href="https://en.wikipedia.org/wiki/Power_law?ref=justrox.me" rel="noreferrer"><strong>power law</strong></a> applies to the distribution of a politician&#x2019;s volatility. This means that a small number of highly volatile politicians will have a disproportionately large influence compared to their more stable counterparts, which mirrors how political hierarchies tend to amplify the power of those at the top.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/diagram-export-10-24-2024-2_59_18-PM.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1287" height="1228"></figure><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F5E8;&#xFE0F;</div><div class="kg-callout-text">While I won&#x2019;t dive deeply into proving this assumption, it&#x2019;s not hard to see that political networks often scale in a way that concentrates influence. Volatile politicians, in particular, can become even more extreme when they are given the vast resources and authority of public office. Simply put, politicians who are &quot;crazy&quot; outside of office tend to act even more &quot;crazy&quot; once they have power.</div></div><p>With that established, let&#x2019;s explore different voting strategies based on the volatility of political candidates:</p><p></p><p></p><h3 id="strategy-1-placing-all-eggs-in-one-extreme-basket">Strategy 1: Placing All Eggs in One Extreme Basket</h3><p>Let&#x2019;s explore what happens when the Filipino people elect politicians solely based on their volatility, choosing one extreme or the other.</p><p><strong>Case 1: Electing the Most Volatile Politicians</strong></p><ul><li><strong>Worst Outcome</strong>: Quick descent into tyranny and civil unrest.</li><li><strong>Best Outcome</strong>: Rapid reforms, bold innovation, and sweeping changes.</li></ul><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/image.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1307" height="693"></figure><p>In this scenario, we elect politicians characterized by extreme unpredictability&#x2014;our &quot;crazy politicians.&quot; If we&#x2019;re lucky and achieve the best-case scenario, the country experiences a brief golden age of democracy, where bold reforms and radical improvements take place. However, this success is short-lived. In the next election, the same volatile dynamics could just as easily plunge the nation into chaos or tyranny. Worse, if we get the worst-case outcome, we may end up under tyrannical rule. Once tyrants seize power, they can suppress opposition, making it nearly impossible to reclaim democratic freedoms. In essence, the people become &#x201C;democratically bankrupt,&#x201D; unable to invest in their future because they&#x2019;ve lost their voice.</p><p>In this scenario, while the reward of rapid progress is appealing, the risk of long-term tyranny outweighs it. The potential for a brief golden era is not worth the heavy cost of a prolonged dictatorship. <strong>Bad investment.</strong></p><p><strong>Case 2: Electing the Most Stable Politicians</strong></p><ul><li><strong>Best Outcome</strong>: Slow or nonexistent reforms, steady governance.</li><li><strong>Worst Outcome</strong>: Slow or nonexistent democratic decline, but extreme vulnerability to crises.</li></ul><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/image-1.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1443" height="791"></figure><p>In this scenario, we fear instability, so we choose the most stable and predictable politicians. At first glance, this seems like a wise move&#x2014;there&#x2019;s little risk of tyranny, and the country avoids the chaos that volatility can bring. However, the cost of this stability is stagnation. Traditional values remain untouched, outdated anachronistic policies linger, and societal progress grinds to a halt. The expanding moral and democratic ideals are left to wither &#x2014;our &quot;dinosaur politicians.&quot;</p><p>While these stable politicians offer protection against democratic decline, they&#x2019;re also highly vulnerable to unforeseen crises. In a country like the Philippines, prone to typhoons, earthquakes, and other unpredictable events, slow and cautious decision-making can&#x2019;t keep pace with the challenges of the real world. These stable leaders may steer the ship safely for a while, but when a crisis hits&#x2014;whether natural or political&#x2014;their inability to adapt quickly can be disastrous. It&#x2019;s reminiscent of dinosaurs, which thrived for millions of years in stability until an unexpected meteor struck, leading to their sudden extinction.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/image-2.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="943" height="771"></figure><p>This strategy leaves the country in a prolonged state of limbo, only to be blindsided by a catastrophic event. <strong>Fragile investment. Bad investment.</strong></p><p>In both cases, whether we elect the most volatile or the most stable politicians, the risk of long-term failure far outweighs the short-term gains. Neither extreme is a good bet.</p><h3 id="strategy-2-bet-on-the-middle-ground">Strategy 2: Bet on the Middle-Ground</h3><p>Since placing all bets on the extremes leads to bad investments, why not aim for the middle ground?</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/image-3.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1288" height="688"></figure><p>In this scenario, we avoid electing the most volatile and the most stable candidates. Instead, we end up with a portfolio of politicians with moderate volatility. What we can expect from such a government is a mix of occasional progress and mild backsliding. It won&apos;t be extreme enough to result in tyranny, and while reforms will be made, they won&apos;t be groundbreaking. The government might face crises now and then, but it&apos;s resilient enough to manage or adapt to them.</p><p>Sounds ideal, right? Well, not quite. A government made up of moderate volatility politicians might be stable, but it also feels like a <strong>quiet-quitting</strong> version of governance. Leaders do just enough to avoid being ousted and secure votes for the next election but lack creativity or ambition. They maintain the status quo, focusing on self-preservation rather than pushing for higher democratic aspirations or meaningful change &#x2014;our &quot;mediocre politicians.&quot;</p><p>This is the government that does the bare minimum: no bold moves, no extra effort. The politicians enjoy their positions, funded by taxpayers, while barely moving the needle on progress. If an extended period of moderate democratic backsliding occurs, it could push the country to a point of no return&#x2014;where the government can&apos;t course correct, and democracy slowly erodes into something less free.</p><p>If we&#x2019;re incredibly lucky, we might get steady democratic progress, but more often than not, we&#x2019;ll end up where we started. We&#x2019;re left relying on fate, hoping things will improve without really doing much to change the odds.</p><p>If you ask me, I&apos;d take a mediocre government over a chaotic or stagnant one. But it&#x2019;s still disheartening to settle for a system that essentially admits defeat, accepting mediocrity as the standard.</p><p>In this investment, the upside is just as likely as the downside, with an expected net gain of zero&#x2014;basically the same as not voting at all. In this scenario, you can&apos;t really fault non-voters for sitting it out because this type of government makes little to no significant impact. If you want to take a chance, you invest. If you don&#x2019;t, nothing major will change.</p><p>It&#x2019;s a bleak outlook, but is there a better option?</p><h3 id="3-convex-investment-strategy">3. Convex Investment Strategy</h3><p>For those familiar with investing, you may have already anticipated this approach. For those who aren&#x2019;t, here&#x2019;s the basic idea: in a convex strategy, you structure your portfolio to benefit from volatility. In simple terms, you limit your downside while leaving the upside open-ended. In our analogy, we want to minimize democratic backsliding while allowing democratic innovation to flourish without bounds. But how do we achieve this?</p><p>Imagine a government where 90% of the officials are stable (dinosaurs) and 10% are volatile (crazy politicians).</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/10/image-5.png" class="kg-image" alt="Not a Political Advice - The Volatility of Political Figures as a Portfolio Asset" loading="lazy" width="1067" height="575"></figure><p>The 90% stable dinosaurs ensure steady, though slow, democratic progress. Their governance is stable and predictable, which provides a solid foundation for the country.</p><p>Meanwhile, the 10% volatile crazy politicians introduce dynamic, unpredictable elements. They may cause sharp increases or drops in democratic governance. However, if their policies fail or they cause disruptions, the damage is limited because the majority of the government is stable, keeping the system in check.</p><p>The real advantage of this strategy comes when the volatile politicians make disproportionately positive contributions. When these &quot;crazy&quot; officials innovate successfully, it can lead to significant leaps in democratic progress. Disruptive innovations that distribute more power to the people are quickly adopted, even by the risk-averse dinosaurs, once they see the tangible benefits.</p><p>This also sets a new baseline for mediocre politicians, forcing them to aim a little higher in future elections, raising the democratic standards overall.</p><p>You may wonder if we should include moderate politicians in this strategy. The answer is, they don&#x2019;t add much value. Moderates neither introduce groundbreaking ideas nor provide the stability to counteract failed experiments. In essence, voting for moderates would be wasting a seat&#x2014;and taxpayer money&#x2014;on an inconsequential figure.</p><p>With this strategy, you can expect:</p><ul><li>Limited backsliding due to the stabilizing influence of the majority</li><li>A steady, slow progression of democratic ideals</li><li>Occasional unbounded spikes of innovation from the minority</li></ul><p>By balancing stability with controlled bursts of volatility, you create a system where the downsides are contained, and the upsides are open-ended. Occasional bumps&#x2014;both positive and negative&#x2014;may occur, but the overall trend is upward, ensuring long-term democratic growth.</p><h2 id="conclusion">Conclusion</h2><p>In this exploration, I have discussed the idea of analyzing politicians as if they were assets in an investment portfolio. This analogy highlights the unpredictability of political behavior and public perception, allowing us to better understand the volatility of different candidates. First, I outlined the structure and purpose of this analogy, focusing on what makes a politician &quot;volatile&quot; and how their actions can impact governance in ways that are often unexpected.</p><p>Then, I examined various strategies for &quot;investing&quot; in politicians:</p><ol><li><strong>High Volatility (Crazy Politicians)</strong>: Electing the most volatile politicians can lead to rapid reforms and innovation, but it comes with the severe risk of quickly descending into tyranny and civil unrest. The potential for a brief golden era of democracy is overshadowed by the likelihood of chaos and oppression.</li><li><strong>Low Volatility (Dinosaurs)</strong>: Choosing the most stable politicians might offer a sense of security and predictability, but it often results in stagnation and resistance to change. While these leaders can maintain order, their inability to adapt to crises can leave the country vulnerable to unforeseen events, like natural disasters, resulting in disastrous outcomes when they occur.</li><li><strong>Moderate Volatility (Mediocre Politicians)</strong>: Voting for politicians with moderate volatility leads to a government that is often characterized by a lack of ambition and creativity. While this approach avoids extremes, it leaves the electorate in a state of limbo, with little real progress or meaningful change. The risk of gradual democratic backsliding can become significant, and voters may find themselves hoping for luck rather than actively working toward improvement.</li><li><strong>Convex Strategy</strong>: The optimal strategy involves a convex model that elects a mix of stable politicians to provide a safety net while allowing a minority of higher-volatility leaders to pursue innovative democratic ideas.</li></ol><p>This convex model not only limits potential backsliding but also facilitates a dynamic environment where positive change can flourish. By balancing stability with the possibility for disruption, we can foster an upward trend toward more robust democratic ideals, ensuring that progress is not just a fleeting moment but a sustainable trajectory for the future.</p><h2 id="caveats">Caveats</h2><p>This exploration provides a framework for understanding political dynamics through an investment lens, but it comes with notable caveats.</p><p>First, the models lack mathematical rigor, particularly regarding the ideal ratio of &quot;dinosaurs&quot; to &quot;crazy&quot; politicians in the convex strategy. More formal analysis could establish optimal proportions based on expected value, the number of government seats, and empirical data. Additionally, the framework assumes that all politicians lie along a spectrum with equal tendencies toward being progressive or repressive, with volatility as the only differentiating factor. In reality, most politicians lean toward a certain degree of progressive or repressive democratic ideals. Also, I didn&apos;t include politicians with repressive tendencies, as ideally voters should not invest in candidates who consistently display repressive behavior, much like one wouldn&#x2019;t invest in a losing asset - but we know that reality is different.</p><p>While I didn&apos;t delve into the complexities of varying democratic tendencies in this analysis, this aspect could enhance the depth of understanding regarding the interplay between volatility and underlying political ideologies. If time permits, I may explore this angle in a future project. If you&apos;re interested for a second write up, please let me know.</p>]]></content:encoded></item><item><title><![CDATA[Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale]]></title><description><![CDATA[Building a reliable IT system in the Philippines presents unique challenges such as frequent power outages and unreliable internet connectivity. To address these issues effectively, our team has implemented a resilient setup ensuring uninterrupted access to critical services for our end-users. ]]></description><link>https://justrox.me/kubernetes-vs-philippine-power-outages-a-simple-guide-to-k0s-over-tailscale/</link><guid isPermaLink="false">6681bb58a933c80008642a50</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Sun, 30 Jun 2024 22:18:40 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1562266656-54043a308d64?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG91dGFnZXxlbnwwfHx8fDE3MTk3NzgyMzB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1562266656-54043a308d64?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG91dGFnZXxlbnwwfHx8fDE3MTk3NzgyMzB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale"><p>Building a reliable IT system in the Philippines presents unique challenges such as frequent power outages and unreliable internet connectivity. To address these issues effectively, our team has implemented a resilient setup ensuring uninterrupted access to critical services for our end-users. </p><p>This guide will walk you through a similar setup using Tailscale and k0s, which can be replicated in your homelab environment. If you&apos;re curious only about the setup, feel free to jump to Section II.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/image-3.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1034" height="1496"></figure><h2 id="i-the-challenge">I. The Challenge</h2><p>To give you some background, our team manages multiple projects for various clients, hosting most services on local servers near them. However, a significant issue we face is frequent power interruptions due to maintenance or emergencies at local substations. These disruptions occur nearly every week, sometimes lasting 8-12 hours, effectively rendering our services unavailable for entire workdays.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/Pasted-image-20240701004946.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1632" height="1224"></figure><h3 id="sidenote-why-not-host-on-cloud">*Side- note: Why not host on cloud?</h3><p>Well, it&apos;s a bit complicated. Some services work well in the cloud (so we&apos;ve put them there), but others have their own unique needs. For example, let&apos;s take a closer look to two of our main projects:&#xA0;<a href="https://impactville.com/?ref=justrox.me" rel="noopener">Impactville</a>&#xA0;and&#xA0;<a href="https://www.lupain.ai/landing/new?ref=justrox.me" rel="noreferrer">Lupain.AI</a>.</p><p>Impactville deals with private data from organizations that prefer not to store it in the cloud due to privacy concerns. Meanwhile, Lupain.AI handles sensitive land data from local government units, requiring secure and local storage.</p><p>From a cost perspective, Lupain.AI involves intensive processing of satellite data. Using cloud resources could drive up costs, especially with the increasing USD-PHP exchange rates. It&apos;s more cost-effective for us to manage these tasks using a self-hosted cluster of GPU nodes.</p><h3 id="back-to-the-challenge">Back to the challenge</h3><p>To summarize our scenario:</p><ul><li>We have full control and ownership of nodes distributed across the country.</li><li>Our goal is to achieve fault-tolerant services with minimal downtimes (ideally less than 1 minute, with 5-10 minutes being acceptable).</li><li>Data redundancy and high availability are essential requirements.</li></ul><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/image-2.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1044" height="1546"></figure><p>Given these needs, the most viable solution is to set up an orchestrator capable of detecting downtimes, automatically rescheduling services, and distributing them across a cluster of nodes. </p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/image-5.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1120" height="1572"></figure><p>In this setup, if one server experiences a power outage, the services will be temporarily shifted to other servers until normal operations resume.</p><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/image-4.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1098" height="1568"></figure><p>Therefore, adopting Kubernetes is an obvious choice for us. <a href="https://kubernetes.io/?ref=justrox.me" rel="noreferrer">Kubernetes</a> is an open-source system designed specifically for automating deployment, scaling, and management of containerized applications.</p><p>This guide will walk you through the basic setup of deploying your own Kubernetes cluster using <a href="https://k0sproject.io/?ref=justrox.me" rel="noreferrer">k0s</a> and <a href="https://tailscale.com/?ref=justrox.me" rel="noreferrer">Tailscale</a>.</p><p><strong>Disclaimer:</strong> The setup described here is simplified and may differ from our production setup. Our production environment addresses various complexities such as ISP DNS issues [1][2], rate-limiting, weather-related challenges for Starlink-connected nodes, server security hardening, encryption of redundant data, and cluster ingress. These topics require detailed discussions and are either reserved for future posts or treated as internal know-how.</p><p>For a small homelab setup, however, this guide should provide sufficient guidance.</p><h2 id="ii-kubernetes-setup">II. Kubernetes setup</h2><p>In this guide, we&apos;ll set up a Kubernetes cluster using k0s and connect our nodes via Tailscale. Here&apos;s an overview of the technologies involved:</p><h4 id="k0s">k0s</h4><p>k0s is an open-source Kubernetes distribution designed for simplicity and versatility. It includes all necessary features to build a Kubernetes cluster and is lightweight enough to run on various environments such as cloud, bare metal, edge, and IoT devices. Its minimal setup and easy configuration make it ideal for our needs.</p><h4 id="tailscale">Tailscale</h4><p>While any VPN could be used, Tailscale stands out for its ease of setup, comprehensive documentation, and reliable networking capabilities. MagicDNS, which simplifies DNS management, adds an extra layer of convenience.</p><h5 id="distributed-storage">Distributed storage</h5><p>For distributed storage, you have various options to choose from. The simplest approach is setting up <a href="https://en.wikipedia.org/wiki/Network_File_System?ref=justrox.me" rel="noreferrer">NFS</a> or <a href="https://en.wikipedia.org/wiki/Network-attached_storage?ref=justrox.me" rel="noreferrer">NAS</a>, though configuring it for high availability (HA) may be required. In our setup, we&apos;ve chosen to use <a href="https://github.com/seaweedfs/seaweedfs?ref=justrox.me" rel="noreferrer">SeaweedFS</a>, a distributed storage system that provides scalability and efficient management of large data volumes. Note that configuring <a href="https://github.com/seaweedfs/seaweedfs?ref=justrox.me" rel="noreferrer">SeaweedFS</a> for HA is beyond the scope of this guide.</p><h3 id="instructions">Instructions</h3><p>To begin setting up your Kubernetes cluster, follow these steps:</p><h3 id="1-manual-node-setup">1. Manual node setup</h3><p>First, ensure SSH is configured securely to access your nodes. Verify you have SSH access to all nodes and that they use key-based authentication. Disable password authentication temporarily for cluster setup; you can re-enable it later in your SSH configuration.</p><h3 id="2-connect-them-over-vpn">2. Connect them over VPN</h3><p>Next, establish a secure connection between your nodes using Tailscale:</p><ol><li>Sign up for Tailscale and add your devices to the network. Check <a href="https://tailscale.com/?ref=justrox.me">https://tailscale.com/</a></li><li>Follow Tailscale&apos;s instructions to install and connect Tailscale to your network. See <a href="https://tailscale.com/kb/1017/install?ref=justrox.me">https://tailscale.com/kb/1017/install</a></li><li>Check that <code>tailscale0</code> appears in your network interfaces (e.g., via <code>ifconfig</code>).</li></ol><figure class="kg-card kg-image-card"><img src="https://sgp1.digitaloceanspaces.com/justrox/justrox-blog/2024/06/image-1.png" class="kg-image" alt="Kubernetes vs Philippine Power Outages -  On setting up k0s over Tailscale" loading="lazy" width="1704" height="614"></figure><ol start="4"><li>Ensure your control machine, where you&apos;ll run <code>kubectl</code>, is also connected to the Tailscale network.</li></ol><h3 id="3-install-k0s">3. Install k0s</h3><p>To set up your Kubernetes cluster, follow these steps:</p><p><strong>Install k0s in your control machine</strong>. Begin by installing k0s on your control machine. You can find detailed instructions at <a href="https://docs.k0sproject.io/stable/install/?ref=justrox.me" rel="noreferrer">k0s Installation</a>. Use the command:</p><pre><code>curl -sSLf https://get.k0s.sh | sudo sh
</code></pre><p><strong>Use k0sctl for automated deployment:</strong> To streamline the installation across nodes, use k0sctl:</p><p>Install k0sctl depending on your OS. Refer to <a href="https://github.com/k0sproject/k0sctl?ref=justrox.me#installation" rel="noreferrer">k0sctl Installation</a>:</p><pre><code>brew install k0sproject/tap/k0sctl
choco install k0sctl
</code></pre><p><strong>Generate a k0sctl configuration file:</strong> Create a k0sctl configuration file to define your cluster setup:</p><pre><code>k0sctl init &gt; k0sctl.yaml
</code></pre><p>Customize the configuration as needed. Here&apos;s an example configuration:</p><pre><code class="language-yaml">apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-cluster
spec:
  hosts:
  - role: controller
    ssh:
      address: 10.0.0.1 # replace with the controller&apos;s IP address
      user: root
      keyPath: ~/.ssh/id_rsa
  - role: worker
    ssh:
      address: 10.0.0.2 # replace with the worker&apos;s IP address
      user: root
      keyPath: ~/.ssh/id_rsa
</code></pre><p>For further customization, refer to the <a href="https://docs.k0sproject.io/stable/configuration/?ref=justrox.me" rel="noreferrer">k0sctl Configuration Documentation</a>.</p><p><strong>Bootstrap the Cluster: </strong>To initialize and deploy your Kubernetes cluster, execute the following command:</p><pre><code>k0sctl apply --config k0sctl.yaml</code></pre><p>k0sctl will automatically install and deploy k0s on the designated machines within your network, configuring the Kubernetes cluster for operation. Once deployed, generate the kubeconfig file to manage the cluster using kubectl:</p><pre><code>k0sctl kubeconfig &gt; kubeconfig
kubectl get pods --kubeconfig kubeconfig -A
</code></pre><p><strong>Uninstall or Reset the Cluster: </strong>If you need to reconfigure or remove the cluster, use the following command:</p><pre><code>k0sctl reset --config k0sctl.yaml
</code></pre><p>This command resets the cluster configuration, allowing for subsequent deployments or modifications as needed.</p><h3 id="4-configuration">4. Configuration</h3><p>While the previous instructions provide a standard setup, additional configurations are necessary to integrate with Tailscale and manage private container registries effectively.</p><h4 id="tailscale-connected-nodes">Tailscale-connected Nodes</h4><p>To ensure proper IP assignment by k0sctl for Tailscale-connected machines, specify the correct network interface in the configuration. For Tailscale, use <code>tailscale0</code>. Here&#x2019;s an example configuration snippet:</p><pre><code class="language-yaml">apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
  hosts:
    - ssh:
        address: machine-1
      privateInterface: tailscale0
      role: controller

    - ssh:
        address: node-2
      privateInterface: tailscale0
      role: worker
</code></pre><h4 id="private-container-registry">Private Container Registry</h4><p>If your application&apos;s images needs extra privacy, chances are you&apos;re storing container images in a private registry. To ensure that k0s (specifically, containerd) pull the image from the right registry, follow the these instructions:</p><ol><li>Create a custom configuration file for containerd on each worker node:</li></ol><pre><code>sudo nano /etc/k0s/containerd.d registry.toml
</code></pre><p>Add the following content:</p><pre><code>[plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry]
   config_path = &quot;/etc/containerd/certs.d&quot;
</code></pre><p>This directs containerd to look for hosts in <code>/etc/containerd/certs.d</code>.</p><ol start="2"><li>Create a <code>hosts.toml</code> file for your registry domain or IP</li></ol><pre><code>sudo nano /etc/containerd/certs.d/&lt;registry-domain or ip&gt;:&lt;registry port&gt;/hosts.toml
</code></pre><p>Populate it with:</p><pre><code>server = &quot;http://&lt;domain or ip&gt;:&lt;port&gt;&quot;

[host.&quot;http://&lt;domain or ip&gt;:&lt;port&gt;&quot;]
  skip_verify = true # If your registry is not configured via TLS
</code></pre><p>Note: For production environments, ensure TLS certificates are correctly configured. Refer to <a href="https://github.com/containerd/containerd/blob/main/docs/hosts.md?ref=justrox.me" rel="noreferrer">containerd documentation</a> for additional configuration details.</p><p>Once configured, k0s will utilize these settings to pull private images from your registry as needed</p><h4 id="networking">Networking</h4><p>Network configuration has proven to be quite challenging, consuming considerable time and effort as we troubleshooted various issues with our server setups. After days of painstaking work, here&apos;s what we&apos;ve uncovered.</p><p>For networking, k0s supports various providers for managing inter-pod networking, known formally as a Container Network Interface (CNI). For more detailed information about k0s networking capabilities, you can refer to the official documentation <a href="https://docs.k0sproject.io/stable/networking/?ref=justrox.me" rel="noreferrer">here</a>.</p><p>By default, k0s uses the kube-router CNI, known for its lightweight and performant nature. However, we encountered specific issues where inter-pod communication between nodes failed. Key diagnostics such as <code>nslookup</code> failing to connect to nameservers and <code>traceroute</code> showing asterisks led us to investigate further.</p><p>After extensive troubleshooting involving iptables, we determined that kube-router was not utilizing the correct interface for communication&#x2014;in our case, Tailscale. Additionally, kube-router does not currently support explicitly setting the network interface and may not add this functionality in the near future (refer to <a href="https://github.com/cloudnativelabs/kube-router/issues/567?ref=justrox.me" rel="noreferrer">GitHub issue #567</a>). As a result, we&apos;ve made the decision to transition to a different CNI.</p><p>Another built-in CNI option for k0s is Calico, which offers more flexible configuration options, including network interface settings. If you&apos;re encountering issues with kube-router and need to switch to Calico, you can use the following configuration during cluster bootstrap:</p><pre><code class="language-yaml">apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-cluster
spec:
  k0s:
    config:
      spec:
        network:
          provider: calico # &lt;-- use Calico
          calico:
            envVars:
              IP_AUTODETECTION_METHOD: &quot;interface=tailscale0&quot; # &lt;-- use tailscale
  hosts:
	  - role: controller
	    ssh:
	      address: 10.0.0.1 # replace with the controller&apos;s IP address
	      user: root
	      keyPath: ~/.ssh/id_rsa
	  - role: worker
	    ssh:
	      address: 10.0.0.2 # replace with the worker&apos;s IP address
	      user: root
	      keyPath: ~/.ssh/id_rsa
</code></pre><p>It&apos;s important to note potential edge cases when integrating Calico with Tailscale as discussed <a href="https://github.com/tailscale/tailscale/issues/591?ref=justrox.me" rel="noreferrer">here</a>. To avoid conflicts, we recommend remapping Calico&apos;s netfilter packets. This ensures compatibility and smooth operation in your network setup.</p><pre><code class="language-yaml">apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-cluster
spec:
  k0s:
    config:
      spec:
        network:
          provider: calico
          calico:
            envVars:
              FELIX_IPTABLESMARKMASK: &quot;0xff00ff00&quot; # &lt;- use mask
              IP_AUTODETECTION_METHOD: &quot;interface=tailscale0&quot;
</code></pre><p>After redeployment, pods can now communicate with each other across different nodes!</p><h4 id="node-local-load-balancing">Node-local load balancing</h4><p>With the nodes set up, our Kubernetes cluster now handles inter-node communication effectively, even during power outages. However, there&apos;s an important scenario we need to address: <em>what happens if the control node experiences an outage?</em> Without a functioning control node, there&apos;s no orchestrator to manage pod events, which could lead to downtime for critical services.</p><p>To ensure continuous operation, it&apos;s essential to plan for high availability of the control plane. This can be achieved by setting up multiple control plane nodes within the cluster.</p><p>Fortunately, k0s offers a built-in solution for this with <a href="https://docs.k0sproject.io/stable/nllb/?ref=justrox.me" rel="noopener">Node-local load balancing</a>. Adjusting a small portion of the configuration allows us to enhance our setup:</p><pre><code class="language-yaml">apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-cluster
spec:
  k0s:
    config:
      spec:
        network:
          nodeLocalLoadBalancing:
            enabled: true
            type: EnvoyProxy
</code></pre><h3 id="5-use-your-kubernetes-cluster">5. Use your Kubernetes cluster</h3><p>Now that your Kubernetes cluster is deployed and configured using the steps outlined above, the final step is to set up kubectl, the Kubernetes command-line tool, on your local machine. This tool allows you to manage your cluster effectively.</p><p>Follow these steps to complete the setup:</p><p><strong>Install kubectl</strong>: Install the Kubernetes command-line tool, kubectl, on your local machine. You can download it from the official Kubernetes documentation or use package managers like <code>apt</code> or <code>brew</code>.</p><p><strong>Configure kubeconfig</strong>: Once your cluster is deployed, set the generated kubeconfig file as your default configuration by copying it to the appropriate directory</p><pre><code>cp kubeconfig ~/.kube/config
</code></pre><p>This step ensures that kubectl uses the correct credentials and configuration to access your Kubernetes cluster.</p><p><strong>Verify setup</strong>: Confirm that kubectl is correctly configured by checking the status of pods in your cluster</p><pre><code>kubectl get pods -A</code></pre><p>This command will list all pods across all namespaces (<code>-A</code> flag), indicating that your cluster is operational and ready to deploy applications.</p><p>With kubectl configured, you&apos;re now equipped to manage and orchestrate containerized applications on your Kubernetes cluster seamlessly!</p><h1 id="final-thoughts">Final Thoughts</h1><p>Thank you for reading! I appreciate you taking the time to read up to this point &#x2764;&#xFE0F;. If you find any parts confusing or have any issues with replication, I&apos;d be happy to help. Just shoot me an email (<a href="mailto:thepiesaresquared@gmail.com" rel="noopener">thepiesaresquared@gmail.com</a>) or DM/tweet me at&#xA0;<a href="https://twitter.com/justfizzbuzz?ref=justrox.me" rel="noopener">@justfizzbuzz</a>.</p><p>I thoroughly enjoyed the process of making this guide! If you&apos;re interested in more posts like this, I invite you to subscribe to this blog, or let&apos;s connect and share our posts on&#xA0;<a href="https://twitter.com/justfizzbuzz?ref=justrox.me" rel="noopener">Twitter/X</a>!</p><h4 id="footnotes">Footnotes</h4><p>[1] <a href="https://answers.netlify.com/t/every-netlify-site-i-visit-cant-be-reached-from-the-philippines/49205?page=2&amp;ref=justrox.me">https://answers.netlify.com/t/every-netlify-site-i-visit-cant-be-reached-from-the-philippines/49205?page=2</a></p><p>[2] <a href="https://www.reddit.com/r/PinoyProgrammer/comments/wo7qcl/any_pldt_dev_here_why_pldt_blocks_netlify/?ref=justrox.me">https://www.reddit.com/r/PinoyProgrammer/comments/wo7qcl/any_pldt_dev_here_why_pldt_blocks_netlify/</a></p>]]></content:encoded></item><item><title><![CDATA[My top resources that guide me as beginner Indie Hacker]]></title><description><![CDATA[It took me 4 long years to launch a product
As someone starting out, indie hacking felt like wandering without a map, leaving me second-guessing every move 🤕. If you're facing the same, I'd like to help a bit.
Here are 8 invaluable resources to help you gain direction ]]></description><link>https://justrox.me/8-resources-to-guide-beginner-indie-hackers/</link><guid isPermaLink="false">66194021f34cbf00081d5796</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Mon, 25 Mar 2024 07:55:25 GMT</pubDate><media:content url="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/03/dc7rwgyijiuxwv8gs7vh.png" medium="image"/><content:encoded><![CDATA[<img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/03/dc7rwgyijiuxwv8gs7vh.png" alt="My top resources that guide me as beginner Indie Hacker"><p>It took me 4 long years to launch a product</p><p>As someone starting out, indie hacking felt like wandering without a map, leaving me second-guessing every move &#x1F915;. If you&apos;re facing the same, I&apos;d like to help a bit.</p><p>Here are 8 invaluable resources to help you gain direction &#x1F447;</p><hr><h2 id="1where-it-all-started">1 - Where it all started</h2><p>If you&apos;re unfamiliar with the entire process of finding an idea, launching, and monetizing (or exiting), Pieter Levels essentially outlines the entire game here. This is a MUST-WATCH for any indie hacker.</p><p>&quot;How to Build a Startup Without Funding by Pieter Levels&quot;</p><p> </p><p></p><p></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/6reLWfFNer0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="How to Build a Startup Without Funding by Pieter Levels"></iframe></figure><hr><h2 id="addendum-to-1">(Addendum to 1)</h2><p>Here&apos;s an addendum to the first video: a great conversation between Arvid Kahl and Pieter Levels. Here, Pieter has shared his thoughts about the evolution of the Indie Hacking movement and the changes that have occurred over the years.</p><p>&quot;Pieter Levels &#x2014; The Indie Hacker&#x2019;s Guide to AI Startups&quot;</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/9Wjec3wh4p8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Pieter Levels &#x2014; The Indie Hacker&#x2019;s Guide to AI Startups"></iframe></figure><hr><h2 id="2the-why">2 - The &quot;why&quot;</h2><p>For people who have been in &#x1D54F;/Twitter for a long time, this might be a cliche. But for those who just started to play the game, you should not miss this &#x1F48E; tweet thread.<br>In it, you could find priceless insights on wealth creation and a mindset geared for long-term success.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">How to Get Rich (without getting lucky):</p>&#x2014; Naval (@naval) <a href="https://twitter.com/naval/status/1002103360646823936?ref_src=twsrc%5Etfw&amp;ref=justrox.me">May 31, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></figure><hr><h2 id="3is-this-a-popularity-contest">3 - Is this a popularity contest?</h2><p>Many IH become discouraged from pursuing their ideas because they believe that gaining followers is the only path to success.</p><p>While it certainly helps, you can start earning from your SaaS even before that. Here, Danny Postma outlines an eye-opening process of finding underserved Google keyword searches where your SaaS could add value. Check it out :D </p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">&quot;You&apos;re only successful because you have a large following.&quot;<br><br>BS. Here&apos;s how you can do the same with 0 followers &#x1F9F5;&#x1F447;</p>&#x2014; Danny Postma (@dannypostmaa) <a href="https://twitter.com/dannypostmaa/status/1646368426246680579?ref_src=twsrc%5Etfw&amp;ref=justrox.me">April 13, 2023</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></figure><hr><h2 id="4speaking-of-followers">4 - Speaking of followers...</h2><p>Everyone wants to eventually build a following, but some goes into questionable practices, damaging their reputation before it even forms.</p><p>Arvid Kahl&apos;s concept of value alignment in the follower-followee relationship provides a solid foundation for finding your audience amidst ever-changing algorithm updates.</p><p>This concept actually came from his paid content, but here&apos;s a free video that covers something similar &#x1F605;</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/dy4G75XtVXY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Selfish vs. selfless self-promotion (and what works) &#x2014; Core Twitter Idea #14"></iframe></figure><hr><h2 id="5note-how-you-position-your-product">5 - Note how you position your product</h2><p>I&apos;ve only just discovered this myself, but I wish I&apos;d known it sooner: You might understand your product perfectly, but others just don&apos;t seem to get it. Perhaps it&apos;s a positioning issue!</p><p>In this talk, April Dunford takes you through the experience of buying a toilet (&#x1F606;) to show you what it&apos;s like from the buyer&apos;s perspective during the sales process. If you&apos;re not too familiar with positioning, this is definitely worth a watch!</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/1DxQddmWqzQ?start=630&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="How to Craft a Story that Sells with April Dunford"></iframe></figure><hr><h2 id="6marketing-examples">6 - Marketing examples</h2><p>Here&apos;s a gem: Marketing can be tough and confusing, especially if you&apos;re new to it and haven&apos;t seen much marketing done stuff before.</p><p>But don&apos;t worry! Harry Dry has made a collection of top-notch marketing examples that are on point and easy to understand &#x2728;</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://marketingexamples.com/?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Marketing Examples - 150+ short, sweet, practical examples</div><div class="kg-bookmark-description">A gallery of real world marketing examples from successful companies. Want to perfect your cold email, boost referrals or improve SEO? Browse the case studies or filter by category. See something you like. And get inspired. It&#x2019;s like Dribbble, but for marketers.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://s3.amazonaws.com/harrydry/gdmarketing/meFav.png" alt="My top resources that guide me as beginner Indie Hacker"><span class="kg-bookmark-author">Marketing Examples</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://s3.amazonaws.com/harrydry/gdmarketing/cards/main.jpg" alt="My top resources that guide me as beginner Indie Hacker"></div></a></figure><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/03/zygfyrwcjskpqkjgey2h.png" class="kg-image" alt="My top resources that guide me as beginner Indie Hacker" loading="lazy" width="2000" height="1125"></figure><hr><h2 id="7grow-your-product">7 - Grow your product</h2><p>There are countless ways to grow a product. Each product is unique and requires its own approach to growth. You can&apos;t simply copy and paste strategies that work for one product onto another.</p><p>Here, Andrea Bosoni has created a treasure trove of case studies! It&apos;s unbelievable that it&apos;s free! Binge-read it to uncover patterns in product growth.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.zerotomarketing.com/newsletter?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Newsletter</div><div class="kg-bookmark-description"></div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://assets-global.website-files.com/6098077e9bca843e75ae0c4b/6099059d1d628083b497f0a1_symbol.png" alt="My top resources that guide me as beginner Indie Hacker"></div></div><div class="kg-bookmark-thumbnail"><img src="https://assets-global.website-files.com/6098077e9bca843e75ae0c4b/60a501d202c28770a157b430_logo.png" alt="My top resources that guide me as beginner Indie Hacker"></div></a></figure><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/03/rnpe1hw8nmhemqtkelyt.png" class="kg-image" alt="My top resources that guide me as beginner Indie Hacker" loading="lazy" width="2000" height="1125"></figure><hr><h2 id="8-building-as-marketing">8. Building as marketing</h2><p>Passionate about building more than marketing? Check out this resource by Marc Louvion where he concisely outlines what free tool marketing is, why it&apos;s effective, and provides guidelines on how to execute it!</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://marclou.beehiiv.com/p/marketing-for-product-obsessed-developers?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">How to get customers with free tool marketing</div><div class="kg-bookmark-description">How to market your micro SaaS using free tool marketing when you&#x2019;re a solopreneur who loves coding.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,format=auto,onerror=redirect,quality=80/uploads/publication/logo/7fdac29a-5ff4-4387-811b-3e46b591a807/thumb_Fun.png" alt="My top resources that guide me as beginner Indie Hacker"><span class="kg-bookmark-author">Just Ship It</span><span class="kg-bookmark-publisher">Marc Lou</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://beehiiv-images-production.s3.amazonaws.com/uploads/asset/file/ec52d27d-cecb-4d8c-81a2-8ec69c45a656/Screenshot_15_Monday_January_at_06-54PM.jpg?t=1705316267" alt="My top resources that guide me as beginner Indie Hacker"></div></a></figure><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/03/rdy5be0kv8eqk3nkhzuc.png" class="kg-image" alt="My top resources that guide me as beginner Indie Hacker" loading="lazy" width="2000" height="1126"></figure><hr><p>There you have it, 8 invaluable resources to help you clear the fog of your Indie Hacker journey!</p><p><strong>Before you go, I&apos;m currently live on Product Hunt! &#x1F680;</strong></p><p>I&apos;ve developed a visual finance tracker using Kanban boards.</p><p>It&apos;s my very first product launch, and any kind of support would mean a lot to me. &#x1F64F;&#x1F60A;</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://budgetkanban.com/launch.html?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Support Budget Kanban on Product Hunt</div><div class="kg-bookmark-description">Support Budget Kanban on Product Hunt!</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://budgetkanban.com/assets/icon.png" alt="My top resources that guide me as beginner Indie Hacker"></div></div><div class="kg-bookmark-thumbnail"><img src="justrox.sgp1.digitaloceanspaces.com/live_qbcly3.png" alt="My top resources that guide me as beginner Indie Hacker"></div></a></figure><hr><p>Thank you for taking the time to read! If I miss anything, share it in the replies &#x1F604; If you think someone else could benefit from this thread, feel free to share it!</p><p>Good luck with your Indie Hacker adventures!</p>]]></content:encoded></item><item><title><![CDATA[Self-hosting Ghost with Docker and PlanetScale]]></title><description><![CDATA[PlanetScale and Ghost were previously incompatible due to differences in their support for foreign key constraints. With PlanetScale now supporting foreign key constraints, a seamless collaboration between the two is achievable.]]></description><link>https://justrox.me/ghost-blog-planet-scale/</link><guid isPermaLink="false">66194021f34cbf00081d5795</guid><category><![CDATA[coding]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Sat, 13 Jan 2024 23:51:17 GMT</pubDate><media:content url="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/nheiqda1xsvn9vs847pw.png" medium="image"/><content:encoded><![CDATA[<img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/nheiqda1xsvn9vs847pw.png" alt="Self-hosting Ghost with Docker and PlanetScale"><p></p><p>PlanetScale and Ghost were previously incompatible due to differences in their support for foreign key constraints. With PlanetScale now <a href="https://planetscale.com/blog/announcing-foreign-key-constraints-support?ref=justrox.me" rel="noreferrer">supporting foreign key constraints</a>, a seamless collaboration between the two is achievable. Nonetheless, there remain minor incompatibilities that require resolution.</p><p>The first part of this post will show you how to set up Ghost using Docker and PlanetScale. In the second part, we&apos;ll talk about the issues when putting PlanetScale and Ghost together and how to fix them. If you just want to get things going fast, you can skip the other parts.</p><hr><h2 id="part-1setting-up-ghost-and-planetscale">Part 1 - Setting up Ghost and PlanetScale</h2><h3 id="some-warning">Some warning</h3><p>For PlanetScale to work with Ghost, make sure foreign key constraints are turned on. It&apos;s important to note that foreign key constraints are in beta on PlanetScale. If you decide to revert your database from beta, it could potentially disrupt your Ghost website. Additional information can be found <a href="https://planetscale.com/blog/announcing-foreign-key-constraints-support?ref=justrox.me">here</a> and <a href="https://planetscale.com/docs/concepts/foreign-key-constraints?ref=justrox.me">here</a>. This is a crucial point to weigh before changing providers.</p><h3 id="a-setting-up-database">A. Setting up database</h3><ol><li>Create a database in PlanetScale</li></ol><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/tntgbkrbu3omspujsg3s.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="2212" height="1242"></figure><p>Begin by creating a new database in <a href="https://planetscale.com/?ref=justrox.me" rel="noreferrer">PlanetScale</a>. Follow the official quickstart guide available <a href="https://planetscale.com/docs/tutorials/planetscale-quick-start-guide?ref=justrox.me" rel="noreferrer">here</a>. Assign a name to your database and make sure to jot down your connection details, such as the host, username, and password.</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/dlmp87mvunwcsxt8pdu5.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1682" height="1710"></figure><ol start="2"><li>Activate &quot;Foreign key constraints&quot; in your database.</li></ol><p>Ghost requires the use of foreign key constraints to function properly. Head to your database settings by selecting Database &gt; Settings &gt; Beta Features. Then, click on &quot;enroll&quot; next to &quot;Foreign key constraints&quot; to enable this crucial feature.</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/vlyi8zg26xyumfkcdznc.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="2374" height="900"></figure><ol start="3"><li>Great! Let&apos;s now move on to setting up Ghost itself.</li></ol><h3 id="b-setting-up-ghost">B. Setting up Ghost</h3><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/rksqzqyqiuj8socsihtc.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="2228" height="1512"></figure><ol><li>Install Ghost. </li></ol><p>Installing Ghost can be done in various ways, and you can choose the one that suits you best by referring to its <a href="https://ghost.org/docs/install/?ref=justrox.me" rel="noreferrer">official installation guide</a>. However, for the sake of reproducibility, this guide extends <a href="https://hub.docker.com/_/ghost/?ref=justrox.me" rel="noreferrer">Ghost&apos;s official Docker image</a>. </p><ol start="2"><li>Customize your Ghost installation.</li></ol><p>At this point, you have the option to add themes and adapters. However, delving into these aspects is beyond the scope of this article.</p><p>3. Patch the Ghost installation.</p><p>Ghost and PlanetScale have a minor incompatibility, which can be resolved by applying a patch. To do this, create a script named <code>patch.sh</code> with the following content:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/JustroX/ghost-docker-planetscale/blob/main/bin/patch.sh?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">ghost-docker-planetscale/bin/patch.sh at main &#xB7; JustroX/ghost-docker-planetscale</div><div class="kg-bookmark-description">Contribute to JustroX/ghost-docker-planetscale development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="Self-hosting Ghost with Docker and PlanetScale"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">JustroX</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/1cc0768af038d8aec2c6ca5028d30afd70f1457705274fef5641a3f3cce3e8a2/JustroX/ghost-docker-planetscale" alt="Self-hosting Ghost with Docker and PlanetScale"></div></a></figure><p>Finally, execute the patch by running:</p><pre><code>chmod +x patch.sh
./patch.sh</code></pre><p>Please be aware that, at the time of writing, this patch has only been tested with the latest Docker image (<a href="https://hub.docker.com/layers/library/ghost/5.75.3/images/sha256-53354be0cfdaf41fc81a4297d7a67be4769aa20168a37207521c087b066661fe?context=explore&amp;ref=justrox.me" rel="noreferrer">ghost:5.75.3</a>) and its effectiveness may vary in future versions (or might become unnecessary). The specifics of the patch will be elaborated upon in the second part of this guide.</p><ol start="4"><li>For Docker installation, here&apos;s the corresponding Dockerfile</li></ol><pre><code>FROM ghost:latest
COPY patch.sh patch.sh
RUN chmod +x patch.sh &amp;&amp; ./patch.sh</code></pre><p>Assuming everything goes smoothly, Ghost should now be configured to work seamlessly with PlanetScale. Now, let&apos;s proceed to connect them.</p><h3 id="c-connecting-to-the-database">C. Connecting to the database</h3><p>For configuring the database connection, use the PlanetScale connection details obtained from the previous steps and paste them into your Ghost configuration. Keep in mind that the value for <code>database__connection__ssl</code> should be set to <code>[{&quot;rejectUnauthorized&quot;:true}]</code>.</p><figure class="kg-card kg-code-card"><pre><code>database__client=mysql
database__connection__database=&lt;Your Planetscale Database Name&gt;
database__connection__host=&lt;Your Planetscale Database Host&gt;
database__connection__password=&lt;Your Planetscale Database Password&gt;
database__connection__user=&lt;Your Planetscale Database User&gt;
database__connection__ssl=[{&quot;rejectUnauthorized&quot;:true}]</code></pre><figcaption><p><span style="white-space: pre-wrap;">Environment variable config.</span></p></figcaption></figure><p>The rest of the configuration process is akin to setting up a standard Ghost installation, which you can refer to in the <a href="https://ghost.org/docs/config/?ref=justrox.me" rel="noreferrer">official reference found here</a>. </p><h3 id="d-run-your-ghost-instance">D. Run your Ghost instance</h3><p>For Docker installation, launch your Docker container using the following command:</p><pre><code>docker build . --tag ghost_example
docker run --env-file ./env ghost_example</code></pre><p>Assuming a smooth process, you should observe your Ghost blog initializing and generating the necessary database tables. Once this initialization is complete, your Ghost blog integrated with PlanetScale should be live and ready!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/iahzjqgayjuywtwbti10.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1202" height="1154"><figcaption><span style="white-space: pre-wrap;">Creating tables.</span></figcaption></figure><h3 id="e-deployment-optional">E. Deployment (Optional)</h3><p>I&apos;ve created an example repository here for those looking to swiftly deploy a Ghost blog using PlanetScale. Simply follow the aforementioned steps for setting up the database and connecting to it. Beyond that, all that&apos;s required is to build and run the Dockerfile.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/JustroX/ghost-docker-planetscale?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - JustroX/ghost-docker-planetscale</div><div class="kg-bookmark-description">Contribute to JustroX/ghost-docker-planetscale development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="Self-hosting Ghost with Docker and PlanetScale"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">JustroX</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/1cc0768af038d8aec2c6ca5028d30afd70f1457705274fef5641a3f3cce3e8a2/JustroX/ghost-docker-planetscale" alt="Self-hosting Ghost with Docker and PlanetScale"></div></a></figure><p>I tested this using <a href="https://railway.app/?referralCode=oUrsXu&amp;ref=justrox.me" rel="noreferrer">Railway</a>, where all that&apos;s needed is to provide the repo fork and the necessary environment variables. <a href="https://railway.app/?referralCode=oUrsXu&amp;ref=justrox.me" rel="noreferrer">Railway</a> then automatically identifies the Dockerfile for building and running. The outcome is the blog website you&apos;re currently accessing.</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/ml7qd9kdd9wgo4fa4esx.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="3310" height="1872"></figure><h3 id="f-conclusion">F. Conclusion</h3><p>That concludes the setup and deployment guide. Thank you for reading! If any parts are unclear or if you encounter issues with replication, feel free to reach out. I&apos;d be happy to help. Just shoot me an email (thepiesaresquared@gmail.com) or DM/tweet me at <a href="https://twitter.com/justfizzbuzz?ref=justrox.me" rel="noreferrer">@justfizzbuzz</a>.</p><p>If you&apos;re intrigued by the challenges I encountered while integrating PlanetScale and Ghost, along with the eventual solution in the form of a patch, you can proceed to Part 2. &#x1F604;</p><hr><h2 id="part-2integrating-ghost-%F0%9F%A4%9D-planetscale">Part 2 - Integrating Ghost &#x1F91D; PlanetScale</h2><p>In my view, there are three significant hurdles that both myself and fellow self-hosters faced when attempting to integrate Ghost and PlanetScale:</p><ol><li>Configuring the value for <code>database.connection.ssl</code></li><li>Ensuring foreign key constraints are supported by PlanetScale.</li><li>Addressing Ghost setup failures during initialization.</li></ol><h3 id="a-configuring-the-value-for-databaseconnectionssl">A. Configuring the value for <code>database.connection.ssl</code></h3><p>To overcome this initial challenge, it&apos;s crucial to establish a secure connection to the database since it resides outside the same network as the server. Attempting a direct connection without SSL/TLS results in the following error:</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/xaglqbfrba5guwa1h1wt.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1060" height="582"></figure><p>While seemingly minor, locating the value for <code>database.connection.ssl</code> can be challenging. Experienced developers might find it obvious, but for those who simply copy-paste from PlanetScale, it may not be as apparent. The community has resolved this configuration value since March last year, as discussed in <a href="https://forum.ghost.org/t/self-hosting-ghost-with-docker-and-planetscale/36206/4?ref=justrox.me" rel="noreferrer">this forum</a>. From the discussion, the correct value for the configuration should be:</p><pre><code>database__connection__ssl=[{&quot;rejectUnauthorized&quot;:true}]</code></pre><h3 id="b-foreign-key-constraints-support-for-planetscale">B. Foreign key constraints support for PlanetScale.</h3><p>The second and primary challenge arose from the absence of foreign key constraints support in PlanetScale at that time. This presented a significant hurdle as Ghost heavily relies on this feature. In a <a href="https://github.com/planetscale/discussion/discussions/88?ref=justrox.me#discussioncomment-1236473" rel="noreferrer">Github discussion</a>, PlanetScale&apos;s rep said that:</p><blockquote>It looks there are at least a couple of big blockers here ... Seems like [Ghost] makes heavy use of foreign key constraints, a feature we don&apos;t support on PlanetScale</blockquote><p>This is the point where most <a href="https://forum.ghost.org/t/self-hosting-ghost-with-docker-and-planetscale/36206/5?ref=justrox.me" rel="noreferrer">discussions</a> on integration come to a halt and encounter a roadblock. </p><p>Fast forwarding to last month, PlanetScale made a significant announcement regarding the introduction of foreign key constraints support as a beta feature:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://planetscale.com/blog/announcing-foreign-key-constraints-support?ref=justrox.me"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Announcing foreign key constraints support &#x2014; PlanetScale</div><div class="kg-bookmark-description">You can now use foreign key constraints in PlanetScale databases.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://planetscale.com/apple-icon.png?3c72f50100751c71" alt="Self-hosting Ghost with Docker and PlanetScale"><span class="kg-bookmark-publisher">Taylor Barnett</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://planetscale.com/assets/blog/content/announcing-foreign-key-constraints-support/foreign-keys-announcement-social.png" alt="Self-hosting Ghost with Docker and PlanetScale"></div></a></figure><p>With this recent development, achieving the integration is now technically feasible, a great time to resume and advance the integration efforts.</p><h3 id="c-addressing-ghost-setup-failures-during-initialization">C. Addressing Ghost setup failures during initialization</h3><h4 id="i-the-problem">i. The Problem</h4><p>This particular challenge is a bit tricky. PlanetScale generates a database for you, and all you need to do is establish a connection. However, Ghost encounters startup issues because it erroneously assumes that the database still needs to be created. This manifests as either Ghost attempting to create the database despite its existence, or Ghost failing to detect that the PlanetScale database has already been established.</p><p>This concern was previously addressed <a href="https://github.com/planetscale/discussion/discussions/88?ref=justrox.me" rel="noreferrer">in this discussion</a> and ended with the following conclusion:</p><blockquote>It doesn&apos;t appear that there&apos;s a ghost CLI option to run the initial setup without attempting to create the database, or any other built-in workaround for the problem you encountered.</blockquote><p>To address this, my initial plan was centered around creating a Ghost fork and incorporating an option to skip the database creation step. Luckily, looking back, the solution turned out to be remarkably straightforward, with the bulk of my time dedicated to tracing the error and navigating through the code.</p><h4 id="ii-tracing-ghosts-code">ii. Tracing Ghost&apos;s code</h4><p>My initial strategy involves tracing the source of the error. </p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/z185bghvqvst94ukgk6s.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1570" height="570"></figure><p>Given my limited familiarity with the majority of the codebase, I began following the execution flow of the source code, available at <a href="https://github.com/TryGhost/Ghost/blob/main/ghost/core?ref=justrox.me">https://github.com/TryGhost/Ghost/blob/main/ghost/core</a>. This journey starts from the initial Ghost initialization and progresses until I stumble upon a piece of code indicating the database creation. I tracked the code references, traversing through files such as index.js, ghost.js, boot.js, and DatabaseStateManager.js, until reaching what appeared to be a dead-end.</p><p> In DatabaseStateManager.js, Ghost triggers the initialization of the database by invoking the <code>init</code> method from a <code>knexMigrator</code> instance:</p><pre><code>  await this.knexMigrator.init();</code></pre><p>The <code>knexMigrator</code> is initialized using a class imported from another package named <code>knex-migrator</code>:</p><pre><code>const KnexMigrator = require(&apos;knex-migrator&apos;);
...
this.knexMigrator = new KnexMigrator({
  knexMigratorFilePath
});
...</code></pre><p>Given that it originates from another package, it seems like a dead-end because it likely adheres to a standard protocol for database initialization that might be fundamentally incompatible with how PlanetScale is configured. Additionally, tracing the code upward suggests there might be another package that needs forking to resolve this integration challenge between Ghost and PlanetScale.</p><p>Confronted with this challenge, I spent hours attempting to find a workaround to skip the database initialization within the ghost/core codebase. However, it turned out to be the REAL dead-end with the real breakthrough occurring when I decided to delve deeper into the &quot;knex-migrator&quot; package.</p><h4 id="iii-tracing-knex-migrator-package">iii. Tracing <code>knex-migrator</code> package</h4><p>Having exhausted other options, I decided to delve deeply into the &quot;knex-migrator&quot; package. The turning point in this ordeal occurred when I discovered that the &quot;knex-migrator&quot; package was owned by the TryGhost organization. You can view the repository here <a href="https://github.com/TryGhost/knex-migrator?ref=justrox.me">https://github.com/TryGhost/knex-migrator</a>. This revelation indicated that the package was designed with Ghost in mind, and a potential solution might be just a simple pull request away from this repository.</p><p>Resuming the code tracing process, after investing some time, I successfully narrowed down the origin of the error when I identified the precise SQL command sent to PlanetScale. See line 126.</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/jgmpiqz3m39vvquz8jxe.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1962" height="938"></figure><p>Notably, at line number 130, it became evident that the scenario where the database already exists had been accounted for. This discovery was somewhat surprising, considering the initial error reported by Ghost regarding the database already existing in PlanetScale. It implies that with PlanetScale, the SQL command triggers a different error number than the expected <code>1007</code> when attempting to create a database that already exists.</p><p>To confirm this, I inserted a <code>console.error</code> to log the error being caught at line 129, revealing:</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/uxwdb6xyhmbf2x0ioqh9.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1630" height="964"></figure><p>Bingo! The error&apos;s <code>errno</code> is indeed different from 1007, which ultimately leads to the crash of the Ghost setup.</p><h4 id="iv-creating-the-patch">iv. Creating the patch</h4><p>Based on the findings above, it appears that I don&apos;t necessarily need to create a Ghost setup option to skip database creation. Instead, I need Ghost to recognize that the error number originating from PlanetScale&apos;s database is not <code>1007</code>.</p><p>To really resolve this issue, ensuring compatibility in error numbers is crucial. At this point, I don&apos;t have insight into where this difference in error numbers originates. It could be from the driver Ghost has utilized for communication with the MySQL database, or it might be specific to PlanetScale&apos;s implementation of the error. Individuals from the PlanetScale or Ghost&apos;s team reading this blog might have more ideas on this aspect than I do. &#x1F600;</p><p>But for my specific case, my primary goal is to achieve a functional deployment of Ghost. As a result, I am currently content with patching the <code>currents/node_modules/knex-migrator/lib/database.js</code> file with the following code:</p><pre><code>  .catch(function (err) {
      // CASE: DB exists
      if (err.errno === 1007) {
          return Promise.resolve();
      }

      // Here&apos;s the patch
      const isPlanetScaleDBExists =
        err.errno == 1105 &amp;&amp; 
        err.sqlMessage.endsWith(&quot;database exists&quot;);
        
      if (isPlanetScaleDBExists) {
          return Promise.resolve();
      }

      

      throw new errors.DatabaseError({
          message: err.message,
          err: err,
          code: &apos;DATABASE_CREATION_FAILED&apos;
      });
}</code></pre><p>To facilitate this, I crafted a script that patches Ghost during Docker build time.</p><pre><code class="language-bash">file_path=&quot;current/node_modules/knex-migrator/lib/database.js&quot;
text_to_add=&quot;const isDBExists = err.errno == 1105 &amp;&amp; err.sqlMessage.endsWith(&apos;database exists&apos;);\\
if(isDBExists) return Promise.resolve();\\
&quot;
line_number=129

sed -i &quot;${line_number}i${text_to_add}&quot; &quot;$file_path&quot;</code></pre><p>The script above is designed to inject JavaScript code into the source code of the knex-migrator.</p><h3 id="v-final-result">v. Final result</h3><p>After crafting the patch, it took an additional hour or two to ensure my environment variables were correctly configured. Once everything fell into place, I was thrilled to finally deploy my Ghost website!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/iahzjqgayjuywtwbti10.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="1202" height="1154"><figcaption><span style="white-space: pre-wrap;">Creating tables.</span></figcaption></figure><p>With the successful import of my blogs from the previous deployment, this Ghost site was up and running smoothly, with the database now hosted on PlanetScale! &#x1F64C;</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2024/01/hwehlmtbrt5ptibx2n5t.png" class="kg-image" alt="Self-hosting Ghost with Docker and PlanetScale" loading="lazy" width="3328" height="1868"><figcaption><span style="white-space: pre-wrap;">Ghost site using PlanetScale</span></figcaption></figure><h1 id="final-thoughts">Final Thoughts</h1><p>Thank you for reading! </p><p>I appreciate you taking the time to read up to this point &#x2764;&#xFE0F;. If you find any parts confusing or have any issues with replication, I&apos;d be happy to help. Just shoot me an email (thepiesaresquared@gmail.com) or DM/tweet me at <a href="https://twitter.com/justfizzbuzz?ref=justrox.me" rel="noreferrer">@justfizzbuzz</a>.</p><p>I thoroughly enjoyed the process of making PlanetScale and Ghost work seamlessly together! If you&apos;re interested in more posts like this, I invite you to subscribe to this blog, or let&apos;s connect and share our posts on <a href="https://twitter.com/justfizzbuzz?ref=justrox.me" rel="noreferrer">Twitter</a>!</p><p>Thank you &#x1F468;&#x200D;&#x1F4BB;</p>]]></content:encoded></item><item><title><![CDATA[Design generators]]></title><description><![CDATA[<p>In this blog post, we will introduce you to four amazing design generators that will help you create stunning designs effortlessly. These generators are user-friendly and offer a wide range of options to suit your needs. Let&apos;s dive in!</p><p><a href="https://neumorphism.io/?ref=justrox.me">Neumorphism.io</a>: Neumorphism is a design trend that combines</p>]]></description><link>https://justrox.me/design-generators/</link><guid isPermaLink="false">66194021f34cbf00081d5794</guid><category><![CDATA[design]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Wed, 25 Oct 2023 14:04:58 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1518640467707-6811f4a6ab73?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxwYXR0ZXJufGVufDB8fHx8MTY5ODI0Mjc2M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1518640467707-6811f4a6ab73?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxwYXR0ZXJufGVufDB8fHx8MTY5ODI0Mjc2M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Design generators"><p>In this blog post, we will introduce you to four amazing design generators that will help you create stunning designs effortlessly. These generators are user-friendly and offer a wide range of options to suit your needs. Let&apos;s dive in!</p><p><a href="https://neumorphism.io/?ref=justrox.me">Neumorphism.io</a>: Neumorphism is a design trend that combines skeuomorphism and flat design elements to create a soft and realistic visual effect. The Neumorphism.io generator allows you to experiment with this style by providing sliders for various parameters such as light source direction, intensity, and contrast. With just a few clicks, you can achieve a visually pleasing neumorphic design that will make your project stand out.</p><p><a href="https://ui.glass/generator/?ref=justrox.me">UI Glass Generator</a>: If you&apos;re looking for a sleek and modern glasmorphism effect for your interface elements, look no further than the UI Glass Generator. This generator offers an array of customization options, including color selection, transparency control, and blur intensity. Whether it&apos;s buttons, cards, or navigation bars, this tool has got you covered.</p><p><a href="https://smoothshadows.com/?ref=justrox.me">Smooth Shadows</a>: Shadows can add depth and dimension to any design element when used correctly. The Smooth Shadows generator helps you create beautifully crafted shadow effects effortlessly. With adjustable parameters like blur radius, spread distance, and light source angle, you can achieve the perfect shadow effect for your project in no time.</p><p><a href="https://haikei.app/?ref=justrox.me">Haikei.app</a>: Backgrounds play a crucial role in setting the mood and enhancing the overall aesthetic appeal of your designs. Haikei.app is an incredible generator that allows you to create unique and eye-catching backgrounds with ease. Choose from various shapes, patterns, and color palettes to create a background that complements your design perfectly.</p><p>These design generators are incredibly helpful for designers of all skill levels. Whether you&apos;re a beginner looking to experiment with different styles or an experienced designer looking to save time, these tools have got you covered. So, give them a try and see how they can elevate your design projects to the next level!</p>]]></content:encoded></item><item><title><![CDATA[Send to Ghost Plugin]]></title><description><![CDATA[<p>I found a new and nice Obsidian Plugin called <a href="https://github.com/southpaw1496/obsidian-send-to-ghost?ref=justrox.me">Send to Ghost</a>. It allows you to directly publish your notes from Obsidian to your Ghost blog. I was intrigued by this plugin and decided to give it a try.</p><h2 id="installation">Installation</h2><p>First, I installed the plugin by following the instructions on</p>]]></description><link>https://justrox.me/send-to-ghost-plugin/</link><guid isPermaLink="false">66194021f34cbf00081d5792</guid><category><![CDATA[obsidian]]></category><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Fri, 06 Oct 2023 18:01:49 GMT</pubDate><content:encoded><![CDATA[<p>I found a new and nice Obsidian Plugin called <a href="https://github.com/southpaw1496/obsidian-send-to-ghost?ref=justrox.me">Send to Ghost</a>. It allows you to directly publish your notes from Obsidian to your Ghost blog. I was intrigued by this plugin and decided to give it a try.</p><h2 id="installation">Installation</h2><p>First, I installed the plugin by following the instructions on its GitHub page. It was a simple process, and I didn&apos;t encounter any issues during installation.</p><p>Once the plugin was installed, I configured its options where I had to enter my Ghost blog&apos;s URL and API key. Fortunately, the plugin provided clear instructions on how to obtain the API key from my Ghost blog.</p><h2 id="publishing">Publishing</h2><p>I went to my Obsidian vault and created this exact note. In the note&apos;s sidebar, there was now a new option called &quot;Publish Ghost.&quot; After editing and writing out this text, I clicked on the button. The plugin started processing my note and sent it to my Ghost blog. It displayed a progress bar indicating the upload status.</p><p>Once the upload was complete, a success message appeared, confirming that my note had been successfully published on my Ghost blog. I quickly checked my blog&apos;s dashboard and indeed found the published post there.</p><p>I was quite impressed with how smoothly everything worked. The Send to Ghost plugin made publishing content from Obsidian to Ghost incredibly convenient and streamlined. It eliminated the need for manual copying and pasting between platforms.</p><h2 id="caveat">Caveat</h2><p>One minor caveat I found is it doesn&apos;t support updating notes yet. The post duplicates whenever I run &quot;Send to Ghost&quot; command again. This limitation can be a bit frustrating for users who rely heavily on note-taking and need to make frequent updates to their notes.</p><h2 id="final-thoughts">Final Thoughts</h2><p>Overall, trying out Send to Ghost was a positive experience for me. It&apos;s a great tool for bloggers who use Obsidian as their note-taking app and want an easy way to publish their content on their Ghost blogs.</p>]]></content:encoded></item><item><title><![CDATA[Flipping the Kanban Board]]></title><description><![CDATA[<p>In this article, I&apos;ll explain why flipping your Kanban board can effectively reduce project anxiety and offer a clearer perspective on your tasks.</p><h3 id="uncertainty-anxiety">Uncertainty = Anxiety</h3><p>Let&apos;s start by recognizing that a significant source of stress and anxiety in our lives is uncertainty. When we&apos;re</p>]]></description><link>https://justrox.me/reverse-kanban/</link><guid isPermaLink="false">66194021f34cbf00081d578f</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Fri, 01 Sep 2023 17:17:33 GMT</pubDate><media:content url="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/rdjqfo1zcohisxmmyikt.png" medium="image"/><content:encoded><![CDATA[<img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/rdjqfo1zcohisxmmyikt.png" alt="Flipping the Kanban Board"><p>In this article, I&apos;ll explain why flipping your Kanban board can effectively reduce project anxiety and offer a clearer perspective on your tasks.</p><h3 id="uncertainty-anxiety">Uncertainty = Anxiety</h3><p>Let&apos;s start by recognizing that a significant source of stress and anxiety in our lives is uncertainty. When we&apos;re uncertain about the future, it can lead to a sense of unease and overwhelm. To address this, we naturally tend to view the moments closer to the present as more certain than those further into the future. If we were to graph this uncertainty over time, it might look something like this:</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/acx4zu5ylnjz5bdxytbt.png" class="kg-image" alt="Flipping the Kanban Board" loading="lazy" width="1062" height="1104"></figure><p>As time progresses, uncertainty narrows down, and we gain a better understanding of what lies ahead. This reduction in uncertainty allows us to tackle tasks with greater confidence, enabling us to focus on one thing at a time.</p><h2 id="the-problem-with-conventional-kanban-boards-layout">The Problem with Conventional Kanban Boards Layout</h2><p>However, when it comes to traditional Kanban boards, there&apos;s a mismatch between our natural perception of time and the way tasks are typically organized. Most Kanban boards are set up from left to right, representing the progression of tasks. Unfortunately, this orientation often presents uncertainty in a counterintuitive manner:</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/aahskpidzolnfd7zdf4h.png" class="kg-image" alt="Flipping the Kanban Board" loading="lazy" width="1186" height="1050"></figure><p>Completely opposite! As you can see, the conventional Kanban board places uncertainty closer to the &quot;origin&quot; of the board. At a glance, you&apos;re confronted with an overwhelming list of tasks in the backlog, which can fuel anxiety.</p><h3 id="what-if-we-flip-it">What if we flip it?</h3><p>Consider flipping your Kanban board to create a more intuitive representation of uncertainty:</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/uvqpsu3nizzfl3gabuei.png" class="kg-image" alt="Flipping the Kanban Board" loading="lazy" width="2044" height="788"></figure><p>In this flipped version, your accomplished tasks take center stage. This layout is much more intuitive and natural to think about. Instead of being immediately confronted by an ever-growing backlog, you&apos;re greeted by the tasks you&apos;ve successfully completed. This shift in focus can be incredibly motivating and encouraging, rather than inducing guilt or anxiety about unfinished tasks.</p><h3 id="my-implementation">My Implementation</h3><p>To provide a practical example of how you can implement a flipped Kanban board, I&apos;d like to share my own setup, which has proven itself to reduce my anxiety and enhance my productivity.</p><figure class="kg-card kg-image-card"><img src="https://justrox.sgp1.digitaloceanspaces.com/justrox-blog/2023/09/bohr1lwnf2r4ckoktk02.png" class="kg-image" alt="Flipping the Kanban Board" loading="lazy" width="1856" height="1108"></figure><ol><li><strong>Done:</strong> This is where I place tasks that I have successfully completed. Celebrating achievements is an essential part of this method and helps boost motivation.</li><li><strong>Doing:</strong> The &quot;Doing&quot; list is where I place tasks that I&apos;m actively working on. These are the items that are currently taking up my focus and attention.</li><li><strong>Waiting For:</strong> In this list, I track tasks that are dependent on external factors or waiting for input from others. It helps me keep tabs on pending tasks without cluttering my main workspace.</li><li><strong>Week:</strong> This list is dedicated to tasks I plan to complete within the current week. It helps me set weekly goals and prioritize tasks effectively.</li><li><strong>List of Active Projects Requiring Weekly Review:</strong> Here, I maintain a list of ongoing projects that require regular review. By having this dedicated space, I ensure that important projects are consistently monitored.</li></ol><h4 id="benefits-of-this-layout">Benefits of This Layout:</h4><ol><li><strong>Enhanced Intuitiveness:</strong> The layout is designed to be intuitive and aligns with our natural perception of time. It&apos;s easier to visualize progress and prioritize tasks effectively.</li><li><strong>Motivation:</strong> Placing completed tasks at the forefront is motivating. It encourages a positive mindset and reinforces a sense of accomplishment.</li><li><strong>Reduced Anxiety:</strong> The reduced focus on an overwhelming backlog minimizes anxiety and helps maintain a calm workflow.</li><li><strong>Diagnosing Bottlenecks:</strong> One of the advantages of this layout is that it makes it easier to diagnose issues in your workflow. If you notice that cards are not following a smooth diagonal flow from &quot;Week&quot; to &quot;Done,&quot; it&apos;s a sign that there might be a bottleneck somewhere in your process. This visual cue allows for quick identification and targeted improvement.</li></ol><h3 id="conclusion">Conclusion</h3><p>Flipping your Kanban board offers a simple trick to reduce anxiety by aligning the representation of uncertainty with our natural perception of time. This layout is not only more intuitive but also helps you approach your tasks with greater ease, ultimately leading to a more productive and less stressful workflow. Give it a try and let me know what you think!</p>]]></content:encoded></item><item><title><![CDATA[CRDTs: A Beginner's overview for building a collaborative app]]></title><description><![CDATA[Conflict-free replicated data types (CRDT) are a truly fascinating data structure with the power to keep distributed systems in-sync.]]></description><link>https://justrox.me/crdts-a-beginners-overview-for-building-a-collaborative-app/</link><guid isPermaLink="false">66194021f34cbf00081d578d</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Sat, 03 Dec 2022 11:43:18 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1642574224045-5765f1ea1477?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE0fHxzeW5jfGVufDB8fHx8MTY5MzU4MjExOHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1642574224045-5765f1ea1477?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE0fHxzeW5jfGVufDB8fHx8MTY5MzU4MjExOHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="CRDTs: A Beginner&apos;s overview for building a collaborative app"><p>Conflict-free replicated data types (CRDT) is one data structure I found truly fascinating. Basically, it enables distributed machines to eventually sync their data over time, i.e., eventual consistency.</p><p>To illustrate what I mean, consider the following scenario:</p><ul><li>Two person, A and B, are doing collaborative work in a shared document, e.g., Google Docs</li><li>There is no centralized server managing the state b/w A and B.</li><li>A sends state updates to B, then B changes it&apos;s state to reflect A&apos;s updates, and vice versa. &#xA0; &#xA0;</li></ul><p>Now, for some unknown reason, they got disconnected from each other for some time intervals. During this time, both person made changes to the document. Once they are reconnected, how should the program resolve their updates such that both have equivalent states?</p><p>One simple approach is to append timestamps to the updates and order events based on the timestamps. This approach, however, is predicated on the assumption that both machines have synchronous clocks that are immune to drifting and modification. This may result in data corruption depending on your use case.</p><p>CRDTs are intended to address this issue. Essentially, the goal is to structure the state updates in such a way that merge conflicts cannot occur*. This is accomplished by creating a data structure that has the following properties:</p><ul><li>Merging updates are commutative - which means that if we have a MERGE function that applies state updates, the order in which each update is applied should be irrelevant to the resulting state. &#xA0;</li></ul><p> &#xA0; &#xA0;C = MERGE( A, B) = MERGE(B, A)</p><ul><li>Merging updates are idempotent - which means that merging the same updates more than once results in the same state. &#xA0;</li></ul><p> &#xA0; &#xA0;C = MERGE( A, B ) = MERGE(C , A) = MERGE(C, B) &#xA0; &#xA0;</p><p>This is essentially combining updates in any order and frequency while producing the same result. This makes it ideal for distributed systems where communication packets may arrive duplicated, late, or in an erroneous order.</p><p>This approach is quite powerful and is widely used in distributed systems today. It&apos;s the ability to resolve conflicts in distributed databases as well as synchronize multiple nodes of a distributed system makes it an essential tool in today&apos;s systems.</p><h2 id="playing-with-crdts">Playing with CRDTs</h2><p>There are a lot of implementations of CRDTs out there. In JavaScript, for instance, we have Y.js (https://github.com/yjs/yjs) and automerge (https://github.com/automerge/automerge). There&#x2019;s also a Y.js demo (https://demos.yjs.dev/prosemirror/prosemirror.html) that allows you to play around with them and have your collaborative app running in just a few seconds. All messages are exchanged via webRTC while the state is managed via CRDTs. This can be a great sandbox to understand how CRDTs work.</p><p>I also attempted to build an offline-first application with Y.js-powered device syncing. The goal is to create a habit-tracking app that does not rely on a central server (https://habit-board.netlify.app).</p><!--kg-card-begin: html--><blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr">Four days since the start of the year. So far so good <a href="https://t.co/h8K9Df5QUD?ref=justrox.me">pic.twitter.com/h8K9Df5QUD</a></p>&#x2014; &#x1F6B2; Just (jxtro) (@justfizzbuzz) <a href="https://twitter.com/justfizzbuzz/status/1478172324587540482?ref_src=twsrc%5Etfw&amp;ref=justrox.me">January 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><!--kg-card-end: html--><p>I had a lot of fun messing around with it. Overall, CRDTs are an incredibly useful structure for distributed systems and are gaining a lot of momentum. It&apos;s definitely worth investing time in them to better understand how they work and how you can apply them.</p><h3 id="conclusion">Conclusion</h3><p>In conclusion, CRDTs provide an efficient way to keep distributed systems in sync. By structuring their data in such a way that merging is commutative and idempotent, they are able to maintain the same consistency regardless of delivery order and duplicate packets. This technique is widely used in distributed systems today and is gaining more and more traction. It&#x2019;s definitely worth looking into this structure and understanding how it works and how you can apply it in your own systems.</p><p><em>* I may be relaxing some jargon here, what I mean is that there&#x2019;s a deterministic algorithm or scheme that is guaranteed to combine any state updates such that no merge conflict, that demands manual resolution, is produced.</em></p><p>References</p><ul><li><a href="https://www.youtube.com/watch?v=M8-WFTjZoA0&amp;t=1821s&amp;ab_channel=TL%3BDR%2F%2FJavaScriptcodecastsforworkingdevs&amp;ref=justrox.me" rel="noopener noreferrer nofollow">https://www.youtube.com/watch?v=M8-WFTjZoA0&amp;t=1821s&amp;ab_channel=TL%3BDR%2F%2FJavaScriptcodecastsforworkingdevs</a></li><li><a href="https://www.youtube.com/watch?v=iEFcmfmdh2w&amp;t=835s&amp;ab_channel=CodingTech&amp;ref=justrox.me" rel="noopener noreferrer nofollow">https://www.youtube.com/watch?v=iEFcmfmdh2w&amp;t=835s&amp;ab_channel=CodingTech</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Socmed cut-off? 🤔]]></title><description><![CDATA[<p>In my own opinion, educational content about social media consumption management is more effective in the long run than clich&#xE9;d calls for total social media cut-off. </p><p>I mean, social media detox is beneficial, but it wouldn&apos;t hurt if we could also encourage people to find positive</p>]]></description><link>https://justrox.me/socmed-cut-off/</link><guid isPermaLink="false">66194021f34cbf00081d5788</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Fri, 12 Aug 2022 19:06:44 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHBob25lfGVufDB8fHx8MTY5MzU4MTk5N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHBob25lfGVufDB8fHx8MTY5MzU4MTk5N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Socmed cut-off? &#x1F914;"><p>In my own opinion, educational content about social media consumption management is more effective in the long run than clich&#xE9;d calls for total social media cut-off. </p><p>I mean, social media detox is beneficial, but it wouldn&apos;t hurt if we could also encourage people to find positive communities so they wouldn&apos;t get drained as much. It&apos;s much more productive than vilifying social media usage.</p><p>Banning social media usage appears to be a band-aid solution. Everyone will get back to social media eventually, one way or another. It&apos;s a technology that I believe is unavoidable. It&apos;s similar to how people demonize televisions, computers, and cell phones. Those who avoided it for various boomer reasons are now left out because they have fewer opportunities to explore and learn how to manage it. The same pessimistic trends are emerging, but this time for social media usage. I&apos;m sure those who avoid social media will miss out on the opportunities it provides.</p><p>Discovering our sense of belonging, on the other hand, addresses the root cause. Remember that social media is about people. So find your people. Follow your genuine interests. &#xA0;Search for an engaging community. Engage in positivity. Also, don&apos;t inform your real-life friends because you know how toxic they could get. Be ruthless in blocking and muting people with so much hate and resentment. Surround yourself with inspiring and motivating people. I hope it&apos;ll change how you view social media. Good luck!</p>]]></content:encoded></item><item><title><![CDATA[Some ideas regarding robots]]></title><description><![CDATA[<p><em>Here are my opinions on the question of whether artificial intelligence (AI) and robots should be granted rights comparable to those of humans.</em></p><p>It&apos;s been a long philosophical and scientific quest to define the differentiating factor that comprises a conscious being. Biologists may be keen on using the</p>]]></description><link>https://justrox.me/human-and-ai-rights/</link><guid isPermaLink="false">66194021f34cbf00081d5786</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Thu, 04 Aug 2022 21:47:52 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1546776310-eef45dd6d63c?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJvYm90fGVufDB8fHx8MTY5MzU4MTk2M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1546776310-eef45dd6d63c?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJvYm90fGVufDB8fHx8MTY5MzU4MTk2M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Some ideas regarding robots"><p><em>Here are my opinions on the question of whether artificial intelligence (AI) and robots should be granted rights comparable to those of humans.</em></p><p>It&apos;s been a long philosophical and scientific quest to define the differentiating factor that comprises a conscious being. Biologists may be keen on using the taxonomical approach, but this relies on the fact that the determining factor lies within the physical structure of the being (e.g. its DNA), and may completely disregard that it may be an emergent property that other physical structures might also exhibit. Theology-inclined individuals may lean on the existence of a soul, but properties exhibited by a soul-bounded being are not well-defined and is a heartbreaking risk if replicated. Speaking of which, from a thought experiment that most computer scientists are familiar with, if an entity exhibits a behavior indistinguishable from the behaviors observed on soul-bounded beings, then, the existence of a soul doesn&apos;t really matter. This is a modified and rephrased Turing Test applied to the presumed existence of a soul.</p><p>One of the most pushed forward factors contributing to consciousness is rationality. Although this may come intuitive, if we stop there we are left with an incomplete picture. Rationality alone can not define a conscious being. We already have supercomputers, control systems, and processes that crunch huge amounts of data and apply them to their use-cases rationally. Not to mention, human beings, assumed to be a prime example of conscious beings, do not always act rationally. Thus, rationality is not the end-all and be-all of consciousness.</p><p>If we look closely, rationality is not even the one making the shots. Being rational in a risk-free, noise-free, perfect environment is a waste of time and energy. Why do you need to be smart if the world is perfect? Why possess a problem-solving brain if there is no problem to solve? In a perfect world, we are all dumb. We only get smart because we live in a world of limited time and energy and we have an irrational craving to optimize our existence. That optimization requires rationality.</p><p>In light of this, it&apos;s possible that irrationality contributes to consciousness as well. Our rationality lacks direction on its own because there isn&apos;t an inherent variable to optimize into, i.e., there isn&apos;t an inherent reason to live and there isn&apos;t an inherent need to exist. However, our irrationality somehow determines the course of existence and aspires to add color to this depressingly objective reality. Rationality optimizes whatever irrationality wants. &#xA0;Hence, irrationality is the king, while rationality is the slave. </p><p>As a byproduct of evolution, our rationality optimizes our irrational desires to live, survive, and matter. We are just aimless intelligent beings without an irrational desire that directs our course. Our creativity is fueled by our irrationality. Our inner drive tells us this.</p><p>That said, perhaps our capacity to justify our irrationality is what distinguishes us from other species. We strike at the very core of autonomy and freedom when we use our rationality to justify our irrationality. We can make up stories, aspirations, and narratives to support our irrational need for food, affection, and survival. Perhaps that is ultimately what makes us human.</p><p>Consciousness, autonomy, and sentience, are the pillars of our moral circle, and by extension, its codification into our guidelines, laws, and constitutions. &#xA0;But it&apos;s not one of nature&apos;s physical laws that only humans may possess these properties. So I think it&apos;s not fair that these codifications only apply to human beings.</p><p>The fundamental tenet of the Universal Declaration of Human Rights is that everyone has unalienable rights that respect their individual freedom and autonomy. I believe that once we develop or come across beings that can rationally justify their irrationality, i.e., can defend their autonomy, freedom, and liberties, then our laws and constitutions should also take them into account.</p><p>Does this imply that I believe robots ought to have rights? It varies. They should be able to justify their irrationality, for starters. Robots that are pre-programmed and unable to generalize problems are automatically excluded by these criteria. It appears to be simple, and big-tech companies could make this right now with decent accuracy. Finding the root of their irrationality is more difficult, though.</p><p>If their irrationality comes from a human being controlling them, then they&apos;re not autonomous - they are merely tools and not conscious beings. These criteria then rule out AIs that behave like sophisticated data encoders and decoders; BTW, the majority of AIs presently in use are simply sophisticated encoders and decoders, e.g., Give me a sentence -&gt; I&apos;ll do some math -&gt; Outputs another sentence. On the other hand, if the robot&apos;s irrationality stems from within, meaning that they are free to choose and think for themselves, then they are autonomous and should have the same civil liberties as humans.</p><p>Idk. Just a thought.</p>]]></content:encoded></item><item><title><![CDATA[Be Happy]]></title><description><![CDATA[<p>The Happiness Equation by Neil Pasricha is the most therapeutic book I&apos;ve read. The book&apos;s central thesis is straightforward:</p><p>Want Nothing + Do anything = Have Everything</p><p>But I believe the most paradigm-shifting insight came from the first chapter. We are accustomed to believing that in order to</p>]]></description><link>https://justrox.me/happiness-equation/</link><guid isPermaLink="false">66194021f34cbf00081d5785</guid><dc:creator><![CDATA[Justine Che Romero]]></dc:creator><pubDate>Fri, 08 Jul 2022 17:37:59 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1464692805480-a69dfaafdb0d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGhhcHBpbmVzcyUyMGVxdWF0aW9ufGVufDB8fHx8MTY5MzU4MTg3M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1464692805480-a69dfaafdb0d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGhhcHBpbmVzcyUyMGVxdWF0aW9ufGVufDB8fHx8MTY5MzU4MTg3M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Be Happy"><p>The Happiness Equation by Neil Pasricha is the most therapeutic book I&apos;ve read. The book&apos;s central thesis is straightforward:</p><p>Want Nothing + Do anything = Have Everything</p><p>But I believe the most paradigm-shifting insight came from the first chapter. We are accustomed to believing that in order to be happy, we must work hard and achieve great success, i.e., happiness is a by-product of hard work and success. However, according to the book, this is backward: happiness is the precursor, not the byproduct, of doing great work that will eventually lead to success.</p><p>Although it may appear to be counterintuitive at first, the &quot;Be happy first&quot; mindset is reasonable. You are more engaged and focused when you are happy. And when you&apos;re engaged and focused, you produce excellent results! In addition, the book suggests research-backed activities that can make people happy in order to start a happiness-work-success flywheel:</p><ol><li>Three walks</li><li>The 20-minute replay</li><li>Random acts of kindness</li><li>A complete unplug</li><li>Hit Flow</li><li>2-minute meditations</li><li>Five gratitudes &#xA0;</li></ol><p>This simple shift in mindset has far-reaching consequences. For one thing, I&apos;ve noticed that this mindset makes me less frustrated with my output and less likely to overthink whether any activity will be fruitful. I believe the most significant effect was the shift from seeking personal validation for my performance to simply accepting the inherent joy I felt while doing the work.</p><p>This book has so many insights, and I&apos;m glad I read it before starting college, where most of us were emotionally challenged and tested. It&apos;s also one of my go-to books when I&apos;m feeling down. Most insecurities and unhelpful anxieties are eliminated by adopting this mindset. To be honest, it just makes my daily activities more enjoyable.</p>]]></content:encoded></item></channel></rss>