<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Engineering on Vedant Andhale</title>
    <link>https://www.vedant.me/tags/engineering/</link>
    <description>Recent content in Engineering on Vedant Andhale</description>
    <image>
      <url>https://www.vedant.me/</url>
      <link>https://www.vedant.me/</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 10 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.vedant.me/tags/engineering/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>A small tool should finish one job</title>
      <link>https://www.vedant.me/notebook/notes-on-shipping-small-tools/</link>
      <pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://www.vedant.me/notebook/notes-on-shipping-small-tools/</guid>
      <description>How to scope a useful internal tool: one input, one outcome, explicit failures and a short path to feedback.</description>
      <content:encoded><![CDATA[<p>A small tool starts to become useful when you can finish this sentence: “Give it this input, and it will produce this result.” If the sentence needs three exceptions and a tour of the interface, the first version probably has too much in it.</p>
<p>For a CSV-checking tool, that promise might be: upload a file and get a list of rows that cannot be imported. It does not need a dashboard, accounts or a scheduling system to prove that the check helps.</p>
<h2 id="define-the-failure-output-too">Define the failure output too</h2>
<p>The successful path is usually obvious. The more important design work is deciding what happens when the file has no header, the encoding is unexpected, or the same identifier appears twice.</p>
<p>A message such as <code>Invalid file</code> sends the work back to the user. “Row 18: customer_id is empty” gives them something to fix. If the tool changes data, show the proposed change before making it and preserve enough information to undo it.</p>
<p>I like a first-version checklist with four items:</p>
<ul>
<li>One supported input format, documented with a real example.</li>
<li>One result that the user can inspect or download.</li>
<li>Errors that identify the failed input and the next step.</li>
<li>A short explanation of what the tool does not handle yet.</li>
</ul>
<h2 id="put-it-in-the-actual-workflow">Put it in the actual workflow</h2>
<p>The right interface depends on where the work already happens. A command-line script can be enough for a developer. A browser form may be the better choice for someone who would otherwise ask a developer to run the script.</p>
<p>Before adding features, watch whether the output is used. Does the person fix the flagged rows? Do they copy the result into another system? Is there a repetitive step immediately before or after it?</p>
<p>That feedback gives the next version a reason to exist. “Add authentication” is a task. “Let three colleagues use the checker without sharing files through me” is a problem you can design around.</p>
<p>The first release does not need to look unfinished. Clear labels, predictable keyboard behaviour and a readable result are part of doing the one job well.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>A dependency becomes part of the maintenance plan</title>
      <link>https://www.vedant.me/notebook/the-cost-of-a-dependency/</link>
      <pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://www.vedant.me/notebook/the-cost-of-a-dependency/</guid>
      <description>Questions to ask before adding a package, beyond whether it saves a few lines today.</description>
      <content:encoded><![CDATA[<p>A package can remove a surprising amount of work. It can also add configuration, upgrade decisions and a new source of failures. The useful comparison is between those two costs over the life of the feature.</p>
<p>Before adding one, I want to know what responsibility it will own. A mature parser can be worth far more than its installation cost because the edge cases are the real work. A package that wraps two clear standard-library calls has a different tradeoff.</p>
<h2 id="look-at-the-boundary">Look at the boundary</h2>
<p>Can the rest of the code use a small interface, or will library-specific types spread through the application? If the package needs replacing, that boundary determines whether the change touches one module or fifty.</p>
<p>Also check how it behaves in the environment where it will run. A dependency that works on a laptop may require a native library missing from the deployment image. A browser package may bring much more code than the page&rsquo;s one interaction needs.</p>
<p>Useful questions include:</p>
<ul>
<li>Does it solve the difficult part of the problem?</li>
<li>Is the licence suitable for the project?</li>
<li>Are its runtime and version requirements compatible with deployment?</li>
<li>Can we diagnose a failure inside it?</li>
<li>Is there a plausible replacement or removal path?</li>
</ul>
<h2 id="pinning-is-the-beginning">Pinning is the beginning</h2>
<p>An exact version makes a build more reproducible. It does not make the package permanently safe or remove the need to review updates. Someone still needs to understand why an upgrade is needed and what could change.</p>
<p>For this portfolio, the theme is pinned to a Git revision and Hugo has an explicit version. Site-specific templates and CSS live in the project. That arrangement makes the theme relationship visible while keeping the custom presentation inspectable.</p>
<p>A dependency earns its place when the work it reliably owns is larger than the work it creates. Counting the lines it saves today is only one part of that decision.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Read one request through an unfamiliar codebase</title>
      <link>https://www.vedant.me/notebook/reading-a-codebase-you-did-not-write/</link>
      <pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://www.vedant.me/notebook/reading-a-codebase-you-did-not-write/</guid>
      <description>A focused way to build a useful map of a repository without reading every file first.</description>
      <content:encoded><![CDATA[<p>Opening every folder is a slow way to understand a codebase. The directory tree tells you where code lives; it rarely tells you which parts matter for the behaviour you are trying to change.</p>
<p>Start with one concrete action. For an API, choose a request with a small input and an observable result. Find its route, follow the call into the service layer, and identify where it reads or writes state.</p>
<h2 id="build-a-map-of-boundaries">Build a map of boundaries</h2>
<p>Write down the entry point, validation, business decision, persistence and response. You are looking for responsibility changes rather than collecting every function name.</p>
<p>The FreightSense repository, for example, has an evaluation route that connects deterministic calculations, an LLM call and a database record. Reading that path explains more about the application than reading unrelated utilities alphabetically.</p>
<p>Next, follow one failure path. What happens if the external service times out? Does the request fail, use a fallback, or enqueue work? That path often reveals assumptions that the successful example keeps hidden.</p>
<h2 id="use-tests-and-history-selectively">Use tests and history selectively</h2>
<p>Tests near the behaviour can show the expected contract, although a test may also encode an old assumption. Configuration reveals which dependencies and feature choices change the runtime. Git history helps when a seemingly strange branch of code has a reason that the current file no longer explains.</p>
<p>Keep a short list of unresolved questions: where an identifier comes from, whether a write is transactional, or which worker owns retries. Answer the ones relevant to your change first.</p>
<p>You do not need complete understanding before making progress. You need a reliable account of the path you are touching, its neighbours, and the evidence that a change preserves the intended behaviour.</p>
<p>Example repository: <a href="https://github.com/VedantAndhale/FreightSense">FreightSense</a>.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
