<?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"><channel><title><![CDATA[Soumyajit's Engineering Journal]]></title><description><![CDATA[Soumyajit's Engineering Journal]]></description><link>https://soumyajit1216.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 01:36:35 GMT</lastBuildDate><atom:link href="https://soumyajit1216.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Gunam Init and Builder Roadmap: How I'm Building an On-Premise Rust Agent]]></title><description><![CDATA[One of the biggest frustrations developers face is configuration. Whether it's integrating a new library, working with FFI, or setting up infrastructure, the first experience often involves reading pa]]></description><link>https://soumyajit1216.hashnode.dev/how-i-m-building-an-on-premise-rust-agent</link><guid isPermaLink="true">https://soumyajit1216.hashnode.dev/how-i-m-building-an-on-premise-rust-agent</guid><category><![CDATA[Rust]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[#agent]]></category><category><![CDATA[FFI]]></category><category><![CDATA[#systemengineer]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[engineering]]></category><category><![CDATA[iot]]></category><dc:creator><![CDATA[Soumyajit Bhattacharya]]></dc:creator><pubDate>Thu, 02 Jul 2026 20:21:00 GMT</pubDate><content:encoded><![CDATA[<p>One of the biggest frustrations developers face is configuration. Whether it's integrating a new library, working with FFI, or setting up infrastructure, the first experience often involves reading pages of documentation before writing a single line of useful code.</p>
<p>From the beginning, I wanted Gunam to feel different.</p>
<p>My goal has been simple: configuring Gunam should be one of the easiest parts of integrating it into an application. Developers should focus on <strong>what</strong> they want to monitor, not on how the library is implemented internally.</p>
<p>That idea became the foundation of Gunam's configuration layer.</p>
<h2>A Simple Goal</h2>
<p>The design objective was clear from day one:</p>
<blockquote>
<p>Developers should only choose the sensors they want to monitor and how those sensors should be monitored.</p>
</blockquote>
<p>Everything else should be handled by Gunam.</p>
<p>To achieve that, the configuration layer is built around three core concepts.</p>
<h2>Sensor Kind</h2>
<p>The first decision is <strong>what</strong> you want to monitor.</p>
<p>Every deployment is different. A kiosk, an industrial machine, or an Android TV box will have different monitoring requirements. Not every application needs CPU, battery, network, storage, or memory metrics.</p>
<p>Instead of collecting everything by default, Gunam allows developers to explicitly choose the sensors they care about.</p>
<p>This keeps the configuration simple while giving engineers complete control over the data they collect.</p>
<h2>Polling Strategy</h2>
<p>Not every sensor should be polled the same way.</p>
<p>Some information needs to be collected at regular intervals, while other events are only meaningful when they change or when an application explicitly requests them.</p>
<p>For example:</p>
<ul>
<li><p>CPU usage may be collected every few seconds.</p>
</li>
<li><p>Network connectivity may be checked every minute.</p>
</li>
<li><p>Battery level may only be reported when its value changes.</p>
</li>
<li><p>Some sensors may only be queried on demand.</p>
</li>
</ul>
<p>Every sensor tells a different story, so Gunam allows each one to have its own polling strategy instead of forcing a single approach across the entire system.</p>
<h2>Transport</h2>
<p>Once the sensors and polling strategies have been configured, the final step is deciding where the collected data should go.</p>
<p>Different applications have different requirements. Some may send telemetry to a REST API, others may stream data over TCP, while some deployments may simply collect information locally without transmitting anything.</p>
<p>Rather than enforcing a single transport mechanism, Gunam gives developers the flexibility to choose the communication strategy that best fits their system.</p>
<p>This layer also lays the foundation for higher-level capabilities such as alerting, analytics, machine learning pipelines, and remote fleet management.</p>
<h2>Looking Ahead</h2>
<p>This configuration layer is only the first step in Gunam's architecture.</p>
<p>Once configuration is complete, the next challenge is deciding <strong>how</strong> those sensors should execute efficiently. That's where thread management comes in, followed by thread observability so developers can understand exactly what Gunam is doing at runtime.</p>
<p>In the next article, I'll dive deeper into the second layer of Gunam and explain how I'm approaching thread management while keeping the developer experience simple.</p>
<p>If you'd like to follow the project's progress or contribute, you can find Gunam on GitHub:</p>
<p><strong>GitHub:</strong> <a href="https://github.com/IAmInYourKernel/gunam">https://github.com/IAmInYourKernel/gunam</a></p>
]]></content:encoded></item><item><title><![CDATA[Why I stopped trusting device_class to tell me what a device can do .]]></title><description><![CDATA[I almost shipped a bug unknowingly. Probably this bug would have shown up on someone else's hardware without them knowing.
I'm building Gunam, a cloud-free, FFI-first Rust agent for on-premises device]]></description><link>https://soumyajit1216.hashnode.dev/why-i-stopped-trusting-device-class-to-tell-me-what-a-device-can-do</link><guid isPermaLink="true">https://soumyajit1216.hashnode.dev/why-i-stopped-trusting-device-class-to-tell-me-what-a-device-can-do</guid><category><![CDATA[Rust]]></category><category><![CDATA[iot]]></category><category><![CDATA[OTA]]></category><category><![CDATA[#OnPremise]]></category><category><![CDATA[telemetry]]></category><category><![CDATA[systemprogramming]]></category><category><![CDATA[error handling]]></category><dc:creator><![CDATA[Soumyajit Bhattacharya]]></dc:creator><pubDate>Tue, 30 Jun 2026 19:24:54 GMT</pubDate><content:encoded><![CDATA[<p>I almost shipped a bug unknowingly. Probably this bug would have shown up on someone else's hardware without them knowing.</p>
<p>I'm building <a href="https://github.com/IAmInYourKernel/Gunam">Gunam</a>, a cloud-free, FFI-first Rust agent for on-premises device management — OTA updates, telemetry, panic-safe operation, for environments where you can't assume a server is even reachable. Early on, the design seemed obvious: detect what OS you're running on, then run the OTA strategy that matches that OS.</p>
<p>Previously, when I was creating the device class to get the access control of the system, I accidentally never asked the correct question to myself: Is the device class enough to give you complete access?<br />enum DeviceClass { Linux, Android, Windows, Mac, }</p>
<p>Detect Linux → use GRUB-style A/B slot switching. Detect Android → use Android's update mechanisms. Simple dispatch table. I was ready to build the OTA logic directly on top of this.</p>
<p>The actual question comes, "WHO CONTROLLS THE BOOT LOADER ?"</p>
<h3>The assumption that almost created a <strong>catastrophe</strong></h3>
<p>Here's the part I'd glossed over: <strong>that HAL is only reachable if you're the one who built the OS image.</strong> If you're an OEM flashing your own AOSP build, you can talk to it. If you're a regular app — or a <code>.so</code> library sitting inside a regular app, which is exactly what Gunam is — you have <em>zero</em> access to it. Not "restricted access." Zero. No permission grants it. It's locked away from userspace apps by design, for the same reason you don't want any random app able to flip your boot partition.</p>
<p>So device class doesn't actually tell you whether bootloader-level A/B is available. It tells you the OS family. Whether you can <em>do</em> anything with that OS's update mechanism depends entirely on how the device was deployed — whether you're the OEM or just an app running on stock hardware.</p>
<p>If I'd built the OTA dispatch logic directly on <code>DeviceClass</code>, the code would have compiled fine, looked correct, and then silently attempted bootloader operations it had no permission to perform — on whichever Android device someone actually deployed Gunam to. That's the worst kind of bug: invisible until a real user hits it. Cost created the catastrophe .</p>
<h3>The solution I got</h3>
<p>Device classes answer what OS I am, which was not enough to understand how much write and read access I actually have. Here at this point, the introduction of access tiers comes.<br />enum AccessTier { ImageLevel, PrivilegedSystem, AppLevel, ReadOnly }.<br />The same OS can give you different access. As Gunam does telemetry and OTA. Without proper access, the system will give us a permission error, which will block the outcome we want .</p>
<p>A Linux kiosk box you flash yourself is Image level. A rooted Android device is Privilege level. A stock Android app — which is most real-world Android deployments — is App level. And critically, there's a tier for "I don't actually know, or I have no access"—read—only— which exists specifically so the agent can say "I can't safely act here" instead of guessing and failing silently later.</p>
<h3>What this actually bought me</h3>
<p>Beyond avoiding the bug: every OTA-related function in Gunam now has to explicitly handle all four tiers, because the type system makes it impossible to forget one. It goes deep into every layer and asks for permission before it returns the final access control.</p>
<p>The main goal of building Gunam was not only to provide telemetry but to build a system that is fault-tolerant. Managing On-premises devices is hard when the system is not ready to handle errors.  </p>
<p>This blog is not just about sharing the experience but to remind myself that when you have all the answers in the world... Asking the right question at the right time matters.  </p>
<p>If you'd like to follow the project's progress or contribute, you can find Gunam on GitHub:</p>
<p><strong>GitHub:</strong> <a href="https://github.com/IAmInYourKernel/gunam"><strong>https://github.com/IAmInYourKernel/gunam</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Building the monitoring segment for CPU and Battery ]]></title><description><![CDATA[Reading CPU and Battery: The Code Wasn't the Hard Part
Reading CPU and battery information sounds very easy. You search for a library or ask AI for a better and quicker way to get the data for display]]></description><link>https://soumyajit1216.hashnode.dev/building-the-monitoring-segment-for-cpu-and-battery</link><guid isPermaLink="true">https://soumyajit1216.hashnode.dev/building-the-monitoring-segment-for-cpu-and-battery</guid><dc:creator><![CDATA[Soumyajit Bhattacharya]]></dc:creator><pubDate>Mon, 29 Jun 2026 19:51:44 GMT</pubDate><content:encoded><![CDATA[<h3>Reading CPU and Battery: The Code Wasn't the Hard Part</h3>
<p>Reading CPU and battery information sounds very easy. You search for a library or ask AI for a better and quicker way to get the data for display.</p>
<p>Using AI is exactly what I did.</p>
<p>Within a few seconds, I found <code>/proc/stat</code> and <code>/sys/class/power_supply</code>.</p>
<p>I quickly realized that writing the code was no longer the difficult part. Years ago, developers spent hours searching Google, reading documentation, and browsing Stack Overflow. Today, we ask AI, and it usually gives us a working starting point within seconds.</p>
<p>The real challenge was understanding the operating system itself.</p>
<h2>CPU: Reading Numbers</h2>
<p>On Linux, CPU statistics are exposed through <code>/proc/stat</code>.</p>
<p>The moment you read the file, you'll see something like:</p>
<pre><code class="language-text">10132153 290696 3084719 46828483 16683 0 25195 0
</code></pre>
<p>At first glance, these numbers don't mean much.</p>
<p>What I learned is that they are cumulative counters that have been increasing since the system booted. They are <strong>not</strong> CPU percentages.</p>
<p>To calculate CPU usage, you have to:</p>
<ul>
<li><p>Read the counters.</p>
</li>
<li><p>Wait for a short interval.</p>
</li>
<li><p>Read them again.</p>
</li>
<li><p>Calculate the difference between the two readings.</p>
</li>
<li><p>Determine how much of that difference represents busy time.</p>
</li>
</ul>
<p>Operating systems rarely give you exactly what you want. Instead, they expose low-level primitives, and it becomes your responsibility to derive the higher-level metrics from them.</p>
<h2>Battery: When the Environment Becomes the Problem</h2>
<p>Getting battery information looked even easier.</p>
<p>Linux exposes battery information under <code>/sys/class/power_supply</code>.</p>
<p>I wrote code to locate the battery, read its capacity, charging state, and cycle count.</p>
<p>Everything looked correct.</p>
<p>Then I tested it.</p>
<p>Nothing worked.</p>
<p>The reason wasn't my code.</p>
<p>I was running inside WSL on a Windows laptop.</p>
<p>WSL is a compatibility layer rather than a full Linux installation running directly on the hardware. There is no real Linux battery device inside <code>/sys/class/power_supply</code>. The battery belongs to Windows, not to the Linux environment running under WSL.</p>
<p>This taught me an important lesson.</p>
<p>Sometimes your code is perfectly correct, but the environment simply cannot provide the information you're asking for.</p>
<h2>Key Insight: Details Matter</h2>
<p>To be honest, I didn't write most of the operating system or filesystem-related code from scratch. AI generated a significant portion of it.</p>
<p>What AI couldn't do was explain <strong>why</strong> the battery wasn't available in WSL. It couldn't magically expose hardware that the operating system itself wasn't exposing.</p>
<p>That realization made me think.</p>
<p>As engineers, we often become so excited about reaching the final outcome that we overlook the small details that determine whether our solution actually works.</p>
<p>In my case, I overlooked the execution environment.</p>
<p>Similarly, AI is only as useful as the context we provide. If we ignore important details that are still our responsibility—such as the operating system, the execution environment, or hardware limitations—AI cannot compensate for those gaps.</p>
<p>AI can change how we write code.</p>
<p>It cannot change how we think.</p>
<p>Today, generating code is becoming easier and cheaper than ever.</p>
<p>True engineering, however, still lies in understanding the system, asking the right questions, and paying attention to the details that ultimately determine whether a solution succeeds or fails.  </p>
<p>If you'd like to follow the project's progress or contribute, you can find Gunam on GitHub:</p>
<p><strong>GitHub:</strong> <a href="https://github.com/IAmInYourKernel/gunam">https://github.com/IAmInYourKernel/gunam</a></p>
]]></content:encoded></item><item><title><![CDATA[Building Gunam: Why Modern Monitoring Should Work Offline First]]></title><description><![CDATA[Problem Statement
While working on kiosk software at Zuchiz, I realized that many production issues cannot be solved from the application layer alone.
No matter how well an application is designed, it]]></description><link>https://soumyajit1216.hashnode.dev/building-gunam-why-modern-monitoring-should-work-offline-first</link><guid isPermaLink="true">https://soumyajit1216.hashnode.dev/building-gunam-why-modern-monitoring-should-work-offline-first</guid><category><![CDATA[Rust]]></category><category><![CDATA[Rust programming]]></category><category><![CDATA[systemprogramming]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[Linux]]></category><category><![CDATA[iot]]></category><category><![CDATA[On Premise]]></category><dc:creator><![CDATA[Soumyajit Bhattacharya]]></dc:creator><pubDate>Sun, 28 Jun 2026 07:54:26 GMT</pubDate><content:encoded><![CDATA[<h1>Problem Statement</h1>
<p>While working on kiosk software at Zuchiz, I realized that many production issues cannot be solved from the application layer alone.</p>
<p>No matter how well an application is designed, its reliability ultimately depends on the environment in which it runs. In production, there are several factors outside the application's control that can silently degrade the user experience or even break the entire workflow.</p>
<p>Some common examples include:</p>
<ul>
<li><p>Unstable or intermittent internet connectivity</p>
</li>
<li><p>Weak or fluctuating power supply</p>
</li>
<li><p>Hardware failures such as storage corruption, memory issues, or peripheral malfunctions</p>
</li>
<li><p>Device-specific operating system issues</p>
</li>
<li><p>Unexpected application crashes or system restarts</p>
</li>
</ul>
<p>These problems often surface as application failures, even though the root cause lies much deeper in the system.</p>
<p>Another challenge becomes evident as deployments scale: software updates.</p>
<p>Managing hundreds or thousands of on-premise devices is far more difficult than updating software running in the cloud. Although Over-the-Air (OTA) updates exist, most existing solutions are designed for embedded Linux environments. There are comparatively fewer solutions that provide the same level of flexibility for Android-based kiosks, Android TV boxes, Windows devices, or heterogeneous deployments.</p>
<p>As the number of deployed devices grows, monitoring device health and delivering reliable software updates become operational challenges rather than just engineering tasks. The complexity increases, costs rise, and scaling the business becomes significantly harder.  </p>
<h1>The Solution I Wanted to Build</h1>
<p>Earlier this year, I started learning Rust with a different goal in mind. I wanted to migrate an ERP application I had built in Node.js to Rust so that it could deliver better performance while running on cost-effective production servers.</p>
<p>As I learned more about Rust, I realized that performance wasn't its biggest advantage. What impressed me most was its approach to memory safety, predictable resource management, and its ability to build reliable system level software.</p>
<p>That completely changed the way I thought about solving production problems.</p>
<p>The challenges I had experienced with on-premise devices monitoring hardware health, collecting telemetry, delivering reliable software updates, and continuing to operate even when connectivity was unreliable could not be solved entirely from the application layer. They required software that could interact closely with the operating system while remaining stable over long periods of time.</p>
<p>Rust felt like the right foundation for building that kind of software.</p>
<p>That realization led to the creation of <strong>Gunam</strong>.</p>
<p>Gunam is an open-source Rust agent designed for managing fleets of on-premises devices. It focuses on three core capabilities:</p>
<ul>
<li><p>Reliable OTA software updates</p>
</li>
<li><p>Telemetry and system health collection</p>
</li>
<li><p>Offline first synchronization for unreliable network environments</p>
</li>
</ul>
<p>The project is designed with reliability as a first-class goal. One of Gunam's design goals is a panic-safe FFI layer that prevents Rust panics from propagating into the host application, making it easier to integrate Gunam into existing software regardless of the language it was written in.</p>
<p>Gunam is currently Linux first, with planned support for Android and Windows in future releases.  </p>
<h3>Gunam is still in its early stages, and I'm currently working toward the first public release.</h3>
<p>The initial version focuses on building a solid foundation with:</p>
<ul>
<li><p>Operating system detection</p>
</li>
<li><p>CPU, memory, battery, internet, and uptime monitoring</p>
</li>
<li><p>Image-based OTA updates with A/B partitioning and delta update support</p>
</li>
<li><p>A networking layer for telemetry, alerts, and remote session APIs</p>
</li>
<li><p>A panic-safe FFI layer for reliable integration with existing applications</p>
</li>
</ul>
<p>This is only the beginning. In future articles, I'll share the architecture, design decisions, implementation details, and the lessons I learned while building Gunam in public.</p>
<p>If you'd like to follow the project's progress or contribute, you can find Gunam on GitHub:</p>
<p><strong>GitHub:</strong> <a href="https://github.com/IAmInYourKernel/gunam">https://github.com/IAmInYourKernel/gunam</a></p>
]]></content:encoded></item></channel></rss>