<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>reemdalvi/</title>
      <link>https://reemdalvi.com</link>
      <description>Thought dumping ground</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://reemdalvi.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sun, 19 Oct 2025 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Philosophical Undertones of Susanna Clarke&#39;s Piranesi</title>
          <pubDate>Sun, 19 Oct 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://reemdalvi.com/posts/philosophical-undertones-of-susanna-clarkes-piranesi/</link>
          <guid>https://reemdalvi.com/posts/philosophical-undertones-of-susanna-clarkes-piranesi/</guid>
          <description xml:base="https://reemdalvi.com/posts/philosophical-undertones-of-susanna-clarkes-piranesi/">&lt;p&gt;&lt;img src=&quot;/piranesi.png&quot; alt=&quot;piranesi&quot; /&gt;&lt;/p&gt;
&lt;p&gt;⚠️ Contains spoilers ⚠️&lt;/p&gt;
&lt;p&gt;Piranesi is a novel that looks simple on the surface, yet it opens into questions about reality, knowledge, and selfhood. The House in the story is both a place and an idea. It works as a physical maze but it also reads like a model of the mind, or even a modern echo of Plato&#39;s cave. Piranesi trusts his senses completely and takes the House as the whole world. Within his own frame of reference, everything makes sense, although it is far from the full picture.&lt;/p&gt;
&lt;p&gt;That&#39;s a deeply philosophical idea: Is truth determined by internal coherence or by correspondence with an external reality? Piranesi only begins to understand the truth when he notices small irregularities. His world does not collapse in a single moment, it loosens slowly as those cracks become impossible to ignore.&lt;/p&gt;
&lt;p&gt;The novel also ties memory to identity. Clarke suggests that who we are depends on the stories we hold in our minds and the language we use to make sense of them. Without that narrative, as in Piranesi&#39;s case, a person is reduced to something innocent and unburdened, although also profoundly alone.&lt;/p&gt;
&lt;h4 id=&quot;epistemology-and-the-limits-of-reasoning&quot;&gt;Epistemology and the limits of reasoning&lt;/h4&gt;
&lt;p&gt;Piranesi approaches the House with careful attention. He observes, records, and constructs a rational picture of his environment. The problem is that his entire system rests on an incorrect premise. Clarke hints at a familiar philosophical concern. Even if our thinking is sound, it can still mislead us when our starting assumptions are wrong. This recalls Descartes and Kant, who both raised doubts about how far reason can carry us if the structure of perception itself is uncertain.&lt;/p&gt;
&lt;h4 id=&quot;solitude-and-clarity&quot;&gt;Solitude and clarity&lt;/h4&gt;
&lt;p&gt;Piranesi&#39;s purity comes from his isolation. Cut off from manipulation, fear, and ambition, he becomes almost a moral ideal, shaped by patience and openness. This echoes Rousseau&#39;s idea of the noble savage and the older spiritual traditions that view solitude as a path to clear sight. His lack of worldly knowledge is not foolishness, it is a different form of clarity.&lt;/p&gt;
&lt;h4 id=&quot;memory-and-the-self&quot;&gt;Memory and the self&lt;/h4&gt;
&lt;p&gt;Piranesi&#39;s forgotten past raises the possibility that identity is neither fixed nor continuous. Once his life as Matthew Rose Sorenson is uncovered, we have to ask whether he is still that person or if he has become someone entirely different. Clarke hints that moral renewal might require letting go of the stories we cling to, a kind of inner reset.&lt;/p&gt;
&lt;h4 id=&quot;knowledge-power-and-their-moral-cost&quot;&gt;Knowledge, power, and their moral cost&lt;/h4&gt;
&lt;p&gt;Characters like the Other reflect a darker approach to knowledge. He seeks information as a form of control, not understanding. In contrast, Piranesi relates to the House with respect and even devotion. The novel pushes back against the idea that knowledge should dominate. It suggests that wonder, humility, and attention can be more honest ways of engaging with the world.&lt;/p&gt;
&lt;h4 id=&quot;the-house-as-a-picture-of-the-mind&quot;&gt;The House as a picture of the mind&lt;/h4&gt;
&lt;p&gt;If you read the House as a symbolic universe, or as the inner architecture of the mind, it becomes a model of a vast but ordered reality. Every hall and statue becomes an image, an archetype, or an idea. The House supports meaning and life, yet it is built from perception and memory rather than direct truth.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perhaps our world is similar to Piranesi&#39;s. We create sciences, philosophies, and belief systems that work coherently within the limits of human perception, but we cannot step outside those limits to check the foundation itself.&lt;/p&gt;
&lt;p&gt;Question is should we chase an ultimate truth that might lie beyond our reach, or should we live meaningfully within the structures we have?&lt;/p&gt;
&lt;p&gt;The Other pursue knowledge as conquest, and this hunger destroys him. Their ambition represents a distorted form of the human urge to overcome limitation. Piranesi, on the other hand, accepts the world before him and listens to it. This acceptance is not passivity, it is a form of wisdom grounded in experience rather than control.&lt;/p&gt;
&lt;p&gt;Clarke offers an inversion of a familiar philosophical tale. Instead of celebrating the one who breaks out of illusion, she highlights the insight that comes from recognising our limits and still finding beauty within them.&lt;/p&gt;
&lt;p&gt;The novel ties this back to ethics. The arrogance of the Other leads to cruelty and blindness, while Piranesi&#39;s humility creates compassion and a sense of wonder. What we believe about knowledge shapes how we behave. In the end, the way we know the world becomes inseparable from the way we live in it.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>The Birth of Digital Consciousness: Reading Greg Egan&#39;s Diaspora</title>
          <pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://reemdalvi.com/posts/the-birth-of-digital-consciousness-reading-greg-egans-diaspora/</link>
          <guid>https://reemdalvi.com/posts/the-birth-of-digital-consciousness-reading-greg-egans-diaspora/</guid>
          <description xml:base="https://reemdalvi.com/posts/the-birth-of-digital-consciousness-reading-greg-egans-diaspora/">&lt;p&gt;&lt;img src=&quot;/gregan.jpg&quot; alt=&quot;gregan&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Diaspora is a hard sci-fi read that imagines a post-human future where digital consciousness exists. This piece only reflects on the opening chapters that resonated with me most about the evolution of consciousness.&lt;/p&gt;
&lt;p&gt;It began with a portrayal of a digital mind coming into being, a kind of artificial embryogenesis, in what feels like a computational echo of biological development.&lt;/p&gt;
&lt;p&gt;An analogy with real-world embryology, where chemical signals activate genes to differentiate the body into parts like the head or thorax. Here, the raw structure of a consciousness is shaped by evolving algorithms.&lt;/p&gt;
&lt;p&gt;Early in its existence, the mind isn&#39;t aware of itself. It&#39;s just a set of independent components parsing the environment, interpreting signals through structures like infotropes, which I read as a kind of digital cortex.&lt;/p&gt;
&lt;p&gt;Then there are the input and output navigators, which function like sensory and motor systems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It had learnt to single out one or two threads from the symbols&#39; endless thousand-strand argument. It had learnt to narrate its own experience.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Beneath every moment of experience, there&#39;s a vast, silent machinery at work - complex, automatic, and mostly forgotten.&lt;/p&gt;
&lt;p&gt;As the digital being (Yatima) evolves, it starts interacting with others, learning to treat the world as a space of patterns and puzzles.&lt;/p&gt;
&lt;p&gt;Eventually, through these interactions and reflections, it forms a coherent model of self and becomes self-aware.&lt;/p&gt;
&lt;p&gt;I was left wondering if self-awareness was a necessary byproduct of parsing the world effectively? Or, a threshold we cross only under certain cognitive conditions?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yatima is drawn to the truth mines which are immersive mathematical spaces where digital minds test theorems, explore logical structures, and, most importantly, attempt to understand.&lt;/p&gt;
&lt;p&gt;Not just in the sense of storing or retrieving information, but in the deeper sense: making an idea part of oneself. For a digital mind, understanding isn&#39;t about downloading facts. It&#39;s about embedding those facts into the larger symbolic framework of thought, linking them with past experiences, current knowledge, and future implications.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Understanding an idea meant entangling it so thoroughly with all the other symbols in your mind that it changed the way you thought about everything.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It reframes understanding as a kind of internal transformation, not acquisition but integration.&lt;/p&gt;
&lt;p&gt;The concept of an outlook also stood out. In the polis, an outlook is a mental framework, a lens through which one interprets reality.&lt;/p&gt;
&lt;p&gt;Citizens can take a copy of another&#39;s outlook to see the world from their perspective. It&#39;s a literal, computational form of empathy, not abstract or symbolic, but structural.&lt;/p&gt;
&lt;p&gt;In our world, we&#39;re often told to “put ourselves in someone else&#39;s shoes,” but rarely asked what that actually means. Diaspora answers that: it means altering the very conditions under which thought occurs.&lt;/p&gt;
&lt;p&gt;Yatima wonders if every part of the mind can be restructured: memory, preferences, logic then what remains? There must be an immutable region: some kernel of identity that persists across change. Otherwise, what anchors selfhood?&lt;/p&gt;
&lt;p&gt;Diaspora explores this with clarity, defining the self not through narrative or symbolism, but through information, systems, and function.&lt;/p&gt;
&lt;p&gt;These early explorations shows a being coming into the world, not through instinct or tradition, but through intentional cognition, shaping itself by asking: what it means to be, to understand, and to seek truth.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>AWS RDS Subnet Migration</title>
          <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://reemdalvi.com/posts/aws-rds-subnet-migration/</link>
          <guid>https://reemdalvi.com/posts/aws-rds-subnet-migration/</guid>
          <description xml:base="https://reemdalvi.com/posts/aws-rds-subnet-migration/">&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;I&#39;ll walk through how to migrate AWS RDS instances from public subnets to private subnets within the same VPC without recreating the database. The method minimises downtime beyond a controlled failover using built-in AWS functionality.&lt;/p&gt;
&lt;p&gt;This post assumes you&#39;re using Amazon RDS (e.g. PostgreSQL or MySQL), with Multi-AZ deployment enabled, and your DB is currently hosted in a public subnet.&lt;/p&gt;
&lt;h2 id=&quot;why-it-matters&quot;&gt;Why it matters&lt;/h2&gt;
&lt;p&gt;RDS instances placed in public subnets are reachable via a public IP if they are marked as publicly accessible. Even if properly restricted with security groups, this is unnecessary exposure. The best practice is to deploy RDS instances in private subnets to eliminate any potential public routing path.&lt;/p&gt;
&lt;p&gt;The challenge is that you can&#39;t simply change the subnet group of an existing RDS instance within the same VPC. AWS doesn&#39;t allow that through the console or CLI once the instance is created, and many teams assume this requires snapshotting and recreating the DB, which comes with downtime and operational risk.&lt;/p&gt;
&lt;p&gt;Fortunately, there&#39;s a workaround that uses Multi-AZ failover to force the DB into private subnets safely and with minimal disruption.&lt;/p&gt;
&lt;h2 id=&quot;the-plan&quot;&gt;The Plan&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Reconfigure the subnet group to include private subnets&lt;/li&gt;
&lt;li&gt;Use Multi-AZ failover to shift the primary into one of them&lt;/li&gt;
&lt;li&gt;Remove public subnets from the subnet group once they are no longer in use&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;steps-taken&quot;&gt;Steps taken&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Take a Snapshot&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although the process is safe, taking a snapshot is a good precaution. It provides a rollback point in case anything unexpected occurs.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;Disable Multi-AZ temporarily&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can&#39;t remove or add subnets to a DB subnet group while they are in active use. Disabling Multi-AZ drops the standby and frees you to edit the subnet group.&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Edit the Subnet group&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remove any public subnets not being used. Add private subnets that span at least three availability zones.&lt;/p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;Re-enable Multi-AZ&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This triggers AWS to provision a new standby in one of the available private subnets.&lt;/p&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;&lt;strong&gt;Reboot with Failover&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It promotes the private standby to become the new primary, moving the live instance into a private subnet.&lt;/p&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;&lt;strong&gt;Disable Multi-AZ again&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This removes the remaining standby instance.&lt;/p&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;&lt;strong&gt;Remove the final public subnet&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that no part of the RDS deployment uses the public subnet, you can remove it cleanly from the subnet group.&lt;/p&gt;
&lt;ol start=&quot;8&quot;&gt;
&lt;li&gt;&lt;strong&gt;Re-enable Multi-AZ (final)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Enabling Multi-AZ again will create a new standby in one of the private subnets, completing the migration.&lt;/p&gt;
&lt;h2 id=&quot;observations&quot;&gt;Observations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Failover causes the only real downtime: this is expected and manageable&lt;/li&gt;
&lt;li&gt;Disabling/enabling Multi-AZ also caused a brief I/O pause, especially once the instance was already in a private subnet&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dig &amp;lt;rds-endpoint&amp;gt;&lt;/code&gt; was useful for verifying IP changes and subnet shifts during the migration&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;
&lt;p&gt;This approach avoids the need to snapshot and restore or spin up a new DB instance. It leverages AWS&#39;s own failover mechanism to move a live production database into a secure, isolated network space with minimal effort and downtime.&lt;/p&gt;
&lt;p&gt;If you&#39;re still running RDS in a public subnet, you can migrate it safely without a full rebuild, just understand the timing and plan for the short outage when failover occurs.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>AWS Elastic Beanstalk Load Balancer</title>
          <pubDate>Wed, 02 Apr 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://reemdalvi.com/posts/aws-elastic-beanstalk-load-balancer/</link>
          <guid>https://reemdalvi.com/posts/aws-elastic-beanstalk-load-balancer/</guid>
          <description xml:base="https://reemdalvi.com/posts/aws-elastic-beanstalk-load-balancer/">&lt;p&gt;When deploying applications on AWS Elastic Beanstalk (EB), you have two main options for handling load balancing: let Beanstalk manage it for you automatically, or manually configure your own Application Load Balancer (ALB) and hook it into your environment.&lt;/p&gt;
&lt;h2 id=&quot;manual-ec2-alb-custom-infrastructure&quot;&gt;Manual EC2 + ALB (Custom Infrastructure)&lt;/h2&gt;
&lt;p&gt;This approach gives you full control over every part of your architecture. You manage EC2 instances, the ALB, security groups, scaling policies, and networking. It&#39;s ideal for production-grade setups, custom routing logic, and when you need fine-tuned control over TLS, autoscaling, and deployment strategies.&lt;/p&gt;
&lt;p&gt;But that power comes with a cost: it&#39;s slower to set up, requires solid AWS knowledge, and involves more ongoing maintenance.&lt;/p&gt;
&lt;h2 id=&quot;elastic-beanstalk-load-balanced-mode&quot;&gt;Elastic Beanstalk (Load-Balanced Mode)&lt;/h2&gt;
&lt;p&gt;Elastic Beanstalk offers a simplified, managed path for deploying applications, especially when you&#39;re focused on getting something up and running quickly. It handles most of the heavy lifting for you: provisioning infrastructure, health monitoring, autoscaling, and even basic CI/CD hooks.&lt;/p&gt;
&lt;p&gt;However, this convenience comes with trade-offs in control and transparency. Beanstalk can abstract away critical pieces of infrastructure, and small changes (like a platform upgrade) can unintentionally trigger major infra changes like recreating load balancers or breaking TLS setups.&lt;/p&gt;
&lt;h2 id=&quot;when-ssl-tls-handshakes-fail-silently&quot;&gt;When SSL/TLS Handshakes Fail Silently&lt;/h2&gt;
&lt;p&gt;Setting up HTTPS for your application on AWS Elastic Beanstalk seems straightforward, until it isn&#39;t. If you&#39;re not careful with how TLS is configured, especially in load-balanced environments, you can end up in a situation where  &lt;strong&gt;clients silently fail to connect&lt;/strong&gt;  and you have  &lt;strong&gt;no logs, no errors, and no visibility&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;scenario-upgrading-your-beanstalk-environment&quot;&gt;&lt;strong&gt;Scenario: Upgrading Your Beanstalk Environment&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You&#39;re using Elastic Beanstalk to manage a Node.js application. It&#39;s deployed in a load-balanced environment using a default Beanstalk-managed ALB (Application Load Balancer). At some point, you upgrade the platform to a latest version.&lt;/p&gt;
&lt;p&gt;As part of the upgrade, a new security policy was attached which uses  &lt;strong&gt;stricter cipher suites&lt;/strong&gt; or &lt;strong&gt;limited TLS version support&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The deployment goes live. Beanstalk reports success. Health checks are green. No alarms are triggered.&lt;/p&gt;
&lt;h3 id=&quot;problem-certain-clients-can-t-connect&quot;&gt;&lt;strong&gt;Problem: Certain Clients Can&#39;t Connect&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Without realising it, you&#39;ve now made your application  &lt;strong&gt;inaccessible to some clients&lt;/strong&gt;. Specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clients using &lt;strong&gt;older TLS libraries&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Legacy systems that only support outdated cipher suites&lt;/li&gt;
&lt;li&gt;Browsers or mobile devices in locked-down environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These clients attempt to connect but  &lt;strong&gt;fail during the TLS handshake&lt;/strong&gt;. Since the request  &lt;strong&gt;never completes&lt;/strong&gt;, it doesn&#39;t reach your application and it doesn&#39;t even show up in your app logs.&lt;/p&gt;
&lt;p&gt;To make matters worse,  &lt;strong&gt;ALB access logs weren&#39;t enabled&lt;/strong&gt;, so you have zero trace of the failed handshakes at the infrastructure level.&lt;/p&gt;
&lt;h2 id=&quot;why-this-happens&quot;&gt;Why This Happens&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TLS handshakes fail  before the HTTP request is made.&lt;/li&gt;
&lt;li&gt;The ALB doesn&#39;t forward anything to your app so your app knows nothing.&lt;/li&gt;
&lt;li&gt;If access logging on the ALB is disabled (which is the default),  &lt;strong&gt;you have no visibility&lt;/strong&gt;  into the failure.&lt;/li&gt;
&lt;li&gt;Beanstalk&#39;s “all green” status is based on internal health checks, not edge-case TLS compatibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-to-avoid-this&quot;&gt;How to Avoid this&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Verify TLS compatibility before deploying a new policy (&lt;a rel=&quot;external&quot; href=&quot;https://docs.aws.amazon.com/elasticloadbalancing/latest/application/describe-ssl-policies.html&quot;&gt;AWS Security policies&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;If you serve legacy clients or B2B partners, assume there&#39;s at least one ancient TLS stack out there still hanging on&lt;/li&gt;
&lt;li&gt;Have ALB logs enabled&lt;/li&gt;
&lt;li&gt;Monitor for traffic drops, not just error rates&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;These issues don&#39;t come from bad code, they come from &lt;strong&gt;small configuration changes with large ripple effects&lt;/strong&gt;. In environments like Beanstalk where AWS handles infra for you, it&#39;s easy to forget how much is happening under the hood.&lt;/p&gt;
&lt;p&gt;While the issue in this scenario stemmed from an TLS misconfiguration at the load balancer level, it was indirectly caused by the way the app was deployed. Because containers were not used, upgrading the Node.js version meant upgrading the entire Elastic Beanstalk platform, which in turn triggered infrastructure changes, including a new, stricter TLS policy.&lt;/p&gt;
&lt;p&gt;If the application had been containerised, the Node.js version in the image was pinned and deployed as-is, without having to touch the load balancer or changing policies. It&#39;s a reminder that containerisation doesn&#39;t just make deployment more flexible, it reduces the risk of platform-coupled surprises.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Debugging a Production Nightmare</title>
          <pubDate>Wed, 19 Mar 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://reemdalvi.com/posts/debugging-a-production-nightmare/</link>
          <guid>https://reemdalvi.com/posts/debugging-a-production-nightmare/</guid>
          <description xml:base="https://reemdalvi.com/posts/debugging-a-production-nightmare/">&lt;p&gt;I was assigned a seemingly simple task that spiralled into a production issue affecting unrelated parts of the system. What followed was a valuable (and painful) lesson in system design, JavaScript quirks, and the risks of shared mutable state in a monolithic architecture.&lt;/p&gt;
&lt;h2 id=&quot;the-setup&quot;&gt;The setup&lt;/h2&gt;
&lt;p&gt;The system was a large monolith composed of multiple logical components all running in the same process. One of these components used a hardcoded list of “questions” as part of a dynamic form flow.&lt;/p&gt;
&lt;p&gt;My task was to add a new question to this list. This was the first &quot;new&quot; question after the feature was first implemented almost a year ago.&lt;/p&gt;
&lt;p&gt;No database migration, no configuration system, just append an object to a static array declared in code.&lt;/p&gt;
&lt;p&gt;I wasn&#39;t thrilled about the hardcoded setup, but it was meant to be a low-risk change. I added the question, tested the feature, passed QA, and deployed to production.&lt;/p&gt;
&lt;h2 id=&quot;the-bug&quot;&gt;The bug&lt;/h2&gt;
&lt;p&gt;The next day, a different component of the codebase started showing a pre-filled answer to this new question. Except no one had filled them in. There was no data entry. These answers were ghosts.&lt;/p&gt;
&lt;p&gt;This should have been impossible.&lt;/p&gt;
&lt;p&gt;I checked the database: nothing.
I read through the code paths: nothing.
I added logs directly in production. That&#39;s when I saw it.&lt;/p&gt;
&lt;h2 id=&quot;the-cause&quot;&gt;The cause&lt;/h2&gt;
&lt;p&gt;The array of questions was being  &lt;strong&gt;shared across modules&lt;/strong&gt;, passed around by reference. Somewhere downstream, another part of the application was  &lt;strong&gt;mutating&lt;/strong&gt;  that array, modifying it in place by appending answers.&lt;/p&gt;
&lt;p&gt;So my new question, added to the shared array, started receiving mutations intended for other workflows. That corrupted shared state leaked across service boundaries and showed up in user-facing API responses.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot; &gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; questions&lt;/span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;name&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;text&amp;quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;age&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;number&amp;quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;  getAllQuestions&lt;/span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; questions&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; getAllQuestions&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;getAllQuestions was imported in various modules leading to adding an answer somewhere along the way...&lt;/p&gt;
&lt;h2 id=&quot;the-quick-fix&quot;&gt;The quick fix&lt;/h2&gt;
&lt;p&gt;Deep-copy the array before passing it between modules.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot; &gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getAllQuestions&lt;/span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;parse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;stringify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;questions&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, everything worked as expected. The newly added question remained untouched, and the API behaviour stabilised.&lt;/p&gt;
&lt;h2 id=&quot;long-term-fix&quot;&gt;Long-term fix&lt;/h2&gt;
&lt;p&gt;Deep-copying solved the immediate issue, but the real problem was deeper: the system had no clear boundaries or ownership of data, and critical config was being shared and mutated across modules.&lt;/p&gt;
&lt;p&gt;A better long-term solution would involve moving the questions into a database where they are not entangled with application logic. Write tests that assert immutability and fail if shared structured are unexpectedly mutated.&lt;/p&gt;
&lt;p&gt;Eventually, parts of the monolith should probably be refactored into loosely coupled services, or at least well-encapsulated modules that communicate through defined interfaces, not shared memory.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;const in JS/TS gives you a false sense of safety&lt;/strong&gt;, it only protects the reference, not the contents.&lt;/p&gt;
&lt;p&gt;Always assume your data can be mutated unless you&#39;ve made it truly read-only.&lt;/p&gt;
&lt;p&gt;If you&#39;re building anything more complex than a to-do list,  &lt;strong&gt;shared mutable state is a trap&lt;/strong&gt;. Wrap your arrays. Clone your objects. Trust no one. Especially not past developers. Especially not yourself.&lt;/p&gt;
&lt;p&gt;And maybe, just maybe, don&#39;t hardcode production-critical data into a single shared array.&lt;/p&gt;
</description>
      </item>
    </channel>
</rss>
