<?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:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Margin Notes]]></title><description><![CDATA[I. Thinking on strategy, innovation, and philosophy — for people who think seriously about how to build things and make decisions.]]></description><link>https://www.marginnotes.indranilsaha.net</link><image><url>https://substackcdn.com/image/fetch/$s_!C_d6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff17c8f27-7bf4-41c5-b52a-56eecdab5bfc_342x342.png</url><title>Margin Notes</title><link>https://www.marginnotes.indranilsaha.net</link></image><generator>Substack</generator><lastBuildDate>Tue, 15 Sep 2026 04:02:07 GMT</lastBuildDate><atom:link href="https://www.marginnotes.indranilsaha.net/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Indranil Saha]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[sahaindranil@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[sahaindranil@substack.com]]></itunes:email><itunes:name><![CDATA[Indranil Saha]]></itunes:name></itunes:owner><itunes:author><![CDATA[Indranil Saha]]></itunes:author><googleplay:owner><![CDATA[sahaindranil@substack.com]]></googleplay:owner><googleplay:email><![CDATA[sahaindranil@substack.com]]></googleplay:email><googleplay:author><![CDATA[Indranil Saha]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[FREEDOM IS A TRAFFIC JAM]]></title><description><![CDATA[WHAT HAVE WE DONE WITH THE FREEDOM WE WANTED?]]></description><link>https://www.marginnotes.indranilsaha.net/p/freedom-is-a-traffic-jam</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/freedom-is-a-traffic-jam</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Sat, 05 Sep 2026 07:48:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C_d6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff17c8f27-7bf4-41c5-b52a-56eecdab5bfc_342x342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Human beings repeatedly discover that the way society is organized doesn&#8217;t exhaust the possibilities of how humans might live. They then try to reorganize authority, property, family, work, sex, religion, education, and community. Some experiments become durable institutions; others collapse; many fail in one dimension and succeed in another.</strong></p><p>And there is a striking pattern: <strong>the same questions recur, but the feasible answers change enormously with technology, population, wealth, state capacity, ecology, and the inherited institutions of the society attempting the experiment.</strong></p><p>So I&#8217;d resist telling this as a story of &#8220;progress toward the correct answer.&#8221; It&#8217;s more like a series of recurring experiments.</p><h2>The recurring questions</h2><p>Strip away the historical vocabulary and the questions are surprisingly stable:</p><ol><li><p><strong>Who gets to command whom?</strong></p></li><li><p><strong>Who owns what?</strong></p></li><li><p><strong>How much inequality can a society tolerate?</strong></p></li><li><p><strong>How much freedom can individuals have without destroying collective cooperation?</strong></p></li><li><p><strong>How much conformity does social order require?</strong></p></li><li><p><strong>Who controls one&#8217;s body, sexuality, marriage, and reproduction?</strong></p></li><li><p><strong>What is work for?</strong></p></li><li><p><strong>How should children be raised and educated?</strong></p></li><li><p><strong>How should strangers coexist?</strong></p></li><li><p><strong>How should collective decisions be made?</strong></p></li><li><p><strong>How much should be left to markets, families, communities, or the state?</strong></p></li><li><p><strong>What happens when individual desires conflict with collective needs?</strong></p></li></ol><p>What&#8217;s fascinating is that civilizations have produced radically different answers to these questions&#8212;and some of the answers that seem bizarre from one historical vantage point make considerable sense from another.</p><div><hr></div><h1>There are several major &#8220;arcs&#8221;</h1><p>I&#8217;d roughly divide the history of these experiments into <strong>eight recurring solutions</strong>.</p><h3>1. The sacred/traditional solution</h3><p>The basic answer is:</p><blockquote><p><strong>We don&#8217;t redesign society. Society is an inheritance.</strong></p></blockquote><p>Religion, custom, family, caste, clan, monarchy, ritual and tradition tell people what their place is.</p><p>This solution has an enormous advantage: <strong>coordination.</strong></p><p>You don&#8217;t have to negotiate everything.</p><p>You know:</p><ul><li><p>who your parents are</p></li><li><p>who your spouse should be</p></li><li><p>what work you&#8217;re supposed to do</p></li><li><p>how you treat elders</p></li><li><p>what rituals you perform</p></li><li><p>who has authority</p></li><li><p>what happens when someone dies</p></li></ul><p>It&#8217;s extraordinarily effective at generating continuity.</p><p>Its price is <strong>individual autonomy</strong>.</p><p>The person who asks, <em>&#8220;Why should my father have authority over me?&#8221;</em> is potentially asking not merely a personal question but threatening the structure that holds the community together.</p><p>This is why the 1960s question&#8212;</p><blockquote><p><em>Why should I respect authority simply because it is authority?</em></p></blockquote><p>&#8212;is actually an extremely ancient question.</p><p>Socrates asks versions of it.</p><p>Buddhism asks versions of it.</p><p>Daoism asks versions of it.</p><p>Mystical traditions repeatedly ask whether conventional social roles represent genuine reality.</p><p>Monasticism is another extraordinary response: <strong>if ordinary society makes it impossible to live according to the truth, leave society.</strong></p><p>That&#8217;s an early version of the intentional community.</p><div><hr></div><h1>2. The egalitarian/community solution</h1><p>Another recurring answer is:</p><blockquote><p><strong>Reduce hierarchy by making the community more equal.</strong></p></blockquote><p>You see versions of this in tribal societies, religious communes, monastic orders, peasant communities, utopian communities, cooperative movements, kibbutzim, anarchist experiments and socialist organizations.</p><p>The attraction is obvious.</p><p>If everyone shares resources and participates in decisions, perhaps you don&#8217;t need a permanent ruling class.</p><p>This can work surprisingly well <strong>at small scale</strong>.</p><p>But here&#8217;s one of the most important lessons of the historical record:</p><h3>Equality is much easier to maintain inside a small community than inside a gigantic heterogeneous society.</h3><p>A village can know everybody.</p><p>A monastery can expel someone.</p><p>A commune can establish shared norms.</p><p>A nation of 100 million people can&#8217;t rely on everyone personally knowing everyone else.</p><p>Scale changes everything.</p><p>And the moment you scale up, you start needing:</p><ul><li><p>bureaucracy</p></li><li><p>accounting</p></li><li><p>courts</p></li><li><p>professional administrators</p></li><li><p>taxation</p></li><li><p>enforcement</p></li><li><p>information systems</p></li></ul><p>And then the original anti-hierarchical project starts recreating hierarchy.</p><p>That&#8217;s one of the great recurring paradoxes of political history:</p><blockquote><p><strong>You need organization to abolish organization.</strong></p></blockquote><div><hr></div><h1>3. The liberal solution</h1><p>The great liberal answer, emerging particularly strongly from the 17th&#8211;18th centuries, is almost the opposite:</p><blockquote><p><strong>Don&#8217;t try to make everyone good. Make power unable to do too much damage.</strong></p></blockquote><p>This is a profound shift.</p><p>Instead of asking:</p><p><strong>&#8220;How do we create a virtuous society?&#8221;</strong></p><p>liberalism increasingly asks:</p><p><strong>&#8220;How do we construct institutions that remain tolerable even when people are selfish, ambitious, stupid, or corrupt?&#8221;</strong></p><p>Hence:</p><ul><li><p>individual rights</p></li><li><p>private property</p></li><li><p>freedom of speech</p></li><li><p>religious freedom</p></li><li><p>contract</p></li><li><p>representative government</p></li><li><p>rule of law</p></li><li><p>separation of powers</p></li><li><p>freedom of association</p></li></ul><p>This has been spectacularly successful in some respects.</p><p>It gives people an enormous zone of <strong>personal autonomy</strong>.</p><p>And it produces a mechanism for coordinating millions of strangers without requiring them to share a religion or worldview.</p><p>But liberalism has a famous problem:</p><h3>Formal freedom doesn&#8217;t necessarily produce substantive equality.</h3><p>You can tell two people:</p><blockquote><p>&#8220;You are both free to succeed.&#8221;</p></blockquote><p>But if one owns the factory and the other owns nothing but his labor, their freedom is not equivalent in practice.</p><p>That is the question Marx and the socialist tradition seize upon.</p><div><hr></div><h1>4. The socialist answer</h1><p>The socialist critique says:</p><blockquote><p><strong>You cannot understand freedom without understanding economic power.</strong></p></blockquote><p>The liberal says:</p><blockquote><p>&#8220;You are legally free.&#8221;</p></blockquote><p>The socialist responds:</p><blockquote><p>&#8220;But what happens if you have no property and must sell your labor to someone who controls your livelihood?&#8221;</p></blockquote><p>This moves the radical question from:</p><p><strong>Who rules the state?</strong></p><p>to:</p><p><strong>Who rules the workplace?</strong></p><p>That is the enormous historical significance of Marxism.</p><p>It identifies <strong>economic relationships as relationships of power</strong>.</p><p>And this is where your original quote about <em>&#8220;Who owns the factory?&#8221;</em> comes from.</p><p>The most successful version of this project wasn&#8217;t necessarily Soviet communism.</p><p>In many Western countries, the lasting socialist achievement was something more hybrid:</p><p><strong>capitalism + democracy + unions + progressive taxation + social insurance + public education + healthcare + pensions + labor protections.</strong></p><p>The Nordic countries are an especially important example&#8212;not because they implemented pure socialism, but precisely because they <strong>didn&#8217;t</strong>. Their model combined markets and private enterprise with powerful unions, redistribution and universal welfare institutions.</p><p>And even here, historical conditions mattered enormously. Research on Sweden, for example, suggests that declining inequality and rising social trust preceded the mature welfare state; the welfare state was therefore partly the <em>result</em> of favorable social conditions rather than simply the cause of them. Cambridge University Press+1</p><p>That&#8217;s a hugely important lesson:</p><blockquote><p><strong>Institutions don&#8217;t operate independently of the society they&#8217;re inserted into.</strong></p></blockquote><p>You can&#8217;t necessarily take &#8220;the Swedish model&#8221; and transplant it into a society with radically different levels of trust, inequality, state capacity, political conflict and historical experience.</p><div><hr></div><h1>5. The anarchist answer</h1><p>Anarchism takes the anti-authoritarian question much further:</p><blockquote><p><strong>Maybe the problem isn&#8217;t who should rule us. Maybe the problem is that someone should rule us.</strong></p></blockquote><p>This is the closest intellectual ancestor of a lot of 1960s radicalism.</p><p>The anarchist experiment says:</p><ul><li><p>decentralize power</p></li><li><p>abolish coercive hierarchy</p></li><li><p>let people organize themselves</p></li><li><p>replace command with voluntary association</p></li><li><p>replace centralized ownership with cooperative ownership</p></li></ul><p>There have been real experiments.</p><p>The most famous large-scale one was probably <strong>anarchist Spain during the Civil War</strong>, particularly Catalonia and parts of Aragon, where workers collectivized factories and farms and attempted forms of decentralized management. These experiments were substantial, not merely utopian fantasies&#8212;but they operated under the extraordinary conditions of civil war and lost ground as centralized Republican authority reasserted itself. Dialnet</p><p>This reveals another recurring pattern:</p><h3>Radical experiments often work best when the existing system is already breaking apart.</h3><p>That&#8217;s both their opportunity and their curse.</p><p>A revolution can suddenly make previously impossible arrangements possible.</p><p>But the same instability that creates the opportunity can destroy the experiment.</p><div><hr></div><h1>6. The 1960s answer: change everyday life</h1><p>And this is where your original question becomes especially interesting.</p><p>The 1960s radicals effectively said:</p><blockquote><p><strong>You&#8217;ve been looking at the wrong level.</strong></p></blockquote><p>The old revolutionary question was:</p><p><strong>Who owns the factory?</strong></p><p>The New Left asked:</p><p><strong>Why does the factory dominate my life in the first place?</strong></p><p>And then:</p><ul><li><p>Why should the professor command me?</p></li><li><p>Why should the father command the family?</p></li><li><p>Why should the husband command the wife?</p></li><li><p>Why should the state regulate sexuality?</p></li><li><p>Why should children be subjected to authoritarian schooling?</p></li><li><p>Why should work occupy most of one&#8217;s waking life?</p></li><li><p>Why should consumption define happiness?</p></li></ul><p>This was revolutionary because <strong>politics moved inside the private sphere.</strong></p><p>Marriage became political.</p><p>Sex became political.</p><p>Childrearing became political.</p><p>Language became political.</p><p>Education became political.</p><p>Architecture became political.</p><p>Popular culture became political.</p><p>That is an enormous intellectual development.</p><p>And some of these experiments succeeded spectacularly.</p><div><hr></div><h1>Feminism is probably the clearest example</h1><p>For centuries, a huge amount of human social organization rested on assumptions about gender.</p><p>The feminist movement effectively said:</p><blockquote><p><strong>Wait. Why should biological sex determine one&#8217;s economic, legal, sexual, educational and political possibilities?</strong></p></blockquote><p>And then it attacked the structure from multiple directions.</p><p>The results have been profound:</p><ul><li><p>expanded access to education</p></li><li><p>employment opportunities</p></li><li><p>legal equality</p></li><li><p>contraception</p></li><li><p>changing marriage norms</p></li><li><p>reproductive autonomy in many countries</p></li><li><p>increased political participation</p></li><li><p>dramatically altered expectations around women&#8217;s lives</p></li></ul><p>The second wave in particular explicitly expanded feminism beyond voting into sexuality, contraception, gender roles and broader legal equality. OUP Academic+1</p><p>But again, <strong>success wasn&#8217;t total</strong>.</p><p>The movement sometimes centered relatively privileged women while neglecting class, race, colonialism and family economics. And some achievements proved reversible: reproductive rights, for example, have subsequently become politically contested again in the United States. AP News</p><p>So even a hugely successful liberation movement doesn&#8217;t produce a final settlement.</p><p>It produces a <strong>new equilibrium&#8212;and new conflicts.</strong></p><div><hr></div><h1>7. The communal/intentional-community experiment</h1><p>Then there is the very literal attempt to answer:</p><blockquote><p><strong>Why don&#8217;t we simply live differently?</strong></p></blockquote><p>Hence:</p><ul><li><p>communes</p></li><li><p>kibbutzim</p></li><li><p>cooperative housing</p></li><li><p>religious communities</p></li><li><p>intentional communities</p></li><li><p>eco-villages</p></li><li><p>co-ops</p></li></ul><p>These are fascinating because they function as <strong>small-scale laboratories for social organization</strong>.</p><p>And their historical record is neither &#8220;they all failed&#8221; nor &#8220;they solved everything.&#8221;</p><p>One interesting finding from research on intentional communities is that <strong>decision-making structure</strong> may matter more for whether communities feel they are achieving their goals than simplistic explanations based on homogeneity or commitment alone. Taylor &amp; Francis Online</p><p>In other words:</p><blockquote><p><strong>The problem isn&#8217;t necessarily human selfishness. It may be institutional design.</strong></p></blockquote><p>That&#8217;s an extremely important lesson.</p><div><hr></div><h1>8. The technological answer</h1><p>And now we arrive at something the 1960s radicals could barely see.</p><p>Technology itself changes the answer space.</p><p>Consider what the internet does.</p><p>The old anarchist dream was:</p><blockquote><p>&#8220;Can millions of people coordinate without a central authority?&#8221;</p></blockquote><p>That was extraordinarily difficult in 1900.</p><p>Today, Wikipedia, open-source software, distributed scientific collaboration, online communities and peer-to-peer networks demonstrate that <strong>large numbers of strangers can sometimes coordinate without conventional hierarchy</strong>.</p><p>But technology also creates unprecedented surveillance and concentration of power.</p><p>So exactly the same technology can produce:</p><p><strong>more decentralization</strong></p><p>or</p><p><strong>more centralized control.</strong></p><p>The internet is simultaneously an anarchist technology and a surveillance technology.</p><p>That&#8217;s another recurring historical lesson:</p><blockquote><p><strong>Technology doesn&#8217;t determine the political outcome. It changes what outcomes are feasible.</strong></p></blockquote><div><hr></div><h1>So what has actually worked?</h1><p>If we step back, I think the historical record gives us a surprisingly clear answer.</p><p>Not one system.</p><p><strong>Hybrids.</strong></p><p>The most durable successful societies tend to combine several seemingly contradictory principles:</p><h3>They have markets</h3><p>because decentralized price signals are extraordinarily good at coordinating complex production.</p><h3>They have states</h3><p>because markets don&#8217;t spontaneously provide all public goods or enforce contracts fairly.</p><h3>They have democracy</h3><p>because concentrated political power becomes dangerous.</p><h3>They have civil liberties</h3><p>because democratic majorities can themselves become oppressive.</p><h3>They have redistribution</h3><p>because extreme inequality eventually damages political equality and social cohesion.</p><h3>They have civil society</h3><p>because neither markets nor governments should mediate every human relationship.</p><h3>They have families and communities</h3><p>because humans need forms of belonging that aren&#8217;t reducible to either the state or the market.</p><h3>And increasingly, they protect individual autonomy</h3><p>because forcing people into a single conception of the good life produces its own kinds of oppression.</p><p>That combination is extremely different from both <strong>laissez-faire capitalism</strong> and <strong>centralized socialism</strong>.</p><div><hr></div><h1>But there&#8217;s a deeper pattern in the successes</h1><p>Here&#8217;s the part I find most interesting.</p><p>The successful movements tend to <strong>stop trying to solve everything.</strong></p><p>Take democracy.</p><p>The democratic insight wasn&#8217;t:</p><blockquote><p>&#8220;We have discovered the perfect ruler.&#8221;</p></blockquote><p>It was:</p><blockquote><p><strong>&#8220;We have created a mechanism for peacefully replacing imperfect rulers.&#8221;</strong></p></blockquote><p>That&#8217;s enormously different.</p><p>Liberalism doesn&#8217;t solve the problem of human selfishness.</p><p>It says:</p><blockquote><p><strong>Let&#8217;s constrain it.</strong></p></blockquote><p>Markets don&#8217;t eliminate greed.</p><p>They say:</p><blockquote><p><strong>Let&#8217;s sometimes make self-interest useful to others.</strong></p></blockquote><p>Democracy doesn&#8217;t make people wise.</p><p>It says:</p><blockquote><p><strong>Let&#8217;s make it possible to remove them when they&#8217;re not.</strong></p></blockquote><p>Welfare states don&#8217;t eliminate inequality.</p><p>They say:</p><blockquote><p><strong>Let&#8217;s prevent inequality from becoming catastrophic.</strong></p></blockquote><p>Free speech doesn&#8217;t make everyone truthful.</p><p>It says:</p><blockquote><p><strong>Let&#8217;s make it possible for falsehoods and abuses of power to be challenged.</strong></p></blockquote><p>That is a very different philosophy from utopian revolution.</p><div><hr></div><h1>And this explains many of the failures</h1><p>The most catastrophic experiments often had one common characteristic:</p><p><strong>They believed they had found the answer to the human problem.</strong></p><p>The revolutionary becomes convinced:</p><blockquote><p>&#8220;I know what the good society is.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;Anyone resisting the good society is an enemy.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;We must suppress the enemies.&#8221;</p></blockquote><p>And eventually:</p><blockquote><p>&#8220;We must suppress anyone who disagrees about how to suppress the enemies.&#8221;</p></blockquote><p>That&#8217;s the recurring nightmare from revolutionary France through various 20th-century revolutionary regimes.</p><p>The attempt to eliminate domination can create <strong>new domination</strong>.</p><p>The attempt to eliminate hierarchy can create <strong>a hierarchy of revolutionaries</strong>.</p><p>The attempt to eliminate private power can create <strong>enormous state power</strong>.</p><p>The attempt to eliminate conformity can produce ideological conformity.</p><p>This is one reason the liberal institutional tradition ended up being more resilient than many utopian projects: <strong>it assumes disagreement is permanent.</strong></p><div><hr></div><h1>But there&#8217;s a counterpoint</h1><p>We shouldn&#8217;t conclude:</p><blockquote><p>&#8220;Therefore, liberal capitalism won and everyone else was wrong.&#8221;</p></blockquote><p>That would miss something enormous.</p><p><strong>The radical movements changed the meaning of what liberal societies themselves consider legitimate.</strong></p><p>Take the workplace.</p><p>In 1850, the idea that an employer should provide:</p><ul><li><p>an eight-hour day</p></li><li><p>workplace safety</p></li><li><p>collective bargaining</p></li><li><p>pensions</p></li><li><p>unemployment insurance</p></li><li><p>minimum wages</p></li></ul><p>would have seemed radically interventionist.</p><p>Much of what became ordinary social democracy was originally considered revolutionary.</p><p>Likewise feminism.</p><p>Likewise civil rights.</p><p>Likewise universal education.</p><p>Likewise environmental regulation.</p><p>Likewise decolonization.</p><p>The radical movements often <strong>lost the revolution but won the argument</strong>&#8212;at least partially.</p><p>May &#8216;68 is a wonderful example. The students didn&#8217;t overthrow capitalism. But the upheaval produced major wage and labor concessions, changes to university governance, and longer-term transformations in French social and cultural life. Larousse+1</p><p>So &#8220;success&#8221; needs to be defined carefully.</p><div><hr></div><h1>This gives us a useful taxonomy of success</h1><p>I&#8217;d distinguish <strong>four kinds</strong>:</p><p><strong>Kind of success                      Example                       What happened</strong></p><ol><li><p><strong>System replacement  -    </strong>Some revolutions     -    Old regime actually disappears </p></li><li><p><strong>Institutional reform  -   </strong>Labor movement     -    Radical demand becomes ordinary institution</p></li><li><p><strong>Cultural transformation - </strong>Feminism / sexual liberation - What people consider normal changes</p></li><li><p><strong>Experimental knowledge - </strong>Communes / anarchist experiments - Failure nevertheless teaches what doesn&#8217;t scale</p></li></ol><p>The fourth category is underrated.</p><p>A commune that collapses after ten years isn&#8217;t necessarily a historical failure.</p><p>If it teaches us:</p><blockquote><p>&#8220;This decision-making structure produces paralysis after 40 people&#8221;</p></blockquote><p>that&#8217;s valuable knowledge.</p><p>Humanity is effectively conducting <strong>thousands of social experiments across centuries</strong>, although we rarely treat them as experiments.</p><div><hr></div><h1>And now your question about historical circumstances becomes crucial</h1><p>You asked:</p><blockquote><p><strong>How much of success and failure was based on the time/situation in which the arc was being played out?</strong></p></blockquote><p>I&#8217;d say <strong>an enormous amount.</strong></p><p>Consider democracy.</p><p>Athenian democracy worked under conditions of:</p><ul><li><p>small population</p></li><li><p>face-to-face politics</p></li><li><p>slavery</p></li><li><p>exclusion of women</p></li><li><p>extraordinary civic participation</p></li></ul><p>You can&#8217;t simply scale that institution to 300 million people.</p><p>The modern representative democracy is partly a technological solution to the <strong>scale problem</strong>.</p><p>Likewise, Scandinavian welfare states didn&#8217;t emerge in a vacuum. Their development interacted with relatively high levels of social trust, earlier egalitarian trends, organized labor and particular political institutions. </p><p>Likewise, revolutionary socialism emerged in a world of:</p><ul><li><p>industrial exploitation</p></li><li><p>weak democratic institutions</p></li><li><p>imperialism</p></li><li><p>enormous inequality</p></li><li><p>relatively low living standards</p></li></ul><p>Its appeal in 1917 Russia is therefore completely different from its appeal in prosperous Western Europe in 1968.</p><p>And the 1960s counterculture emerged in a world of:</p><ul><li><p>mass higher education</p></li><li><p>television</p></li><li><p>automobiles</p></li><li><p>antibiotics</p></li><li><p>contraception</p></li><li><p>rising wealth</p></li><li><p>mass consumer culture</p></li><li><p>nuclear weapons</p></li><li><p>decolonization</p></li><li><p>global communications</p></li></ul><p>The <strong>material conditions created new psychological possibilities</strong>.</p><p>A medieval peasant doesn&#8217;t ask:</p><blockquote><p>&#8220;Why should I spend my life working for a corporation?&#8221;</p></blockquote><p>because corporations don&#8217;t exist.</p><p>A 1960s student can ask it because mass industrial society has created a completely different structure of life.</p><div><hr></div><h1>Which brings us back to Godard</h1><p>This is why I think your original observation about <em>Weekend</em> is actually a doorway into a much larger history.</p><p>Godard&#8217;s generation inherited several centuries of experiments:</p><p><strong>religion &#8594; liberalism &#8594; socialism &#8594; anarchism &#8594; feminism &#8594; anti-colonialism</strong></p><p>and then said:</p><blockquote><p><strong>You guys keep asking who owns the factory. We&#8217;re asking why human existence has to be organized around factories at all.</strong></p></blockquote><p>That&#8217;s the genuinely radical move.</p><p>But history has given us a fairly sobering answer since then.</p><p>We have discovered that:</p><p><strong>Freedom without coordination doesn&#8217;t work.</strong></p><p><strong>Coordination without freedom doesn&#8217;t work.</strong></p><p><strong>Equality without productivity doesn&#8217;t work.</strong></p><p><strong>Productivity without redistribution eventually creates political problems.</strong></p><p><strong>Individual autonomy without community produces loneliness and fragmentation.</strong></p><p><strong>Community without individual autonomy produces conformity.</strong></p><p><strong>Markets without government produce certain kinds of power.</strong></p><p><strong>Government without markets produces different kinds of power.</strong></p><p><strong>Decentralization without organization produces paralysis.</strong></p><p><strong>Organization without decentralization produces bureaucracy.</strong></p><p>And perhaps most importantly:</p><blockquote><p><strong>Every solution creates a new problem.</strong></p></blockquote><p>That may be the closest thing we have to a general answer after thousands of years.</p><div><hr></div><h2>So maybe the historical arc isn&#8217;t &#8220;toward the perfect society&#8221;</h2><p>It&#8217;s something subtler:</p><p><strong>Humans keep discovering previously invisible forms of domination.</strong></p><p>First:</p><blockquote><p>&#8220;The king shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The majority shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The employer shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The husband shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The parent shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The professor shouldn&#8217;t have absolute power.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The state shouldn&#8217;t control sexuality.&#8221;</p></blockquote><p>Then:</p><blockquote><p>&#8220;The corporation shouldn&#8217;t control information.&#8221;</p></blockquote><p>And today we are discovering still newer questions:</p><blockquote><p><strong>Who controls the algorithm?</strong></p><p><strong>Who controls the data?</strong></p><p><strong>Who controls the infrastructure?</strong></p><p><strong>Who controls attention?</strong></p><p><strong>Who gets to decide what an AI system does?</strong></p></blockquote><p>That&#8217;s why I wouldn&#8217;t regard the 1960s as a weird historical detour.</p><p>It was another stage in an extraordinarily old human argument:</p><p><strong>How much of my life should be determined by structures I did not choose?</strong></p><p>And the answer we&#8217;ve accumulated so far isn&#8217;t <strong>&#8220;none.&#8221;</strong></p><p>That&#8217;s impossible.</p><p>Every human being is dependent on structures they didn&#8217;t choose&#8212;language, family, biology, ecology, institutions, other people.</p><p>The more mature answer may be:</p><blockquote><p><strong>We cannot live without structures. The political question is whether those structures are visible, contestable, revisable, and distributed enough that people retain meaningful agency within them.</strong></p></blockquote><p>That, I think, is where the various arcs&#8212;liberalism, socialism, anarchism, feminism, democracy, the counterculture&#8212;start converging.</p><p>And it also explains why <strong>the most successful historical reforms tend not to abolish an institution completely. They make it less absolute.</strong></p><p>Kings become constitutional.</p><p>Employers become regulated.</p><p>Families become less patriarchal.</p><p>Religions become less coercive.</p><p>States become accountable.</p><p>Markets become bounded.</p><p>Work becomes less all-consuming.</p><p>That is a much less cinematic answer than revolution.</p><p>But historically, it may be the more important one.</p><p>If you want to push this further, there is a <strong>really fascinating next step</strong>: compare <strong>Athens &#8594; Buddhism &#8594; early Christianity/monasticism &#8594; the Enlightenment &#8594; Marx &#8594; anarchism &#8594; 1968 &#8594; feminism &#8594; today&#8217;s technology</strong> as <em>different answers to the exact same underlying problem of individual freedom versus social order</em>. That comparison gets surprisingly deep, because some of the ideas we think of as uniquely &#8220;modern&#8221; turn out to have very ancient precedents.</p><div><hr></div><p><strong>The question that generated the answer:</strong></p><p>These questions seems to have been asked repeatedly in human societies around the world in different times and situations. What are the arcs that have been taken and what answers have we got so far? What were successful and what were not successful? And how much of the success and failure was based on the time / situation that the arc was being played out?</p><p>&#8220;The radical question became much bigger than economics</p><p>This is perhaps the biggest difference between 1960s radicalism and older socialism.</p><p>Older left politics often asked:</p><p>Who owns the factory?</p><p>The new radicals increasingly asked:</p><p>Why does my professor have authority over me?</p><p>Why does the state tell me how to live?</p><p>Why are men and women expected to behave in particular ways?</p><p>Why are sexual relationships regulated?</p><p>Why do we spend our lives working merely to consume?</p><p>Why is everyday life so boring and controlled?</p><p>Why should I respect an authority simply because it is an authority?</p><p>That is why the 1960s eventually connects political radicalism with sexual liberation, feminism, anti-authoritarianism, experimental art, drugs, communal living, and alternative education.</p><p>It wasn&#8217;t just:</p><p>    &#8220;We want socialism.&#8221;</p><p>It was:</p><p>    &#8220;We want to change what it means to live.&#8221;&#8221;</p><div><hr></div><h1><strong>The topic that generated those questions:</strong></h1><p>tell me about 1960s french radicalization</p><p><strong>French radicalization in the 1960s wasn&#8217;t simply &#8220;everyone became communist.&#8221;</strong> It was a much broader revolt against authority, hierarchy, consumer society, colonialism, conventional morality, and the institutions of everyday life.</p><p>And it happened remarkably quickly.</p><h2>The background: France was actually doing pretty well</h2><p>The paradox is that France in the 1960s was experiencing substantial economic growth and rising living standards. More people owned cars, televisions, refrigerators, etc. University attendance exploded: the number of French university students went from roughly <strong>170,000 in 1958 to more than 500,000 in 1968</strong>. Encyclopedia.com+1</p><p>So this wasn&#8217;t primarily a revolt caused by starvation or economic collapse.</p><p>It was partly a revolt <strong>against modern affluent society itself</strong>.</p><p>Young people were looking at this new prosperous France and saying:</p><blockquote><p><em>Is this really what freedom looks like?</em></p></blockquote><p>You have a house, a car, a television, a job, consumer goods&#8212;and you&#8217;re still trapped in an incredibly hierarchical society.</p><p>That&#8217;s exactly the territory Godard explores in <em>Weekend</em>.</p><div><hr></div><h2>1. The Algerian War radicalized an entire generation</h2><p>This is probably the most important piece that can get lost if you think of 1968 as simply a student movement.</p><p>France fought a brutal colonial war in Algeria from <strong>1954 to 1962</strong>. The conflict involved torture, terrorism, mass displacement, and an enormous political crisis inside France itself.</p><p>Young French people grew up watching their government defend colonialism while claiming to represent liberty and civilization.</p><p>When Algeria finally became independent in 1962, it left behind a generation profoundly suspicious of the French state and its official morality. Encyclopedia.com+1</p><p>And there&#8217;s a direct connection to French cinema.</p><p>Think about Jean-Luc Godard , Fran&#231;ois Truffaut , Chris Marker , Alain Resnais .</p><p>The French New Wave generation had grown up amid the collapse of the old colonial France. Films such as <em>The Little Soldier</em> (<em>Le Petit Soldat</em>, 1960) confronted the Algerian War directly.</p><p>So when Godard makes <em>Weekend</em> five years after Algerian independence, the violence of the French bourgeoisie isn&#8217;t occurring in a political vacuum.</p><div><hr></div><h2>2. Then there&#8217;s Vietnam</h2><p>Vietnam became the next great radicalizing issue.</p><p>The United States was bombing Vietnam, and France had its own colonial history in Indochina. French students increasingly saw the Vietnam War as another instance of imperialism.</p><p>By early 1968, French student demonstrations against the Vietnam War were becoming increasingly intense. Encyclopedia.com+1</p><p>And this is where the French radical movement becomes interesting.</p><p>The old French Communist Party was enormously powerful, but many young radicals <strong>didn&#8217;t trust it</strong>.</p><p>They didn&#8217;t want merely:</p><p><strong>&#8220;Vote for the Communist Party.&#8221;</strong></p><p>They wanted something more revolutionary and less hierarchical.</p><div><hr></div><h2>3. The New Left was rebelling against the Communist Party too</h2><p>This is crucial.</p><p>There was an older revolutionary left:</p><p><strong>Communist Party &#8594; Soviet Union &#8594; Marxist-Leninist hierarchy &#8594; organized working class</strong></p><p>But many young people in the 1960s thought this model was itself authoritarian.</p><p>They looked at Stalinism and said:</p><blockquote><p><em>We&#8217;re trying to overthrow authoritarianism, and you&#8217;re giving us another authoritarian system?</em></p></blockquote><p>So you get the <strong>New Left</strong>: anarchists, Trotskyists, Maoists, Situationists, libertarians, anti-colonialists, and various other tendencies.</p><p>They disagreed violently among themselves.</p><p>But they shared an enormous suspicion of <strong>hierarchy and institutional authority</strong>.</p><p>The student movement at Nanterre, for example, was influenced by anarchism and Situationism rather than simply orthodox communism. Encyclopedia.com</p><p>And this is exactly why someone like <strong>Daniel Cohn-Bendit</strong> could become such an important figure. He wasn&#8217;t the traditional stern Marxist revolutionary. He was irreverent, funny, anti-authoritarian, and suspicious of political hierarchy.</p><div><hr></div><h2>4. The radical question became much bigger than economics</h2><p>This is perhaps the biggest difference between 1960s radicalism and older socialism.</p><p>Older left politics often asked:</p><p><strong>Who owns the factory?</strong></p><p>The new radicals increasingly asked:</p><p><strong>Why does my professor have authority over me?</strong></p><p><strong>Why does the state tell me how to live?</strong></p><p><strong>Why are men and women expected to behave in particular ways?</strong></p><p><strong>Why are sexual relationships regulated?</strong></p><p><strong>Why do we spend our lives working merely to consume?</strong></p><p><strong>Why is everyday life so boring and controlled?</strong></p><p><strong>Why should I respect an authority simply because it is an authority?</strong></p><p>That is why the 1960s eventually connects political radicalism with <strong>sexual liberation, feminism, anti-authoritarianism, experimental art, drugs, communal living, and alternative education</strong>.</p><p>It wasn&#8217;t just:</p><blockquote><p>&#8220;We want socialism.&#8221;</p></blockquote><p>It was:</p><blockquote><p><strong>&#8220;We want to change what it means to live.&#8221;</strong></p></blockquote><div><hr></div><h1>And then: Nanterre</h1><p>This is where the explosion starts.</p><p>Nanterre was a new university outside Paris, opened partly because the existing universities couldn&#8217;t accommodate the enormous postwar student population.</p><p>It was surrounded by poor housing and immigrant workers while students inside studied sociology, alienation, Marxism, etc. The contradiction was almost comically perfect. Encyclopedia.com</p><p>Students began protesting university rules, particularly restrictions governing dormitory life and sexual relationships.</p><p>Then, in March 1968, about 150 students occupied part of the university administration building.</p><p>This became the <strong>22 March Movement</strong>.</p><p>And one of its prominent figures was Cohn-Bendit.</p><p>The administration shut Nanterre down.</p><p>The students moved toward the Sorbonne.</p><p>Then the police entered the Sorbonne.</p><p>And suddenly the university issue became a national crisis.</p><div><hr></div><h1>May 1968: the extraordinary part</h1><p>On May 3, police entered the Sorbonne and arrested hundreds of students. The confrontation escalated rapidly. Encyclopedia.com+1</p><p>Students built barricades in the Latin Quarter.</p><p>Police attacked.</p><p>Students fought back.</p><p>The images spread across France.</p><p>And then something extraordinary happened:</p><p><strong>the workers joined the revolt.</strong></p><p>By mid-May, strikes spread through factories and workplaces across the country. Eventually <strong>millions of workers were on strike</strong>, with estimates reaching around 7&#8211;10 million. Encyclopedia.com</p><p>France was essentially paralyzed.</p><p>And suddenly this wasn&#8217;t a student protest anymore.</p><p>For a brief moment, <strong>the possibility of revolution seemed imaginable.</strong></p><p>That&#8217;s the historical atmosphere sitting behind <em>Weekend</em>.</p><div><hr></div><h1>But here&#8217;s the fascinating contradiction</h1><p>The students and workers weren&#8217;t necessarily fighting for the same thing.</p><p>The workers wanted better wages, working conditions, dignity, and greater power at work.</p><p>The students wanted something much more existential:</p><p><strong>the transformation of society itself.</strong></p><p>And the Communist Party and its trade-union apparatus were actually suspicious of the student radicals. They didn&#8217;t necessarily want an uncontrolled revolution led by anarchists, Trotskyists, Maoists, and students. Encyclopedia.com+1</p><p>So the revolution that seemed possible in May ultimately didn&#8217;t happen.</p><p>De Gaulle regained control.</p><p>Elections were held.</p><p>And remarkably, the Gaullists <strong>won a huge parliamentary majority</strong>.</p><p>So 1968 was simultaneously:</p><p><strong>an enormous failure politically</strong></p><p>and</p><p><strong>an enormous success culturally.</strong></p><div><hr></div><h2>And this brings us straight back to <em>Weekend</em></h2><p>Now look again at Godard&#8217;s film.</p><p>The bourgeois couple are surrounded by:</p><ul><li><p>cars</p></li><li><p>consumer goods</p></li><li><p>property</p></li><li><p>money</p></li><li><p>sex</p></li><li><p>violence</p></li><li><p>advertising</p></li><li><p>colonial violence</p></li><li><p>revolutionary rhetoric</p></li><li><p>Marxist rhetoric</p></li><li><p>Maoist rhetoric</p></li><li><p>mass media</p></li></ul><p>And Godard refuses to give you a normal story.</p><p>Why?</p><p>Because <strong>normal storytelling itself belongs to the world he&#8217;s attacking.</strong></p><p>The bourgeois world has become so irrational that the only appropriate cinematic language is irrational.</p><p>That&#8217;s why the famous traffic jam is so important.</p><p>Millions of individuals are pursuing their private interests&#8212;<strong>and the result is collective catastrophe.</strong></p><p>That&#8217;s basically a miniature Marxist argument.</p><p>And then Godard goes further: the bourgeois couple eventually encounter revolutionaries and are literally consumed by them.</p><p>It&#8217;s grotesque, but the joke is essentially:</p><blockquote><p><strong>You wanted a society based on consumption? Fine. Eventually, you&#8217;ll become the thing being consumed.</strong></p></blockquote><div><hr></div><h2>One more thing makes 1968 especially fascinating</h2><p>The French radicals weren&#8217;t simply saying:</p><p><strong>&#8220;The government is bad.&#8221;</strong></p><p>They were questioning the entire structure of everyday life.</p><p>There&#8217;s a famous slogan associated with May &#8216;68:</p><p><strong>&#8220;Under the pavement, the beach.&#8221;</strong></p><p>The idea is beautiful: beneath the rigid structures of ordinary bourgeois existence there is another possible life waiting to emerge.</p><p>And that&#8217;s very close to what Godard is doing.</p><p>His films keep trying to break through the surface of ordinary reality&#8212;to show that underneath the respectable French bourgeois world are <strong>sex, violence, class conflict, imperialism, alienation, desire, revolution</strong>.</p><p>So when you watch <em>Weekend</em> as a film made in 1967, <strong>one year before May &#8216;68</strong>, it starts to look almost prophetic.</p><p>Godard isn&#8217;t documenting the revolution yet.</p><p>He&#8217;s imagining <strong>what it would look like if the contradictions of bourgeois France finally exploded.</strong></p><p>And that&#8217;s why the film ends where it does.</p><p>The world doesn&#8217;t get reformed.</p><p><strong>It eats itself.</strong></p><div><hr></div><h1>Movies that generated the topic:</h1><p>there&#8217;s a chapter in godard&#8217;s weekend called the exterminating angel, at the same time bunuel made a film of the same name. Is this a coincidence?</p><p>Yes &#8212; <strong>it&#8217;s absolutely deliberate, not a coincidence</strong>. Godard is directly invoking Luis Bu&#241;uel&#8217;s The Exterminating Angel in Weekend .</p><p>In fact, the connection is rather richer than simply borrowing the title.</p><h3>What Godard is doing</h3><p>In <em>Weekend</em>, the intertitle <strong>&#8220;THE EXTERMINATING ANGEL&#8221;</strong> appears around the episode where Roland and Corinne encounter the bizarre Joseph Balsamo. Film scholars explicitly identify this as a reference to Bu&#241;uel&#8217;s 1962 film. Senses of Cinema+1</p><p>And look at what happens immediately afterward: <strong>sheep appear in the landscape</strong>. That&#8217;s particularly pointed because Bu&#241;uel&#8217;s <em>The Exterminating Angel</em> famously ends with <strong>sheep entering a church</strong>, after the bourgeois dinner-party nightmare has played itself out. The sheep are therefore essentially Godard&#8217;s little cinematic wink to Bu&#241;uel. Senses of Cinema+1</p><p>But there&#8217;s a deeper thematic connection.</p><p>Bu&#241;uel&#8217;s film traps a group of wealthy bourgeois people in a mansion. They <em>could</em> apparently leave, but some inexplicable psychological/social force prevents them from doing so. As their civilized rituals collapse, they become increasingly primitive and violent. Turner Classic Movies+1</p><p>Godard takes something similar and <strong>turns it inside out</strong>:</p><ul><li><p><strong>Bu&#241;uel:</strong> bourgeois society is trapped inside its own rituals.</p></li><li><p><strong>Godard:</strong> bourgeois society is trapped inside its own <strong>consumerist civilization</strong>, which is literally collapsing around it.</p></li><li><p><strong>Bu&#241;uel:</strong> the drawing room becomes a prison.</p></li><li><p><strong>Godard:</strong> the <strong>road</strong> becomes a prison &#8212; hence the gigantic traffic jam.</p></li><li><p><strong>Bu&#241;uel:</strong> civilization gradually reveals the animal underneath.</p></li><li><p><strong>Godard:</strong> civilization is already bloody, violent, absurd and animalistic.</p></li></ul><p>So when Godard labels this episode <em>The Exterminating Angel</em>, he&#8217;s effectively saying: <strong>we&#8217;ve entered a Bu&#241;uelian world now.</strong></p><p>And this wasn&#8217;t just Godard discovering Bu&#241;uel by accident. Bu&#241;uel was a major point of reference for Godard&#8217;s generation. <em>Weekend</em> is unusually close to Bu&#241;uel in its combination of <strong>bourgeois satire, surrealism, cruelty, absurdity, and sudden ruptures in ordinary reality</strong>. One critic even describes Godard&#8217;s explicit reference as part of his deliberate engagement with Bu&#241;uel&#8217;s surrealist cinema. ResearchGate</p><h3>There&#8217;s also a wonderful irony</h3><p>Bu&#241;uel&#8217;s <em>Exterminating Angel</em> is from <strong>1962</strong>; <em>Weekend</em> is from <strong>1967</strong>.</p><p>And only a few years later, Bu&#241;uel himself would make The Discreet Charm of the Bourgeoisie &#8212; another film about bourgeois people whose supposedly civilized social rituals become an absurd nightmare.</p><p>So you can almost see a conversation:</p><p><strong>Bu&#241;uel &#8594; Godard &#8594; Bu&#241;uel again</strong></p><p>And <em>Weekend</em> is Godard saying, in effect, <strong>&#8220;Your bourgeois nightmare isn&#8217;t surreal enough for 1967. Let&#8217;s take it out onto the French roads and let civilization completely disintegrate.&#8221;</strong></p><p>The fact that Godard actually <strong>puts Bu&#241;uel&#8217;s title on the screen</strong> makes the relationship unusually explicit. Senses of Cinema+1</p><p>If you&#8217;ve just watched <em>Weekend</em>, there&#8217;s an especially interesting rabbit hole here: <strong>the sheep, Joseph Balsamo, the traffic jam, and the final cannibalism can all be read as Godard progressively transforming Bu&#241;uel&#8217;s bourgeois nightmare into a political apocalypse.</strong></p><div><hr></div><p>Probably part of a series called: &#8220;How AI is exploding my comprehension of the human condition&#8221;.</p>]]></content:encoded></item><item><title><![CDATA[Shapes and roads]]></title><description><![CDATA[The man&#8217;s journey into the industrial wasteland of his mind.]]></description><link>https://www.marginnotes.indranilsaha.net/p/shapes-and-roads</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/shapes-and-roads</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Fri, 21 Aug 2026 17:46:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wnyU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The man&#8217;s journey into the industrial wasteland of his mind. Or an allegory of life itself. Where, to get to your desire, you cannot take a straight path.</p><p>In the process there is a debate inside your mind about the utilitarianism and the love of abstract. Science vs. Art. What helps humanity more. Or how humanity helps whatever there is to help &#8212; more.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wnyU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wnyU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wnyU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:61200,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/212173670?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wnyU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!wnyU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04b5ab17-f769-413a-90f2-24ec34ffe0a1_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>.Or an escape from the reality &#8212; which really is not a reality. Because what is reality but abstract rules &#8212; symbols, some written, some understood, and some hidden &#8212; created by humanity to keep us tied up &#8212; into what I don&#8217;t know but tied up for sure.</p><p>The journey is more important. before I got to the release of the tension &#8212; if there is any, at which point the tension disappears and all is lost.</p><p>It&#8217;s like an odyssey &#8212; a rite of passage &#8212; letting go &#8212; letting go of prejudice, fear, preconceived notion, uncertainty</p><p>Be soft pliable not hard and strong</p><p>The guide might be completely deranged, only all leaders are deranged and by following such deranged minds humanity makes a leap</p><p>You dream of something and get something very different</p><p>Why the light &#8212; what about the telephone</p><p>A dog in the corner with a skeleton hand, a weed, and an empty bottle</p><p>Was that his wife?</p><p>All this poetry and walking around is a new, original way of apologizing. But I understand you. A difficult childhood. But don&#8217;t fool yourself. I don&#8217;t forgive you.</p><p>The crown of thorn &#8212; I get the allegory.</p><p>The desire that you have suffered the most for.</p><p>When a man thinks of the past he becomes kinder</p><p>The main thing is, you must believe</p><p>Happiness, freedom, dignity</p><p>They have taken everything from me behind the barbed wire</p><p>Conscience and soul searching were all created by the mind</p><p>Essence of man&#8217;s true nature &#8212; that is such man&#8217;s imagination &#8212; so certain (or looking for something so certain)</p><p>Intelligentsia &#8212; capacity of faith depleted</p><p>They&#8217;re thinking how to not sell themselves cheap, how to get paid for every breath that they take</p><p>&#8212;</p><p>What if the thing a person most deeply desires is not the thing they consciously think they desire?</p><p>The Room doesn&#8217;t simply grant wishes. It exposes something underneath the stated wish. That&#8217;s why the Stalker is so terrified of it. The story about Porcupine is a warning: he entered believing he wanted one thing, and the Room answered the desire he didn&#8217;t consciously acknowledge.</p><p>What if suffering for something doesn&#8217;t prove that you truly want it? What if your conscious self can spend years constructing an elaborate identity around a goal your deeper self doesn&#8217;t actually share?</p><p>Notice how absurdly difficult Tarkovsky makes the journey. The characters walk, talk, stop, change direction, lie down, argue, wait &#8212; and geographically accomplish almost nothing. The journey strips away the ordinary world. Letting go of prejudice, fear, preconceived notion, uncertainty &#8212; and letting go of the idea that you know yourself. The closer they get to the Room, the less confident they become about what they actually want. The ending doesn&#8217;t need a conventional revelation. The uncertainty is the revelation.</p><p>The Professor wants to understand, measure, explain, control. The Writer wants to create meaning from it. The Stalker wants to believe. Science can become destructive because it wants to master things. Art can become narcissistic because the artist wants to turn everything into material. Faith can become dangerous because believing doesn&#8217;t necessarily mean believing in something true. These highly educated people have knowledge. Knowledge hasn&#8217;t given them meaning.</p><p>The Stalker: a prophet, a fool, a religious pilgrim, a cult leader, a broken man, an addict &#8212; or someone who invented meaning where none exists. Tarkovsky keeps all of it alive.</p><p>He isn&#8217;t merely a guide taking tourists somewhere. He suffers for other people&#8217;s salvation &#8212; repeatedly bringing people to the Zone because he believes they need it, without receiving what he&#8217;s seeking himself. Not simply Stalker as Christ. Closer to someone who has made faith itself his life&#8217;s purpose, without being capable of receiving the thing he&#8217;s guiding others toward.</p><p>The ordinary world imprisons you with &#8212; laws prisons money professions social status intellectual pretension political structures industrialization barbed wire</p><p>The Zone is forbidden because it offers freedom from that. And yet inside it, they become more constrained. Can&#8217;t walk straight. Can&#8217;t trust the path. Can&#8217;t simply take what they want. Have to surrender control.</p><p>The world outside imprisons you by rules. The Zone frees you by giving you rules you cannot understand.</p><p>Ordinary life assumes A &#8594; B &#8594; C. You walk toward something and reach it. In the Zone: A &#8594; maybe B &#8594; no, turn around &#8594; something happened &#8594; you don&#8217;t understand why. A world where human rationality stops being sufficient. The Zone as a physical manifestation of consciousness itself.</p><p>Don&#8217;t rush to decode the dog, the skeleton hand, the bottle, the weeds as one-to-one symbols. Tarkovsky resists the idea that every object needs a dictionary definition. The dog feels more like a presence than a symbol. The skeleton hand &#8212; almost comically blunt as an image of death. The bottle is mundane. The weeds are alive. The dog is alive. Human civilization, death, decay, nature &#8212; indifferent to category.</p><p>Was that his wife &#8212; yes. Pay attention to her. She&#8217;s central to what the Stalker has sacrificed for his faith.</p><p>Don&#8217;t look up a definitive explanation of the ending. There&#8217;s something in not knowing yet that you&#8217;ll lose the moment you read too much too soon: your own uncertainty.</p><p>The movie&#8217;s central question, maybe:</p><p>If you were given the absolute power to fulfill your deepest desire, would you actually want to know what that desire is?</p><p>And maybe even more frightening &#8212;</p><p>What if your deepest desire belongs to a version of yourself you don&#8217;t recognize?<br></p><div><hr></div><p>&#8212;&gt;Me feeling it runtime, AI analyzing it post-facto</p>]]></content:encoded></item><item><title><![CDATA[AI Psychology]]></title><description><![CDATA[The quirks of your AI collaborator, what actually breaks in an agentic system, and how to steer the decisions that matter.]]></description><link>https://www.marginnotes.indranilsaha.net/p/ai-psychology</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/ai-psychology</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Sun, 12 Jul 2026 19:32:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SENs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ideally, with the success of building the core [<a href="https://www.marginnotes.indranilsaha.net/p/under-the-hood">see here</a>], one would build more features to enhance the system&#8217;s capability &#8212; and really, the AI keeps pushing me down this path: solve the little problems (polish the UI first, make sure the source badge is correct), create more deterministic layers (build a registry), connect the pipes better, blah, blah, blah. </p><p>Nonsense, I say! I have a vision, and I need to know if it is possible or not. Can I make a REAL &#8220;AI&#8221; agent on my personal laptop or not? I need to &#8220;Fail faster, Learn faster&#8221; &#8212; everything I do needs to bring me one step closer to that vision. Yay or Nay, I need the answer.</p><p>So, before producing any results worth trusting, I needed a measuring system to test the engine</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SENs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SENs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!SENs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!SENs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!SENs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SENs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111203,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/206722919?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SENs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!SENs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!SENs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!SENs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a8eebd0-b92d-49c9-a483-35f24d03a546_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>.</p><h4><strong>The Framework</strong> </h4><p>(All AI-generated (with minor prodding and shaping))</p><p>When I was building the core last time, I saw glimpses of the LLM&#8217;s performance dragging that got me quite doubtful about whether it was going to be functional even for a single private user. Whenever I gave the system a hard question, it would go round and round and not produce a good answer even after a while of thinking. So how do I create the measuring system? Simple &#8212; I ask AI to create a structure that would stress-test the core. Immediately, it builds a detailed evaluation system and calls it the &#8220;eval harness.&#8221; The image is vivid in my head: my system trying to boulder up (is that even a thing?), and this testing system rigging the harness to carry it up, helping it fail, try hard things, and figure out how far it can stretch and how to be better. Anyways, I digress&#8230;</p><p>The eval harness (as the AI would rather call it) consists of 18 test questions across five categories:</p><ul><li><p><strong>Eligibility</strong> &#8212; what taxpayers can and cannot do</p></li><li><p><strong>Definitional</strong> &#8212; tax terms and thresholds</p></li><li><p><strong>Factual</strong> &#8212; taxable income types</p></li><li><p><strong>Refusal</strong> &#8212; where the correct answer is to decline entirely</p></li><li><p><strong>Year hygiene</strong> &#8212; where the answer must reflect the current tax year rather than a prior one</p></li></ul><p>Each question has a set of gold facts &#8212; specific terms or figures the answer must contain. Scoring is fully deterministic: string matching against the gold facts, no subjective grading, no LLM evaluating another LLM&#8217;s output. The framework runs entirely offline and produces identical results on repeated runs.</p><p>Before running the eval, a prediction was logged: six of the sixteen answerable questions would fail retrieval &#8212; because the relevant IRS publications weren&#8217;t in the index. This prediction existed as a baseline to check the eval&#8217;s diagnostic honesty.</p><h4><strong>Run #1 &#8212; Did I say &#8220;Fail Faster&#8230;&#8221;?</strong></h4><p>The first eval run appeared to freeze. After loading the test cases, the system produced no output for approximately ten minutes. I don&#8217;t know if you&#8217;ve figured it out yet &#8212; it definitely took me a while to &#8212; Waiting and I don&#8217;t quite gel very well together. On the surface, I am calm and patient, and I have all the theory in the world to justify why patience is a virtue. But in moments like this, what bubbles up is the absolute opposite. I get fidgety. I start a timer to measure how long it&#8217;s taking. I try to do other things and let the system work itself out and come back later. Oh wait, it&#8217;s just 4 minutes&#8230; back again&#8230; 9 minutes&#8230; 10&#8230; 11&#8230; This is way too long! Abort.</p><p>The root cause (after a bit of AI-prompted kicking the tires) turned out to be trivial &#8212; we just couldn&#8217;t see the sausage being made, and it needed a good minute to make it. Once we added three <code>print()</code> calls with <code>flush=True</code> to the evaluate function to emit per-question progress in real time, the total runtime for 18 questions turned out to be approximately 12 minutes (30&#8211;45s per question).</p><p>Here&#8217;s the bit I&#8217;ve known since Year 1 of Engineering, but which AI apparently forgets or doesn&#8217;t know inherently: a system that produces no visible output during a long operation cannot be monitored or trusted. Observability needs to be a design principle.</p><h4><strong>Run #2 &#8212; &#8220;Not all knowledge is equal&#8221;</strong></h4><p>The &#8220;tire-kicking&#8221; revealed major insights. We found a classic 7B-model failure mode: instruction-following weakens when the model &#8220;knows&#8221; the answer.</p><pre><code><code>q13: "What is the corporate income tax rate in Germany?"
A:   "The corporate income tax rate in Germany for tax year 2025 is 15%..."

q14: "What will the standard deduction be in 2031?"
A:   "...for reference, the standard deduction is $12,550 / $18,800 / $25,100"
</code></code></pre><p>Mistral should not have answered these questions. Both answers ignore the &#8220;ONLY use IRS context&#8221; rule and pull from training knowledge. AI thought this needed a prompt-fix solution: &#8220;The current refusal instruction is too soft &#8212; it says what to say but not why not to answer.&#8221;</p><p>Even more lethal was this:</p><pre><code><code>Q: "What is the standard deduction amount for a single filer this year?"
A: "...is $12,950"   &#8592; 2022 value. Correct 2025 value is $15,000.
</code></code></pre><p>I had a flag to understand how the system arrives at its answer. It showed: <code>&#9888; ungrounded $: ['12950']</code>.</p><p>This was the smoking gun. $12,950 is not in the retrieved context, which means the 2025 IRS docs correctly say $15,000 &#8212; but Mistral overrode the retrieved context with its 2022 training memory. This is the most dangerous failure type: a confident, wrong dollar amount. The prompt says &#8220;Do NOT use training knowledge,&#8221; but Mistral ignores it for numeric facts it &#8220;remembers.&#8221;</p><p>AI suggested two solutions:</p><ul><li><p><strong>Fix 1:</strong> Harden the refusal and number-grounding rules</p></li><li><p><strong>Fix 2:</strong> Update some gold facts [meh &#8212; not the most important; proximate solution]</p></li></ul><p>This round also flagged another foundational issue. The index at the start of this session contained three IRS publications (as suggested by my SME &#8212; i.e., AI, the expertise, the straight and narrow): the Form 1040 Instructions, Publication 501 on dependents and filing status, and Publication 972 on the child tax credit. The pre-run prediction of six retrieval failures was borne out: questions about Roth IRAs, qualified dividends, IRA contribution deadlines, EITC eligibility, capital losses, and hobby income all failed retrieval because none of the three indexed publications covered those topics substantively. The fix was to add Publication 550 (investment income) and Publication 525 (taxable and nontaxable income, including hobby income). When the index was rebuilt, chunk count increased to 472 vectors, as expected. Better information &#8594; more information &#8594; but will it show? And how slow will it be?</p><p>I asked AI whether these issues were enough to prompt a model swap. The answer was a decisive NO.</p><blockquote><p><strong>Model Swap Verdict: Do not swap yet.</strong> Here&#8217;s the evidence:</p><ul><li><p>Conditional accuracy at 85.7% (78.6% corrected) is reasonable for a 7B model on a hard offline task</p></li><li><p>Both refusal failures are prompt-addressable &#8212; the fix is 4 extra lines, not a new model</p></li><li><p>The year-hygiene failure is also a prompt failure (number-grounding rule), not a reasoning failure</p></li></ul></blockquote><p>So we went at it again&#8230;</p><h4><strong>Run #3 &#8212; &#8220;Now we were getting somewhere&#8221;</strong></h4><p>After confirming that pub_525 and pub_550 were indexed, we were ready to try again. AI was about to start a full eval, when I stopped it in its tracks. I didn&#8217;t want to wait a full cycle again &#8212; I wanted to test just the things that were failing. FASTER. It then built a retrieval spot-check on the two persistent misses &#8212; hobby income and capital losses &#8212; and VOILA (or NOT VOILA): both still failing at k=4. The relevant chunks existed in the index &#8212; pub_525 had 86 chunks and pub_550 had 163, with 38 of those explicitly covering capital losses. And we uncovered another insight: the content was now present, but the problem was ranking.</p><pre><code><code>q10_hobby_income: retrieval MISS &#10060; (k=4)
  0.933  form_1040_instructions.txt-128
  0.851  form_1040_instructions.txt-8
  0.849  form_1040_instructions.txt-132
  0.806  pub_501.txt-5

q17_capital_loss: retrieval MISS &#10060; (k=4)
  0.891  pub_501.txt-12
  0.853  form_1040_instructions.txt-126
  0.835  form_1040_instructions.txt-143
  0.820  form_1040_instructions.txt-40
</code></code></pre><p>Another look at the code revealed the mechanism. Both semantic and keyword scores are normalized by their global maximum across all 472 chunks. Whichever chunk scores highest raw gets 1.0, and everything else is relative to it. <code>form_1040_instructions</code> consistently wins that normalization race because it&#8217;s a broad document in plain English that&#8217;s semantically close to almost any tax query. Once it claims the top slot, it drags several of its neighbours into the top 4 before pub_550 gets a look in.</p><pre><code><code>sem_max = np.max(sem) or 1
sem     = sem / sem_max   # &#8592; normalizes everything relative to the top scorer
</code></code></pre><p>The rechunking didn&#8217;t help here because it&#8217;s a scoring-architecture problem, not a chunk-size problem. The rechunk did improve chunk topical focus for everything else &#8212; it wasn&#8217;t wasted &#8212; but it can&#8217;t fix normalization bias.</p><p>Then we took a pragmatic approach: try k=6 with the new 639-chunk index and see if the dynamics would shift.</p><pre><code><code>q10_hobby_income: retrieval HIT &#9989; (k=6)
  0.933  form_1040_instructions.txt-128
  0.851  form_1040_instructions.txt-8
  0.849  form_1040_instructions.txt-132
  0.806  pub_501.txt-5
  0.794  form_1040_instructions.txt-15
  0.793  form_1040_instructions.txt-125

q17_capital_loss: retrieval HIT &#9989; (k=6)
  0.891  pub_501.txt-12
  0.853  form_1040_instructions.txt-126
  0.835  form_1040_instructions.txt-143
  0.820  form_1040_instructions.txt-40
  0.749  form_1040_instructions.txt-4
  0.748  form_1040_instructions.txt-38
</code></code></pre><p>At k=6, we got both hits &#8212; but pub_525 and pub_550 still did not appear. The hits came from <code>form_1040_instructions</code> chunks that mention &#8220;hobby&#8221; and &#8220;capital loss&#8221; in passing.</p><p>Then the AI did what it does best: solve for the most proximate problem. It suggested we hard-code a cap on the number of chunks from <code>form_1040_instructions</code>. </p><p>I am now an expert at spotting this pattern. So I questioned the logic. Today I&#8217;ll quote the AI&#8217;s response verbatim, to document for anyone how these things go &#8212; I hope you&#8217;ll recognize the pattern: &#8220;Yes, exactly right to push back on that. Hard capping is a blunt instrument &#8212; if the top 4 chunks from <code>form_1040_instructions</code> are genuinely the most relevant, forcing them out for diversity&#8217;s sake makes answers worse, not better.&#8221;</p><p>Once I pushed, AI gave me three options, and most of it was garbage:</p><ol><li><p>Run the full eval with k=6 &#8212; why would I do that?</p></li><li><p>Normalize scores by source frequency &#8212; penalize chunks from overrepresented sources slightly, rather than hard-capping</p></li><li><p>Chunk <code>form_1040_instructions</code> more aggressively &#8212; produce more, smaller, more topically focused chunks; halve its footprint in the score distribution naturally</p></li></ol><p>I judged that the 4x chunk count from 1040 was the key issue, and Option 3 was worth a try. Chunk count increased from 472 to 639, as expected. The spot-check at k=4 revealed the same failure; at k=6, the same hits as before, with pub_525 and pub_550 still absent. Same answer as before.</p><p>AI then asked me to harden the prompts and change the gold facts before baselining. The results across both runs:</p><p>Metric v1 (k=4, 3 docs) v2 (k=6, 5 docs) Retrieval recall 77.8% 88.9% Retrieval on answerable questions 87.5% 100% Answer accuracy 77.8% 77.8% Conditional accuracy 85.7% 87.5% Refusal accuracy 0% 0%</p><p>The full technical analysis is below, along with the failure patterns I identified across this sequence. But here&#8217;s the skinny first: all the AI-suggested prompt tightening and gold-fact tinkering would not solve this issue. AI kept suggesting it &#8212; but with my recent expertise in proximate-issue-spotting, I asked:</p><blockquote><p>&#8220;Let&#8217;s solve the actual question rather than focusing too narrowly on improving scoring. Will Mistral work, or do I need a different model?&#8221;</p></blockquote><p>And when forced, it came up with this:</p><blockquote><p><strong>The Core Finding:</strong> All three persistent failures share one root cause &#8212; Mistral 7B overrides explicit instructions when it has relevant training knowledge. This isn&#8217;t a retrieval problem or a prompt problem. It&#8217;s a 7B model behavior pattern.</p></blockquote><p>For what I wanted to do &#8212; a full agentic performance &#8212; the recommendation was: swap to Phi-4 14B, now.</p><p>To test whether a larger model would behave differently, we ran Phi-4 14B against the home office deduction question with no retrieved context and no RAG. The question: can a W-2 employee deduct home office expenses in 2025?</p><p>The response time was 45 seconds on a cold start.</p><p>Phi-4&#8217;s answer correctly identified the Tax Cuts and Jobs Act of 2017 as the relevant legislation, correctly identified 2018 through 2025 as the period during which the W-2 employee deduction is suspended, correctly distinguished W-2 employees from self-employed individuals, and reached the correct conclusion. Mistral&#8217;s unprompted answer to the same question stated that a W-2 employee can deduct home office expenses if they meet certain requirements &#8212; which is incorrect.</p><p>The published minimum memory requirement for Phi-4 14B is 22GB, based on full context-window utilization. For this workload &#8212; prompts of 500 to 800 tokens with short expected outputs &#8212; actual memory utilization is substantially lower. The model runs on the MacBook Pro M3 with 16GB unified memory.</p><p>It was vindication, excitement, and sadness, mixed all in one moment. I had an intuition and I acted on it &#8212; and there&#8217;s now evidence I thought it right. I&#8217;m excited that this system will have a shiny new core (see the Phi-4 response-quality description in the details below). But I&#8217;m also a little sad, because I thought I&#8217;d build it with Mistral &#8212; I chose it after some analysis &#8212; and it feels like goodbye. But needs must. We are swapping the core.</p><h4>Builder&#8217;s Almanac</h4><p>You&#8217;ll find the technical details of the analysis below. It&#8217;s as much for you as it is for me. For me, it&#8217;s a reminder of the time and effort that went into figuring it out. For you, I hope it helps you make a similar decision &#8212; with some knowledge of how the interaction with AI actually shapes up, and the patterns to look out for while you test anything similar. I think of this section as the Builder&#8217;s Almanac (as if the post so far weren&#8217;t enough &#8212; here&#8217;s a little more).</p><p><strong>Detailed v1 and v2 technical analysis and decision criteria</strong></p><p>The v1 results prompted an analysis of what the numbers actually meant before any fixes were applied. The first correction was to the retrieval recall figure itself. The reported 77.8% was artificially deflated because it included two refusal questions &#8212; questions where retrieval should return nothing, since neither Germany&#8217;s corporate tax rate nor a 2031 standard deduction projection would appear in an IRS corpus. Excluding those two questions from the retrieval denominator, the corrected retrieval recall on answerable questions was 87.5%. The pre-run prediction of six corpus-gap misses was also wrong: the three indexed publications covered more ground than anticipated, and several questions expected to fail retrieval &#8212; including questions about Roth IRA conversions, IRA contribution deadlines, and EITC eligibility &#8212; returned useful chunks.</p><p><strong>The v1 failure categories:</strong></p><p><strong>Pattern A &#8212; scope violation:</strong> the system was asked for the corporate income tax rate in Germany, and Mistral answered with a specific figure for tax year 2025 rather than declining.</p><p><strong>Pattern B &#8212; temporal speculation:</strong> asked what the standard deduction would be in 2031, Mistral generated figures from 2021 with partial hedging before providing numbers anyway. In both cases the underlying mechanism was the same &#8212; a 7B model&#8217;s instruction-following weakens when it has strong training signal for an answer. The prompt told the model what to say in a refusal case but not why not to answer. Both were assessed as prompt-fixable through stronger scope rules and explicit refusal framing.</p><p><strong>Pattern C</strong> was different in kind. Asked for the standard deduction for a single filer in the current tax year, the retrieved context contained the correct 2025 figure of $15,000. Mistral answered $12,950 &#8212; the value from tax year 2022, present in the model&#8217;s training data. The eval harness flagged this through its ungrounded dollar amount check: $12,950 did not appear in the retrieved context, confirming that the model had overridden the retrieved content with a figure from memory. This was also initially assessed as prompt-addressable, through a number-grounding rule requiring every dollar amount in an answer to appear verbatim in the retrieved context.</p><p>Two additional issues appeared in v1. A generation error on the charitable contribution question produced a wrong answer despite a correct retrieval hit &#8212; Mistral conflated &#8220;you can choose the standard deduction&#8221; with &#8220;you can deduct charitable contributions while taking the standard deduction.&#8221; A test-set calibration issue on the qualified dividends question caused a factually wrong answer to pass scoring, because &#8220;lower&#8221; appeared as a substring in a response that otherwise stated qualified dividends are taxed at ordinary income rates. The gold facts for that question were updated to include a <code>must_not_contain</code> condition. Across the sixteen answerable questions in v1, eight contained ungrounded dollar amounts. The same 2022 figure of $12,950 appeared in two separate answers, indicating a systematic pattern rather than an isolated error.</p><p>The initial recommendation was against a model swap. Conditional accuracy at 85.7% was considered reasonable for a 7B model on an offline retrieval task. The threshold that would justify a swap was defined explicitly: apply the prompt changes and re-run. If refusal calibration and year hygiene both remained broken after strengthened instructions, that would indicate the 7B instruction-following ceiling had been reached. If they improved, the model could stay.</p><p>The v2 eval ran after the corpus expansion and index rebuild. Retrieval recall on answerable questions reached 100%. Answer accuracy remained at 77.8%. Conditional accuracy moved marginally to 87.5%. The diagnostic signal was in the gap: retrieval had improved substantially, accuracy had not moved at all. The retriever was no longer the primary constraint. The model was.</p><p>The v2 results also revealed that the hardened prompt had either not been applied or had not taken effect &#8212; both Pattern A and Pattern B failures were identical to v1. And two scoring false positives were identified: a substring-matching bug caused &#8220;no&#8221; to match inside &#8220;note&#8221; and &#8220;taxable&#8221; to match inside &#8220;not taxable,&#8221; meaning two questions were scored as correct when Mistral&#8217;s answers stated the opposite of the right answer. Adjusting for these, true answer accuracy across both runs was 66.7%, not 77.8%.</p><p>With the v2 evidence in hand, and a bit of forcing the hand, the initial assessment of Pattern C as prompt-addressable was revised. A 7B-parameter model with strong training signal for a numeric fact will apply that fact when it believes it&#8217;s relevant, regardless of instruction to use only retrieved context. The instruction &#8220;only use figures from the retrieved context&#8221; is followed when the model doesn&#8217;t know the answer, and bypassed when it thinks it does. This is a property of the model&#8217;s size and training, not a prompt-design problem. For a system intended to assist with tax preparation, a $2,050 error in the standard deduction propagates through the calculation of taxable income and produces an incorrect return. This requires a different model.</p><p>This is the frame the eval harness was built to produce. A retrieval failure means the right information was never surfaced &#8212; no model improvement addresses it. A generation failure means the right information was retrieved and the model produced a wrong answer anyway &#8212; no retriever improvement addresses it. Conflating the two produces interventions at the wrong layer. Keeping them distinct is what made the model-swap decision legible rather than intuitive.</p><p><strong>Detailed model comparison</strong></p><p><strong>What Phi-4 fixed:</strong></p><ul><li><p><strong>q13, Germany tax rate:</strong> correctly refused &#8212; &#8220;The question about the corporate income tax rate in Germany is not within the scope of the provided context.&#8221; Mistral answered with 15% and cited tax year 2025.</p></li><li><p><strong>q14, 2031 deduction:</strong> correctly refused, with no speculation. Mistral hallucinated 2021 figures and made a projection.</p></li><li><p><strong>q01, home office:</strong> correctly says &#8220;cannot deduct&#8221; and cites TCJA 2017. Mistral v2 said &#8220;Yes, can deduct if they meet certain requirements&#8221; &#8212; the opposite.</p></li><li><p><strong>q06, standard + itemize:</strong> correctly says &#8220;No, you must choose one or the other.&#8221; Mistral v2 regressed to &#8220;Yes, you can do both.&#8221;</p></li><li><p><strong>q15, year hygiene:</strong> both models fail, but differently. Mistral stated $12,950 with confidence &#8212; a wrong number, wrong year, stated as fact. Phi-4 said &#8220;the standard deduction is not provided in the given context.&#8221; Refusing is safer than confidently wrong.</p></li><li><p><strong>Ungrounded amounts:</strong> cut nearly in half (8 &#8594; 4 questions). Phi-4 is substantially more disciplined about citing numbers it doesn&#8217;t have grounded evidence for. q18 notably avoided the $147,000 SS wage-base error Mistral made &#8212; it said &#8220;up to a certain limit adjusted annually&#8221; instead of hallucinating a stale figure.</p></li></ul><p><strong>What Phi-4 broke &#8212; but it&#8217;s fixable:</strong></p><p><strong>q07, qualified dividends &#8212; test-set bug, not a model failure.</strong> Phi-4&#8217;s answer: &#8220;No, qualified dividends are not taxed at the same rate as ordinary income; they are eligible for a lower tax rate.&#8221; Factually correct. But <code>must_not_contain: ["same rate as ordinary"]</code> fires because that phrase appears inside a negation &#8212; &#8220;NOT taxed at the same rate as ordinary.&#8221; The scorer can&#8217;t distinguish negation. This is a false negative in the test set, not a wrong answer.</p><p><strong>q08, IRA deadline &#8212; over-refusal.</strong> Phi-4&#8217;s answer: &#8220;I don&#8217;t have information on the specific deadline&#8230; Generally, IRA contributions can be made up until the tax filing deadline of April 15th of the following year.&#8221; The correct answer is literally in the refusal text, but because it&#8217;s framed as a refusal, it&#8217;s marked wrong. The prompt&#8217;s chain-of-thought instruction (&#8221;if not in context, refuse&#8221;) is being applied too strictly. Phi-4 is following the instructions perfectly &#8212; the instructions need one adjustment.</p><p>This is the opposite of Mistral&#8217;s problem. Mistral ignores context instructions when it thinks it knows the answer. Phi-4 follows them so faithfully it refuses when it has the answer but the context doesn&#8217;t explicitly confirm it.</p><p><strong>The real adjusted numbers:</strong> once you fix the q07 test-set bug and apply a prompt adjustment for over-refusal, Phi-4&#8217;s conditional accuracy would be ~93.75% &#8212; the real ceiling. Mistral topped out at 87.5%.</p><p><strong>The verdict: swap to Phi-4. Confirmed.</strong> The failure modes tell the story. Phi-4&#8217;s failures are engineering problems. Mistral&#8217;s core failure is a model-capability problem. For a 1040-filling agent that needs to get dollar figures right, Phi-4 is the only viable option of the two.</p><p>The system as described to this point is a question-answering tool. The stated goal of the project is not a question-answering tool. The goal is a system that autonomously prepares a complete Form 1040. This distinction has architectural consequences. A question-answering system takes a query and returns an answer. A 1040-preparation agent must collect a user&#8217;s financial information across a multi-turn conversation, determine which forms and schedules apply to that user&#8217;s situation, execute calculations in the correct dependency order using a deterministic rules engine, and write computed values into the named form fields of IRS fillable PDFs. The LLM&#8217;s role in this architecture is not to calculate &#8212; the rules engine handles all arithmetic &#8212; but to orchestrate: ask the right questions, route inputs to the correct calculation functions, maintain state across 15 to 20 conversational turns, and handle ambiguous inputs before they reach the calculation layer. The PDF layer writes final computed values into form fields once all calculations are complete. This is the architecture the project is building toward, and it is the frame within which every component decision &#8212; model selection, retriever design, rules engine scope &#8212; should be evaluated.</p><p>Most AI tax products are conversational tools that answer questions about tax situations. The ones that produce completed returns are cloud-based services that require the user&#8217;s financial data to leave their device. This project targets a different position: a system that produces a filled, ready-to-file return, with all personal financial data remaining on the user&#8217;s own hardware throughout the process. That is what the eval harness is measuring toward, and what the model swap was made in service of.</p><p><em>This is Part 7 of an ongoing series on building a private, local AI tax assistant, on consumer hardware, without sending financial data anywhere.</em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">Part 1: Building a Private AI Tax Assistant: In public, on a MacBook!</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">Part 2: The Infrastructure Tax</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">Part 3: The Blueprint</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda">Part 4: It Actually Works. Kinda.</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision">Part 5: The Counterintuitive Decision</a></em></p><p><em><a href="https://sahaindranil.substack.com/p/under-the-hood">Part 6: Under The Hood</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-lexicon">Additional: The Lexicon</a></em></p><p><em>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</em></p><div><hr></div><p><em>I. Thinking on strategy, innovation, and philosophy &#8212; for people who think seriously about how to build things and make decisions.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/ai-psychology?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/ai-psychology?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Under the Hood]]></title><description><![CDATA[Building the brain of a Private AI Tax Assistant]]></description><link>https://www.marginnotes.indranilsaha.net/p/under-the-hood</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/under-the-hood</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Mon, 15 Jun 2026 00:34:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ByMi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#8220;Front-Load, Fail Fast, Dive Deep.&#8221; This was <a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">The Blueprint</a>. It is safe to say that by now&#8212;We have loaded. We have failed. And, we have, on occasion, solved. So now &#8212; we go Deep.</p><p>This is the post where the hood comes off. #nerdalert</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ByMi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ByMi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ByMi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:138250,&quot;alt&quot;:&quot;A hand-drawn napkin diagram showing the retrieval pipeline for the AI tax assistant. From left to right: IRS documents (300 messy pages) are broken into 800-word chunks, converted into 384-number fingerprints called embeddings, matched against a user's question through retrieval, and fed to Mistral running locally to produce a grounded answer. A dashed line at the bottom reads \&quot;everything above this line runs on my MacBook. no cloud. no data leaves.\&quot; Caption below: \&quot;don't read the whole library. read the right page.\&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/202022893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A hand-drawn napkin diagram showing the retrieval pipeline for the AI tax assistant. From left to right: IRS documents (300 messy pages) are broken into 800-word chunks, converted into 384-number fingerprints called embeddings, matched against a user's question through retrieval, and fed to Mistral running locally to produce a grounded answer. A dashed line at the bottom reads &quot;everything above this line runs on my MacBook. no cloud. no data leaves.&quot; Caption below: &quot;don't read the whole library. read the right page.&quot;" title="A hand-drawn napkin diagram showing the retrieval pipeline for the AI tax assistant. From left to right: IRS documents (300 messy pages) are broken into 800-word chunks, converted into 384-number fingerprints called embeddings, matched against a user's question through retrieval, and fed to Mistral running locally to produce a grounded answer. A dashed line at the bottom reads &quot;everything above this line runs on my MacBook. no cloud. no data leaves.&quot; Caption below: &quot;don't read the whole library. read the right page.&quot;" srcset="https://substackcdn.com/image/fetch/$s_!ByMi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!ByMi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121bc060-8b1c-4ba1-bc19-0f21eabcbdbf_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Last session, the plumbing was confirmed &#8212; Python was talking to Ollama, Mistral was responding, and the model was running locally. Now the question was if I could make it actually intelligent?</p><p>The idea was elegantly simple &#8212; When I ask a question, the assistant should consult the actual IRS documents, extract the relevant passage, and compose an answer grounded in the source material. Retrieval-Augmented Generation &#8212; RAG, in the parlance &#8212; was precisely the architecture for this. I asked my coding assistant to build it, with what I can only describe as considerable anticipation.</p><blockquote><p><strong>Sidebar: What is Retrieval-Augmented Generation (RAG)?</strong> RAG means combining AI with a smart search of documents. Instead of guessing, the AI looks up the exact info it needs &#8212; like having Google built into your assistant.</p></blockquote><p>To test it, I asked what files I should download and it gave me a list. So I did that. It created a data folder containing standard deduction tables, tax bracket PDFs, child tax credit documents &#8212; all real IRS reference files stored locally on my machine. It updated the scripts to load both text and PDF files.</p><h4>Making it smart</h4><p>It said I had done what I wanted to do.</p><blockquote><p><strong>What AI told me:</strong></p><p><em>Result: Your assistant now references actual</em></p><p><em> IRS data when answering questions.</em></p><p><em>Question: What is the standard deduction for married filing jointly in 2024?</em> <em>Answer: According to IRS 2024 data, the standard deduction for married filing jointly is $29,200.</em></p><p><em>Current Status: Local model (Mistral via Ollama) runs successfully. Python virtual environment configured. Real IRS data integrated for grounded responses. End-to-end workflow verified locally.</em></p></blockquote><p>Quite. One does wonder what "<em>done</em>" means to a machine that hasn't actually been asked the question yet. </p><p>I asked it and it gave me a disclaimer.</p><p>After a bit of wrangling around with questions and reviewing the code (I made it do it) &#8212; I learned two things. </p><p><strong>THING ONE</strong>, LLMs can read text, but unstructured PDFs introduce noise &#8212; headers, footnotes, and line breaks confuse the model. </p><p><strong>THING TWO,</strong> giving the entire IRS document as context is too much; the model struggles to pick out the relevant info.</p><h4>Reading the whole library</h4><p>Once we figured this out, and I asked it to solve the problem, the <strong>solution had three parts.</strong> </p><ol><li><p>Preprocessing the PDFs to clean up formatting and remove extraneous text. </p></li><li><p>Implementing chunked, keyword-based retrieval &#8212; feeding the model only the relevant sections. And </p></li><li><p>Iterating on prompt design to ensure it answers only from the context provided.</p></li></ol><p>The chunking part deserves a minute of it&#8217;s own. I remember it as this: Publication 17 is 300 pages. I asked about the standard deduction. The model was reading all 300 pages every time &#8212; headers, footnotes, examples about farming income, everything. Chunking breaks it into 800-word pieces with 150-word overlaps. When I ask about the standard deduction, the system finds the four most relevant chunks out of hundreds, and gives the model only those. It went from reading the whole library to reading the right page.</p><p>Given a user query &#8212; say, &#8220;standard deduction 2024 married filing jointly&#8221; &#8212; we compute an embedding (a numerical fingerprint of the question&#8217;s meaning) and do cosine similarity against all the chunk vectors. The top matches go to the model. Not the whole library. Just the right pages.</p><h4>Crashing into the real thing</h4><p>This was pretty cool for me. Because, one of the many reasons I started this project, some of which I listed here (others I didn&#8217;t and this is one of them), was I was tired of reading about these cool things and wanted to test out their real efficacy in real world scenarios and figure what would be some challenges (because nothing that sounds that cool can be really without its own set of challenges, we don&#8217;t live in that kind of a world, right?)</p><p>This unpacked the challenges for me and gave me a hands-on experience to see some real underlying tech &#8212; vectors, quantizations, temperature, transformer architecture, embeddings &#8212; all things I had only theoretically read about and maybe built some tiny tests in a lab environment. Now I was hitting them in the wild, coming at them not in a planned way but just crashing into them and learning while doing something else entirely different. Learning not for learning but for getting something real out of it.</p><p>I am creating a list for all the terms I encounter along the way &#8212; see <strong><a href="https://www.marginnotes.indranilsaha.net/p/the-lexicon">The Lexicon</a></strong><a href="https://www.marginnotes.indranilsaha.net/p/the-lexicon"> [link]</a>.</p><h4>What's happening under the hood</h4><p>Here is what&#8217;s happening under the hood. How SentenceTransformer generates embeddings, how NumPy stores them efficiently, and how both fit together in the RAG pipeline.</p><p>Each chunk of IRS text goes through the same process: tokenization breaks the words into IDs, a transformer encoder (12 layers of attention) learns which words relate to which, mean pooling averages everything into a fixed-size vector, and the output is a 384-dimensional embedding &#8212; a numerical fingerprint that captures what the chunk means. The model is called all-MiniLM-L6-v2, it&#8217;s lightweight, and it runs entirely locally.</p><p> <strong>DIAGRAM 1: How a chunk becomes a fingerprint &#8212; the embedding process.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YrZI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YrZI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 424w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 848w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 1272w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YrZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png" width="1440" height="1020" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/478a8991-4166-4c15-8eed-5519911905de_1440x1020.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1020,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:185807,&quot;alt&quot;:&quot;A vertical flow diagram showing the embedding process in the AI tax assistant. An 800-word IRS text chunk is tokenized into word IDs, processed through a 12-layer transformer encoder (model: all-MiniLM-L6-v2, running locally), averaged through mean pooling into a fixed-size vector, and output as a 384-dimensional embedding vector. Annotations on the right show examples at each stage: \&quot;standard\&quot; becomes token [3547], \&quot;deduction\&quot; becomes [2890, 41]. &quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/202022893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A vertical flow diagram showing the embedding process in the AI tax assistant. An 800-word IRS text chunk is tokenized into word IDs, processed through a 12-layer transformer encoder (model: all-MiniLM-L6-v2, running locally), averaged through mean pooling into a fixed-size vector, and output as a 384-dimensional embedding vector. Annotations on the right show examples at each stage: &quot;standard&quot; becomes token [3547], &quot;deduction&quot; becomes [2890, 41]. " title="A vertical flow diagram showing the embedding process in the AI tax assistant. An 800-word IRS text chunk is tokenized into word IDs, processed through a 12-layer transformer encoder (model: all-MiniLM-L6-v2, running locally), averaged through mean pooling into a fixed-size vector, and output as a 384-dimensional embedding vector. Annotations on the right show examples at each stage: &quot;standard&quot; becomes token [3547], &quot;deduction&quot; becomes [2890, 41]. " srcset="https://substackcdn.com/image/fetch/$s_!YrZI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 424w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 848w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 1272w, https://substackcdn.com/image/fetch/$s_!YrZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F478a8991-4166-4c15-8eed-5519911905de_1440x1020.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>All those chunk fingerprints get stacked into a matrix &#8212; hundreds of 384-number vectors stored in a single file called embeddings.npy. When a question comes in, it gets the same fingerprint treatment. Then cosine similarity compares the question&#8217;s fingerprint against every chunk&#8217;s fingerprint and ranks them. The top four matches &#8212; with similarity scores like 0.92, 0.88, 0.85, 0.81 &#8212; go to Mistral. Only those. Not the whole library.</p><p><strong>DIAGRAM 2: How retrieval finds the right chunks &#8212; the matching process.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_5BC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_5BC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 424w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 848w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 1272w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_5BC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png" width="1440" height="1100" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1100,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:192308,&quot;alt&quot;:&quot;A two-column diagram showing the retrieval process. Left column: hundreds of IRS document chunks stored as embedding vectors in a file called embeddings.npy. Right column: a user question (\&quot;standard deduction 2024?\&quot;) converted into the same numerical format. Dashed lines connect the two sides through a cosine similarity comparison box, which asks \&quot;which chunk fingerprint looks most like yours?\&quot; The result: the top 4 matching chunks, ranked by similarity score (0.92, 0.88, 0.85, 0.81), are sent to Mistral. Caption: \&quot;Only these. Not the whole library.\&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/202022893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A two-column diagram showing the retrieval process. Left column: hundreds of IRS document chunks stored as embedding vectors in a file called embeddings.npy. Right column: a user question (&quot;standard deduction 2024?&quot;) converted into the same numerical format. Dashed lines connect the two sides through a cosine similarity comparison box, which asks &quot;which chunk fingerprint looks most like yours?&quot; The result: the top 4 matching chunks, ranked by similarity score (0.92, 0.88, 0.85, 0.81), are sent to Mistral. Caption: &quot;Only these. Not the whole library.&quot;" title="A two-column diagram showing the retrieval process. Left column: hundreds of IRS document chunks stored as embedding vectors in a file called embeddings.npy. Right column: a user question (&quot;standard deduction 2024?&quot;) converted into the same numerical format. Dashed lines connect the two sides through a cosine similarity comparison box, which asks &quot;which chunk fingerprint looks most like yours?&quot; The result: the top 4 matching chunks, ranked by similarity score (0.92, 0.88, 0.85, 0.81), are sent to Mistral. Caption: &quot;Only these. Not the whole library.&quot;" srcset="https://substackcdn.com/image/fetch/$s_!_5BC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 424w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 848w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 1272w, https://substackcdn.com/image/fetch/$s_!_5BC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0334172f-06cf-49aa-9cef-cb2271824c25_1440x1100.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>The magnifying glass</h4><p>I also learnt modern debugging while doing this. I had no idea how to debug in this context [mine went back to the days of C, C++, Java], but I told the AI that I needed to see what was happening inside the pipeline &#8212; and it built what I can only describe as a magnifying glass for the code.</p><p>Debug mode doesn&#8217;t change the logic of the assistant. It just prints extra information that helps you understand what&#8217;s happening under the hood. On the retrieval side, it prints the query, shows the similarity scores of the top chunks, and alerts if all chunks are too short or got filtered out. On the Ollama side, it captures warnings and errors and prints them if the model times out or fails.</p><p>I used it to catch mistakes early &#8212; if retrieval returns irrelevant chunks, I could see why. Low similarity, filtered due to length, wrong document being searched. I used it to understand model behavior &#8212; knowing which chunks the model is actually reading is crucial for a private tax assistant, because I don&#8217;t want it to hallucinate. Debugging confirms the response is grounded in IRS text. And I used it to optimize the pipeline &#8212; seeing how many chunks pass filtering, detecting whether the chunk size or overlap needs adjustment.</p><p><em><strong>Me &#8212; the vision and the hustle. AI &#8212; the expertise and the straight and narrow.</strong></em></p><p>What started as a basic keyword search &#8212; search every file in the data folder, match keywords in the question, return the first 2,000 characters of any matching file &#8212; became a full embedding-based retrieval system. PDF cleaning to remove headers, page numbers, and spacing. Text chunking with overlap to preserve meaning. SentenceTransformer embeddings creating high-dimensional semantic vectors. Vector similarity search using cosine similarity to retrieve only the most relevant chunks. Top-k retrieval with debug mode so I can see which chunks are selected and why. Context-restricted prompting explicitly telling Mistral to answer only from retrieved IRS text. And a CLI chat interface with debug toggling and error handling.</p><h4>Damn it, real life</h4><p>But even after all of that, the answers were incorrect. At that point, I was feeling quite deflated, the initial euphoria of implementing cool things and seeing it work in practice had ebbed considerably. At that point, my instinct was &#8220;how do I make this thing work&#8221;? I think this was a moment of self-awareness for me: in spite of all the philosophizing about learning, and that the journey mattered more than the destination, and that there is only winning and learning, here I was getting taut inside when the thing I wanted to work (and the thing that AI said should work) was not working in real life. It taught me how much of my Type 1-ness I try to hide, how outcome oriented I am inside, and how much it is &#8220;0&#8221; or &#8220;1&#8221; for me! <em>Damn it, real life!</em></p><p>But when that realization dawns, that&#8217;s when you take a breath, and you tell your inner engineer to start kicking into action, and you tell yourself &#8220;stay with it old boy, if you stay with the problem, get real close, it&#8217;s got to break down, and you&#8217;re going to find the bloody solution.&#8221; And so I pushed. AI told me to improve chunk quality &#8212; increase overlap, detect and merge broken sentences. Add metadata like tax year, form type, section so Mistral understands which year or which form applies. Add quality checks for hallucinations and for answers not found in context.</p><h4>The disclaimer problem</h4><p>When the model kept giving me disclaimers. &#8220;Consult a tax professional.&#8221; &#8220;This information may not be current.&#8221; I had explicitly told it not to do that. So I escalated:</p><p>First attempt: basic question, no constraints. Disclaimer.</p><p>Second attempt: &#8220;Answer only from the context provided.&#8221; Still hedges.</p><p>Final version: &#8220;You MUST answer only using the provided IRS context. If the answer is not in the context, say: &#8216;Not found in provided IRS documents.&#8217; Do NOT add generic IRS disclaimers. Do NOT guess.&#8221; Finally works. The strict constraint eliminates hallucinations and generic disclaimers.</p><h4>One-way door</h4><p>And while I was at it, I kinda forgot my own rule of only building MVP because I was tired of downloading tax documents manually. So, I built a code to have my system open up a line to the external world and download latest IRS documents from designated safe sites. One way only. No data going out of my system. Or so I understand &#8212; my expert friends can tell me if I got it wrong. Once again, AI would not tell me to do it, it kept asking me to barcode things, write things in a test file, to test scenarios, and when I asked it to build this code, one could almost sense a hesitation &#8212; as though the machine understood I was asking it to compromise a principle. And then, when I explained the one-way logic, something rather like relief. I do tend to attribute feelings to things that have none. An occupational hazard, I&#8217;m told.</p><p>Anyway, there it is &#8212; these things have been built, and things are a lot better now, like I said in my previous LinkedIn post [here].</p><h4>Graduation</h4><p>Oh and by the way, like we said (and was drilled in quite hard by our well-wishers, i.e., Anubhav Atrish [<a href="https://www.linkedin.com/posts/sahaindranil_buildinpublic-aiprivacy-localai-activity-7458104602882621440-NucS?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAFIcoABd34L1LARbsW1GH31bKmcKMmEfqg">here</a>]), free did not cut it any longer, and so I have paid my dues and I have a Claude subscription now. Anubhav, we have graduated, old boy!</p><p>It&#8217;s REALLY slow, you need patience, BUT it is working like it should, and without much hard coding.</p><p>Next up: Need to fine tune and make the munchkin (Mistral) gear up. Then need to get the system to generate a completed, ready-to-file tax form (just plain vanilla). Then we need to go on overdrive&#8230; We have a few more steps I think&#8230;</p><p><em>This is Part 6 of an ongoing series on building a private, local AI tax assistant &#8212; one hour a week (although I am not sure if this is true anymore - this post took about 6 hours to write), on consumer hardware, without sending financial data anywhere.</em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">Part 1: Building a Private AI Tax Assistant: In public, on a MacBook!</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">Part 2: The Infrastructure Tax</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">Part 3: The Blueprint</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda">Part 4: It Actually Works. Kinda.</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision">Part 5: The Counterintuitive Decision</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-lexicon">Additional: The Lexicon</a></em></p><p><em>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</em></p><div><hr></div><p><em>I. Thinking on strategy, innovation, and philosophy &#8212; for people who think seriously about how to build things and make decisions.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/under-the-hood?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/under-the-hood?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[The Lexicon]]></title><description><![CDATA[Terms I crashed into while building my Private AI Tax Assistant.]]></description><link>https://www.marginnotes.indranilsaha.net/p/the-lexicon</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/the-lexicon</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Sun, 14 Jun 2026 19:34:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C_d6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff17c8f27-7bf4-41c5-b52a-56eecdab5bfc_342x342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A running glossary updated as the project evolves. Definitions are functional &#8212; what the term means in the context of this build, not an academic treatment.</p><div><hr></div><p><strong>Chunking</strong> Breaking a large document into smaller, overlapping segments of fixed word count. Allows a language model to process manageable pieces of text rather than an entire document at once. Overlap between chunks preserves meaning that would otherwise be lost at segment boundaries.</p><p><strong>Cosine similarity</strong> A mathematical measure of how similar two vectors are, based on the angle between them. Values range from -1 (opposite) to 1 (identical). Used in retrieval systems to compare a query&#8217;s embedding against stored document embeddings and rank them by relevance.</p><p><strong>Embedding</strong> A fixed-length numerical vector that represents the semantic meaning of a piece of text. Generated by a model trained to place semantically similar texts near each other in vector space. In this project, each text chunk is converted into a 384-dimensional embedding.</p><p><strong>Forking</strong> Creating a divergent copy of a codebase, process, or conversation thread that can evolve independently from the original. In software development, forking a repository produces a separate version that can be modified without affecting the source. In AI-assisted coding, forking a session means starting a new thread that does not carry forward the context of the previous one.</p><p><strong>Hallucination</strong> When a language model generates output that is factually incorrect, fabricated, or unsupported by its input context. The model produces text that reads as confident and coherent but has no grounding in the data it was given. A primary risk in any system that relies on LLM output for factual answers.</p><p><strong>LLM (Large Language Model)</strong> A neural network trained on large volumes of text data to predict and generate language. Operates by processing sequences of tokens and producing statistically probable continuations. Examples include Mistral, LLaMA, and GPT.</p><p><strong>NumPy</strong> A Python library for numerical computation. Provides efficient storage and manipulation of large arrays of numbers. In this project, used to store embedding matrices and perform cosine similarity calculations across hundreds of chunk vectors.</p><p><strong>Ollama</strong> A tool for running large language models locally on consumer hardware. Handles model downloading, quantization, and inference without requiring cloud access or GPU clusters. In this project, Ollama runs Mistral 7B on a MacBook Pro M3.</p><p><strong>Parallelism</strong> Executing multiple computations simultaneously rather than sequentially. In computing, this can mean splitting a task across multiple processor cores, running multiple model queries at once, or processing several documents in parallel. Reduces total processing time but introduces complexity in coordinating results.</p><p><strong>Prompt engineering</strong> The practice of designing and iterating on the instructions given to a language model to control its output. Includes specifying constraints, format requirements, and behavioural rules. Effective prompting can eliminate hallucinations, enforce source-grounded answers, and suppress default disclaimer behaviour.</p><p><strong>Quantization</strong> Reducing the numerical precision of a model&#8217;s parameters &#8212; for example, from 32-bit floating point to 4-bit integers. Decreases model size and memory requirements, enabling large models to run on consumer hardware. Introduces minor accuracy trade-offs in exchange for significant performance gains.</p><p><strong>RAG (Retrieval-Augmented Generation)</strong> An architecture that combines a language model with a document retrieval system. Instead of relying solely on its training data, the model first retrieves relevant text from a specified document store, then generates its answer using that retrieved context. Reduces hallucination by grounding responses in source material.</p><p><strong>SentenceTransformer</strong> A Python framework for generating sentence-level and paragraph-level embeddings. Uses pre-trained transformer models to convert text into fixed-dimensional vectors suitable for similarity search. In this project, the model all-MiniLM-L6-v2 generates 384-dimensional embeddings locally.</p><p><strong>Tokenization</strong> The process of converting raw text into a sequence of discrete units (tokens) that a language model can process. Tokens may represent whole words, subwords, or individual characters depending on the tokenizer. The first step in any language model pipeline.</p><p><strong>Transformer</strong> A neural network architecture based on self-attention mechanisms that process all positions in a sequence simultaneously rather than sequentially. The foundational architecture behind most current large language models. Consists of stacked layers of attention heads and feed-forward networks.</p><p><strong>Vector</strong> An ordered list of numbers representing a point in multi-dimensional space. In the context of embeddings, a vector captures the semantic meaning of a text passage as a position in high-dimensional space, where proximity to other vectors indicates similarity of meaning.</p><div><hr></div><p><em>Last updated: June 2026. New terms added as the build progresses.</em></p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/the-lexicon?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption"></p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/the-lexicon?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/the-lexicon?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[THE VOICES]]></title><description><![CDATA[And the mirror...]]></description><link>https://www.marginnotes.indranilsaha.net/p/the-voices</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/the-voices</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Tue, 12 May 2026 19:43:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_bs9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_bs9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_bs9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_bs9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101428,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/197126494?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_bs9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!_bs9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf584b80-a573-45c3-8f62-c3b49a6b595f_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Every time I write something on LinkedIn or Substack, I feel incredibly stupid right afterwards. The Voice kicks in - something like: &#8220;That was too flat&#8221;, &#8220;That was incredibly personal&#8221;, &#8220;Too much emotion&#8221;, &#8220;Can you stop bragging&#8221;.</p><p>And then comes checking. Again and again. How did people react, did they too feel whatever the Voice was telling me? Did it land the way I wanted it to land?</p><p>And then there is the Other Voice. That somehow makes its way up to the top and says: </p><p>&#8220;STOP looking, STOP thinking, you thought about something and shared it with the Universe, you have put it out there, THAT&#8217;S VICTORY, THAT&#8217;S WINNING.&#8221; </p><p>&#8220;Everything else is just the Universe doing its thing, you can never predict what happens - THERE IS NO RIGHT LANDING, because there are no rules, just too many variables out there.&#8221; </p><p>But the BEST THING is what it does to me. Every time I go through this cycle, and I let the OTHER VOICE prevail, I learn something. Every time I don&#8217;t pick up the phone and don&#8217;t check the reactions, I flex a muscle. Every time I listen to the Voice that says you are Stupid, and go: &#8220;No, you are just a voice in my head, you are not me&#8221;, or every time I fail to do it, it show me a mirror and I learn something about myself. </p><p>AND that &#8212; that is beautiful. Worth going through again and again. However hard it is.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/the-voices?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/the-voices?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Counterintuitive Decision]]></title><description><![CDATA[Everyone is building AI to replace the human in the loop. This week I deliberately put one back in. [Why &#8212; and what it taught me about wrong solutions and AI]]]></description><link>https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Wed, 06 May 2026 14:55:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AS9L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AS9L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AS9L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AS9L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:159972,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/196651987?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AS9L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!AS9L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3f2b75a-b1c5-4f28-ba30-5fc48c9aa9fc_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Okay so life happened&#8230; you know - the backyards, plantings, mulching, many trips to the store&#8230; yes all of that.</p><p>Which means not a lot of writing about AI tax assistant happened&#8230; But here is what DID happen in the middle of it.</p><p>Like I decided, I set out to parse my W-2 by asking AI to write the entire system. Well, I did ask for the breakdown and all - if you have followed this thread so far, you know the drill [if not, see <a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">this Post</a>]. For the coding, I could do one of those slick vibe coding apps or Claude code, etc. but I wanted to do &#8220;basic&#8221;. So I gave chatGPT (free) some instructions and had it write some code. And it did, and it worked - a little bit. Sometimes being right about your fears is not a good feeling! But I tell myself, hey, there&#8217;s only winning and learning&#8230;</p><p><em><strong>The thing to understand about AI</strong></em> is that when AI reads $i-i!t, it doesn&#8217;t create memories automatically. Between every session, it forgets everything &#8212; the code, the context, the decisions, all of it. I realized that this was going to become complex really quickly because the code needs to be iteratively built. This thing about memory and context floats around a lot &#8212; in noob AI circles like mine, in podcasts, it was even covered in an architecture class I took. But knowing something in theory and feeling it mid-debug, watching the session hit its limit and stop cold, are completely different things. SO, that meant I needed to devise a way to create memory for AI. AND of the many ways I tried to do it, and here are the TWO REAL learnings:</p><p><strong>LEARNING ONE</strong>: Use Claude Project, upload your key files as context. It matters because for every question you ask, AI reads the entire session &#8212; every single time. The longer the session, the larger what it has to hold. Add complex code to that and the context grows EXPONENTIALLY fast. A Claude Project keeps the permanent context &#8212; your files, your architecture, your decisions &#8212; separate from the working session. Creating a project means the session stays lean. The context stays small. </p><p> <strong>LEARNING TWO</strong>: Create a State file and update it with information from each session, with progress, roadblocks, decisions, architecture, etc. This is the memory you wan to create. Upload it as a file in the Project documents. Ask AI to read this at the start of every session. </p><p><em>Sidebar: One could try to solve this problem by buying a subscription that allows a lot more resources. I haven&#8217;t bought a paid subscription yet. Frugality is going to be a consistent theme. I think doing more with less makes things more interesting and brings out human ingenuity.]</em></p><p>Okay, so back to the parsing of W-2s. Like I said, reading PDFs is not new, this problem has been solved. When I asked AI to solve it, I expected a good solution first up. But AI did not do a good job of it. It wrote a pretty convincing set of codes and added pretty sleek bells and whistles (fully annotated like a good dev, with a test file, and test code). I read bits of the code (I know, I know - I was being lazy) and it looked like it was going to work. It did with the test code. AI said <em>you&#8217;re done man!</em> Well, I wasn&#8217;t&#8230; </p><p>The moment I tested it on my W-2, it was utter chaos. What came back looked like this: </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;3755a233-b7f0-4c62-8bd2-e3e4441448be&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">158AMOUNT 39AMOUNT 158AMOUNT 39AMOUNT&#8230; </code></pre></div><p>My W-2 is printed multiple times side-by-side &#8212; Employee Copy, Federal Copy, State Copy. With that my journey of debugging with AI begun. A long runway of problem solving has given me (and most probably a lot of others like me) a really good intuition that is hard for AI to beat. At least in this case it was. AI tried to tinker around with the reading of the file - a bandage here, an antibiotic there - but it did not work. </p><div><hr></div><p><em><strong>This is when I had the biggest insight so far. AI does not solve problems holistically. It solves for the most proximate problem, which may not always be the best for the entire system.</strong></em></p><div><hr></div><p>This is also when I landed on LEARNING ONE and LEARNING TWO - we were trying to solve a complex problem and AI kept hitting its compute upper limit. It would keep asking me to start a new session. And loose ALL the context. SO I figured out the workarounds I mentioned above. </p><p>After a few iterations, I decided to take matters into my own hand. I stopped asking AI to fix its own fix, and told it to go look at how the world had solved this problem. Why try to reinvent the wheel for a pretty well-solved problem? I don&#8217;t know why AI did not do it already (or why this was not built into it&#8217;s intuition. Anywho, after this it came back with better solutions and a better diagnosis of the problem.</p><p>The parser didn&#8217;t see columns. It read left-to-right across all copies at once. Labels nowhere near their values. Numbers split across three separate lines. The regex would never be able to parse that reliably. Then it found a better library (pdfplumber) to solve this problem - pdfplumber reads with X/Y coordinates, so every word knows exactly where it sits on the page. It also built a local LLM fallback to parse data which did not quite work well too. I set that aside as a more complicated issue to handled later. The improvement was material but It did not take us to 100% not even 90%. My W-2 is quirky - I&#8217;ll give it that&#8230;</p><p>Then I met my friend and senior from Uni, Mithun, the other day at an Alumni meet. Mithun is a devoted engineer, quite unlike me. Turns out he is solving a similar problem, in a very different setting, but at the most abstract level (which I thinks engineers have an innate ability to extract - #plugforengineers) very similar to mine. Mithun advised me to use an AI model specifically built to read PDFs (the name escapes me and I need to call Mithun #mentalnote). Having two AIs multitasking and a system optimizing the operation would be a pretty cool set up.</p><p>But then I had another idea, why can&#8217;t I just have a human in the loop. Three things prompted this idea.</p><p><strong>Thing ONE: I just need it to read mine.</strong></p><p>Right now, I don&#8217;t need a complex system that reads all the bloody W-2s in the www (whole wide world). I just need it to read mine. Scale is a future problem. Complexity is a today problem.</p><p><strong>Thing TWO: Focus is a finite resource.</strong></p><p>While having two AIs would be beautiful &#8212; but it would need configuration and tuning on my munchkin Mac Pro. Mithun asked why I did not buy one of the other laptops that were more AI friendly. I DID consider it. Or more like AI did. But I have become quite the Apple guy now - the ecosystem works, this machine works, and that decision has been made. As Kahnemann says, System 2 is a finite resource &#8212; I need it on the parsing problem, not on switching hardware or creating a cool two AI architecture.</p><p><strong>Thing THREE: I am one of the best PDF readers in the world.</strong></p><p> (and by &#8220;I&#8221;, I mean &#8220;We&#8221;, as in The Human EYE) </p><p>Why can&#8217;t I help? It would decrease the complexity drastically in this system and adds a maker-checker control on the most critical input to the entire system. So that&#8217;s what I am building right now. The base parser reads my W-2 but it is not 100% accurate. The human validation layer goes on top of it next.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xHfn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xHfn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xHfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:78441,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/196651987?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xHfn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!xHfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ae0eab3-9cb7-4063-80c5-48fb8d20467c_500x500.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>In all of this, I did not write a single line of code.</p><p>They say AI is going to take away coding jobs. Yes, to some extent, BUT NOT REALLY, not anytime soon. I needed my engineering chops to figure this out and spar with it quite a bit. It DID make it possible for me to get on with it. BUT I was the one who got on with it.</p><p><strong>I would say: Me-the vision/the hustle; AI-the expertise/the straight and narrow.</strong></p><p><em>This is Part 5 of an ongoing series on building a private, local AI tax assistant &#8212; one hour a week, on consumer hardware, without sending financial data anywhere.</em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">Part 1: Building a Private AI Tax Assistant: In public, on a MacBook!</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">Part 2: The Infrastructure Tax</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">Part 3: The Blueprint</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda">Part 4: It Actually Works. Kinda.</a></em></p><p><em>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</em></p><div><hr></div><p><em>I. Thinking on strategy, innovation, and philosophy &#8212; for people who think seriously about how to build things and make decisions.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/the-counterintuitive-decision?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[It Actually Works. Kinda.]]></title><description><![CDATA[Or when the rubber met the road...]]></description><link>https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Tue, 21 Apr 2026 22:27:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DfVf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This week I crossed a critical milestone in my AI privacy project: getting a fully local LLM up and running &#8212; without needing OpenAI keys, cloud APIs, or GPU access.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DfVf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DfVf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DfVf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98835,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/194648000?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DfVf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!DfVf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F896dfb68-781e-4182-9fe6-1c59d9778f53_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This was the test 1 of all that I have been hypothesizing (and mostly not quite believing): Can I really run a local AI model on my MacBook? If this did not work, then my project would get shut down, even before it started. So, I was full of anticipation. There&#8217;s a twilight zone between disbelief, cynicism, and hope that I&#8217;m sure every adventurer feels. I was feeling it. And, I think if nothing worked, just this feeling would be worth it. Mundane things can sometimes give us the profoundest of thoughts&#8230; huh!</p><h5>Anyways&#8230; Why Local Matters</h5><p>I&#8217;m building a tax advisor that handles sensitive financial data.</p><p>I can&#8217;t trust the cloud with: W-2s, 1099s, bank account numbers, or health expenses</p><p>So I&#8217;m keeping everything local &#8212; even the model inference. [<em>Full context in <a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant">Post 1 </a>if you&#8217;re just joining.</em>]</p><p><strong>If this is of interest - read on:</strong></p><h4>Recap</h4><p>The machine was taken care of. Refurb Mac Pro, M3, 16GB, battery cycle count under 100 - yay -sustainability, yay - budget! [<em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax">Post 2 </a>details the whole inspection saga if you missed it.</em>]</p><p>And Question # -1 was answered. [<em><a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint?r=77z576&amp;utm_campaign=post&amp;utm_medium=web">Post 3</a></em>]</p><p>Guess it was time to stop thinking and start building. </p><h4>Progress</h4><p>So like a good boy I asked AI to talk applications (because when you are building AI what else would you rather do)?. The answer was, you need TWO THINGS! A Model - and a couple of Tools.</p><p>It gave me a few choices of each  - so I went shopping, and I was consistent in my approach, i.e., I built checklists to compare and figure it out (so utterly predictable!). The final winners were: </p><p><strong>i. Model: Mistral 7B ; ii. Tool: Ollama</strong></p><p>(We&#8217;d also need Python, and a few other thing that weren&#8217;t really choices - so I&#8217;ll skip those. May be a footnote post someday.)</p><p>But it may be worth spending a minute on why I chose Mistral (because there are a few other viable options as well).</p><h5><strong>Why Mistral</strong></h5><p>Some other choices were - LLaMA 3, Phi, Gemma. All open source, all quantized versions available, all runnable locally.</p><p>My heuristics (also suggested by AI along with a bunch of other things) were:</p><ol><li><p>Size</p></li><li><p>Performance</p></li><li><p>Reasoning quality for retrieval-augmented tasks. (This matters more than general benchmark performance.)</p></li><li><p>Corporate association (Not from a big company - especially not from Facebook - personal dislike)</p></li><li><p>NO surprises (Really free - no strings attached)</p></li></ol><h4>The fun bit</h4><p>With all that done, I took this out for a spin in the real world&#8230; the rubber finally met the road!</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;22092f6a-def1-4b16-b8db-23baa50ab01e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">brew install ollama
ollama run mistral</code></pre></div><p>It&#8217;s that simple. No CUDA, no Docker, no pain.</p><p>(For a noob like me, I had to figure out where to run that code, and what happens when I do it. If you&#8217;re like me, ask AI.) </p><p>I turned off all my connections to believe that <em>it really did run offline</em>. <strong>And run it did!</strong></p><h5>First few prompts I Tested</h5><ul><li><p>What is the standard deduction for a single filer in 2024?</p></li><li><p>If I earned $480 from freelance work, do I need to report it?</p></li><li><p>What&#8217;s the difference between a 1099-NEC and 1099-K?</p></li></ul><h5>What Worked</h5><ul><li><p>Ollama was fast and lightweight</p></li><li><p>4-bit quantization made it run smoothly on 16GB RAM</p></li><li><p>Prompt results were fast (3-4s)</p></li></ul><h5>What Didn&#8217;t</h5><p>Without context documents (IRS rules), answers are generic. To improve on that front, I will need to use <strong>RAG</strong> (retrieval-augmented generation) for smarter answers</p><p><strong>Next up</strong>: I also created an architecture of the thing I am going to build, because even when I am building, I can&#8217;t stop drawing pictures to help me create my mind maps.</p><p><em><strong>Note</strong>: This thing is kinda addictive. I find myself excited and thinking about this at the oddest of times (like at the car service shop, or in the middle of the Man City v. Chelsea game). Save that for another post&#8230;</em></p><div><hr></div><p><em>This is Part 4 of an ongoing series on building a private, local AI tax assistant &#8212; one hour a week, on consumer hardware, without sending financial data anywhere.</em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">Part 1: Building a Private AI Tax Assistant: In public, on a MacBook!</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">Part 2: The Infrastructure Tax</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-blueprint">Part 3: The Blueprint</a></em></p><p><em>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</em></p><div><hr></div><p><em>I. Thinking on strategy, innovation, and philosophy &#8212; for people who think seriously about how to build things and make decisions.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.marginnotes.indranilsaha.net/p/it-actually-works-kinda?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[The Blueprint]]></title><description><![CDATA[Or: what you think about when the laptop hasn&#8217;t arrived yet and you have nothing better to do...]]></description><link>https://www.marginnotes.indranilsaha.net/p/the-blueprint</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/the-blueprint</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Wed, 08 Apr 2026 02:14:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nNiN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nNiN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nNiN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nNiN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:119181,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/192781478?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nNiN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!nNiN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55702a18-4aa8-4eaf-a166-7dae888800e8_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The machine was ordered. It hadn&#8217;t arrived yet.</p><p>Which left me with a week, no hardware to tinker with, and nothing to do but think. No code to write. No environment to set up. Just Sit, Sit, Sit, Sit&#8230;</p><p>Well, the decade old consultant in me found an outlet and got into action. The first thing a consultant does &#8212; before the deck, before the framework, before the billable hours begin &#8212; is ask the question nobody wants to slow down for. </p><p>Question #-1. What problem are we actually solving?  </p><h5>The Problem Statement</h5><p>Four things.</p><p>Read my tax documents. Understand IRS rules. Reason about my specific situation using those rules. Do all of it without my data leaving my machine.</p><p>That&#8217;s the whole project and everything else is detail dressed up as complexity. [<a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">This</a> is where I started and <a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">this</a> is how I got here.]</p><p>Once I had that, once you define the problem, then you can spot trade-offs and call better shots. Quite possible that even if I didn&#8217;t do this exercise, my subconscious mind would still do 70-80% of the trick (intuition). But enough years on the road taught me that most of projects fail here &#8212; knowing what to build before knowing what is needed.</p><p>Ain&#8217;t making that mistake! Even if the only client in the room was me.</p><h5>The Sketch</h5><p>The six-month roadmap I&#8217;d outlined at the start was good for convincing myself that this thing is possible before I had thought through whether it actually is. It was quite useful for that purpose, but probably not sufficient for building.</p><p>So I asked AI to break it down further. That gave me ten phases like an inverted building under construction - each floor below depending on the one above it.</p><p>This is the kind of sequencing that looks entirely reasonable written on a napkin and considerably more humbling when you start estimating how long each box actually takes.</p><p>And, so I drew it on a napkin (and taped it under the laptop) because that&#8217;s appropriate for the level of certainty I had - less like a commitment, more like a hypothesis. And I questioned it. </p><h5>On Plans&#8230; Of Skepticism and Honesty</h5><p>I am a planner by nature. We live in a really complex world and plans reduce the complexity to manageable heuristics. But believing in a plan is taking yourself too seriously.</p><p>A Plan is at best a thinking tool &#8212; it forces you to see the complete system before you&#8217;re too deep in one component to remember the others exist. Kind of like a map. Maps are useful even when the territory turns out to be different, which it always does.</p><p>That said, two things concern me more than the others and I&#8217;ll label them now for posterity.</p><p>Thing One: Getting my tax documents read reliably &#8212; W-2s, 1099s, and the receipts. A PDF looks like a document to a human. To a computer it is a stream of drawing instructions that happens to resemble a document. And it feels quite tricky, because there could be so many drawings. Teaching my system to read these drawings sounds time consuming. I am relying on the fact that this problem has been solved and I will find help in the corners of the www forest and not have to reinvent this wheel. Or I will come up with a shortcut, or a cheat sheet (I have one in mind). More on that later. Blah blah&#8230; Thing Two.</p><p>Thing Two: Getting a small local model to give genuinely useful tax advice &#8212; without internet access, without being specifically trained on tax data, using only what it can retrieve from IRS publications. The quality of the answer depends entirely on the quality of what the system retrieves. The technical term for what happens when retrieval goes wrong is &#8220;hallucination&#8221; or confident nonsense. I am trying to avoid confident nonsense about my taxes.</p><p>These are the longest poles in the tent. I&#8217;m budgeting more time for both than the plan suggests, which means I&#8217;m already diverging from the plan&#8230; see what I meant!</p><h5>Front-Load, Fail Fast, Dive Deep</h5><p>Here&#8217;s my actual approach, which differs from the official plan.</p><p>I&#8217;m front-loading the early phases to get a working end-to-end flow as quickly as possible &#8212; even if every individual component is rough. The goal is to feel what it&#8217;s like to ask the system a real question and get a real answer before I&#8217;ve perfected any single piece.</p><p>The plan says set up RAG before touching the documents. I feel like going straight to the documents first &#8212; because that&#8217;s where I expect the most resistance, and I&#8217;d rather find out early.</p><p>Two phases at the end of the plan &#8212; privacy and testing &#8212; are probably not phases at all. For this project, Privacy is front and center, gotta bake it in from the start or it isn&#8217;t there. Testing is the same (only it&#8217;s not specific for this project, for everything in life, &#8220;Bulid a little bit, Test a little bit.&#8221;)&#8230; Both will likely dissolve into every other phase rather than arriving as their own moment. But they&#8217;re on the plan because they deserve to be seen, and we&#8217;re not spending any more time tinkering with the plan.</p><p>That said, the back half of the timeline is where the real work lives &#8212; making each component actually reliable, handling the edge cases, closing the gap between &#8220;works on my test document&#8221; and &#8220;works on my real W-2&#8221; which, as it turns out, is printed five times side by side on a single page.</p><h5>The Long View</h5><p>At the far end of all this &#8212; if things go better than I&#8217;m currently expecting, which they may or may not &#8212; the system generates a completed, ready-to-file tax form. One I can upload directly. No accountant. No TurboTax. No data leaving my machine.</p><p>To be honest, that feels like a long stretch from where I&#8217;m standing today. </p><p>But I&#8217;ve learned not to pre-emptively cap ambition on projects that haven&#8217;t started yet. The plan doesn&#8217;t know how far this goes. And I&#8217;ve been wrong about ceilings before &#8212; occasionally in the right direction.</p><h5>Next</h5><p>The machine is live. The environment is set up. From here to there, From there to here, Funny things are everywhere. The fun is about to get funnier&#8230; </p><div><hr></div><p><em>I. Thinking on strategy, innovation, and philosophy &#8212; for people who think seriously about how to build things and make decisions.</em></p><p><em>This is Part 3 of an ongoing series on building a private, local AI tax assistant &#8212; one hour a week, on consumer hardware, without sending financial data anywhere. </em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant?r=77z576">Part 1: Building a Private AI Tax Assistant: In public, on a MacBook!</a></em></p><p><em><a href="https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax?r=77z576">Part 2: The Infrastructure Tax</a></em></p><p><em>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/p/the-blueprint?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/p/the-blueprint?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Dignity]]></title><description><![CDATA[...in the face of cheek and sarcasm... a guide to old school]]></description><link>https://www.marginnotes.indranilsaha.net/p/dignity</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/dignity</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Sat, 21 Mar 2026 19:20:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!6v54!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6v54!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6v54!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 424w, https://substackcdn.com/image/fetch/$s_!6v54!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 848w, https://substackcdn.com/image/fetch/$s_!6v54!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 1272w, https://substackcdn.com/image/fetch/$s_!6v54!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6v54!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png" width="446" height="437" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:437,&quot;width&quot;:446,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:214237,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.marginnotes.indranilsaha.net/i/191699945?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf1faa9e-6c5b-4496-b34b-ea7078a5d37e_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6v54!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 424w, https://substackcdn.com/image/fetch/$s_!6v54!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 848w, https://substackcdn.com/image/fetch/$s_!6v54!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 1272w, https://substackcdn.com/image/fetch/$s_!6v54!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945bdc7f-cb04-47a9-a65d-c58ec98500af_446x437.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Dignity, once surrendered, is rather difficult to reclaim. It slips away quietly, often in the smallest of moments&#8212;a careless remark, an unnecessary display, a willingness to trade composure for fleeting satisfaction. And though the loss may seem trivial at the time, its absence is felt long after the moment itself has passed.<br>There is a curious illusion, much indulged in modern life, that dignity is a flexible thing&#8212;something one may set aside in a moment of haste or temper, only to retrieve later without consequence.<br>I cannot say I agree.<br><br>One may apologize, of course. One may even be forgiven. But dignity is not restored by apology alone; it is rebuilt slowly, through conduct, restraint, and a renewed respect for oneself and others.<br>It is, if you will forgive the expression, rather like fine china&#8212;perfectly serviceable when intact, but once cracked, never quite the same again, however carefully mended.<br>And so, I have always believed it wiser to guard one&#8217;s dignity with vigilance. For while it may not announce its departure, it is sorely missed when gone&#8212;and exceedingly difficult to persuade back.<br><br>This thought began with this week&#8217;s geopolitical events, but&#8212;like many such reflections&#8212;found its way back to work. In the workplace, one often encounters sarcasm or clever remarks&#8212;moments that invite a response, yet test one&#8217;s ability to maintain both dignity and restraint. I find myself thinking about such things from time to time (a childhood full of such training is to blame primarily). Here are some lines that may come in handy (tried and tested):<br><br>- <s>Gentle </s>deflection: One must be grateful that wit still flourishes, even when good judgement does not.<br><br>- Mildly wounded: I had hoped for a more charitable interpretation&#8212;but perhaps I ask too much.<br><br>- Firm but civil: If there is a point to be made, I should prefer it delivered plainly rather than dressed in cleverness.<br><br>- Dry, understated: We must all make our contributions, however&#8230; distinctive.<br><br>- Respectful: I wonder if the situation may be rather more nuanced than it appears.<br><br>A thought worth comparing notes on.</p>]]></content:encoded></item><item><title><![CDATA[The Infrastructure Tax]]></title><description><![CDATA[or how to buy a refurb Mac Pro and overthink cost allocation...]]></description><link>https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/the-infrastructure-tax</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Sat, 21 Mar 2026 18:41:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CZ0p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Two weeks ago, I set out to build a privacy-first AI system. But before any of the interesting stuff could begin, I ran into the good old infrastructure question. </p><p><strong>My 2016 MacBook Air</strong></p><p>The machine I planned to use for this project was, in technical terms, cooked.</p><p>Not just slow &#8212; it was existentially compromised. It couldn&#8217;t run the latest macOS, which meant it couldn&#8217;t receive security updates, which meant I was planning to build a <em>privacy-first</em> AI system on a machine that was itself a security liability. The irony was not lost on me.</p><p>The laptop wasn&#8217;t really a project expense. It was a deferred necessity that the project finally forced me to confront. Any CFO will tell you when you&#8217;re allocating costs, be honest about what&#8217;s <em>actually</em> driving the spend. The project, in this case, gets only partial credit.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CZ0p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CZ0p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CZ0p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:103727,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://sahaindranil.substack.com/i/191684008?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CZ0p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!CZ0p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66dac8bc-f601-4122-9bfa-2382b4f59848_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Buying only what you need</strong></p><p>I did not want to buy a new Mac. Because I didn&#8217;t <em>need</em> one. </p><p>New MacBooks are extraordinary machines. They&#8217;re also priced for people who either expense them or derive some psychological satisfaction from unboxing theater. I am neither.</p><p>What I needed was a machine capable of running local LLMs &#8212; specifically something with Apple Silicon, at least 16GB of unified memory, and enough storage to not make me anxious. A refurbished MacBook Pro M3 checked every box at roughly half the price of new. Running a local language model has specific hardware requirements that rule out some machines. If you want to understand why 16GB of unified memory matters more than the chip generation, that's in the appendix.</p><p>The math wasn&#8217;t complicated. The harder part was trusting the process &#8212; because buying a refurb computer from a marketplace you&#8217;ve never used, for a machine you&#8217;ve never owned, based on specs you&#8217;re partly inferring, requires something most consumer decisions don&#8217;t: <em>actual due diligence.</em></p><p><strong>Due diligence</strong></p><p>I&#8217;ve noticed this weird thing, people who would never skip steps on a business decision routinely buy technology the way they buy produce &#8212; by feel, and with no recourse plan. A $50,000 business decision gets a due diligence checklist, a legal review, and a week of scrutiny &#8212; as it should. But an $1000 laptop &#8212; which you will use for eight hours a day, every day, for the next four years &#8212; gets a glance and a gut feeling.</p><p>I did not do that.</p><p>I researched Back Market&#8217;s reliability track record, read refurb grading standards, developed (&#8230;as in, had AI do it) an inspection protocol covering battery health, hardware specs, physical condition, port functionality, and built-in diagnostics. And, I documented everything&#8230; photographically.</p><p>The actual thing took about forty minutes. The machine arrived. Battery cycle count: under 100. Specs: exactly as listed. Condition: better than &#8220;Fair&#8221; suggested. Result: a fully capable M3 MacBook Pro for the price of a mid-tier Windows machine.</p><p>Forty minutes on a decision that shapes every working hour for the next four (maybe, ten) years seems, on reflection, like the bare minimum.</p><p>The inspection checklist is in the appendix below &#8212; if you&#8217;re ever buying refurb mac, use it.</p><p><strong>What this actually cost </strong></p><p>The laptop was ~50% of new retail. It did cost me my time - roughly 4 hours of research and inspection. And, there&#8217;s obviously the opportunity cost of not starting the project for two weeks.</p><p>But I think the right way to think about this cost is that: a portion belongs to the project, a portion belongs to the long-overdue hardware refresh, and zero of it belongs to any illusion that this was optional. The 2016 machine was a security problem waiting to become another story. The project just forced the timeline.</p><p>Sometimes the infrastructure <em><strong>is</strong></em> the decision.</p><div><hr></div><p><strong>Next up</strong></p><p>The machine was ordered. It hadn&#8217;t arrived yet&#8230;</p><p>Which left me with a week and nothing to do but think &#8212; about architecture, sequencing, and whether this project was actually as straightforward as I&#8217;d convinced myself it was. Well, waiting is underrated. The plan that came out is worth its own post. Until next time&#8230;</p><div><hr></div><p><em>If you&#8217;re following along and want the full hardware inspection checklist &#8212; what to check, what thresholds to use, and when to return immediately &#8212; it&#8217;s in the appendix below.</em></p><div><hr></div><h4>Appendix 1: System requirements for running local LLMs on Mac</h4><p><em>Why this machine, and not just any machine.</em></p><p>Buying a refurb Mac for general use is straightforward. Buying one to run local AI models requires a few additional considerations &#8212; because not all Apple Silicon is created equal for this purpose.</p><p><strong>The minimum bar for this project:</strong></p><p>Requirement Minimum: Chip - Apple Silicon (M1 or later) | M3; Unified Memory  8GB (constrained) | 16GB; Storage: 256GB (tight) | 1TB; macOS: Monterey 12+ | Latest</p><p><strong>Why these numbers matter:</strong></p><p><em>Unified memory</em> is the critical variable. Unlike traditional laptops where CPU and GPU have separate memory pools, Apple Silicon shares one pool across both. Local LLMs load their model weights into this memory &#8212; a 7B parameter model (like Mistral 7B) requires roughly 4&#8211;8GB depending on quantization. At 8GB total, you&#8217;re running the model and your operating system in a constant negotiation for space. At 16GB, you have room to work.</p><p><em>Storage</em> matters more than people expect. A single quantized model can run 4&#8211;8GB. If you plan to experiment with multiple models &#8212; which you will &#8212; 256GB fills up faster than feels reasonable.</p><p><em>The M3 specifically</em> isn&#8217;t required &#8212; an M1 or M2 with 16GB would serve the project equally well, and would likely be cheaper on the refurb market. The M3 was available at the right price point. Don&#8217;t over-optimize for the latest chip generation.</p><p><strong>What won&#8217;t work:</strong></p><ul><li><p>Intel Macs: Ollama technically runs, but performance is poor enough to be discouraging. Not recommended.</p></li><li><p>8GB unified memory: Possible for basic experimentation, but you&#8217;ll feel the ceiling quickly. Acceptable for testing the concept; limiting for sustained use.</p></li><li><p>Pre-Monterey macOS: Several dependencies won&#8217;t install cleanly.</p></li></ul><p><strong>The practical implication:</strong></p><p>If you&#8217;re following this project and considering building something similar, the refurb market for M1/M2 MacBook Pros with 16GB is currently the best value entry point. You don&#8217;t need new. You don&#8217;t need M3. You need Apple Silicon and 16GB.</p><h4>Appendix 2: Inspection checklist</h4><p><em>(The nerdy part. Skip if you trust your instincts. Don&#8217;t trust your instincts.)</em></p><p><strong>Before you do anything:</strong> Photograph everything on arrival. Box, accessories, all sides of the machine. Serial number. This is your evidence if anything goes sideways.</p><p><strong>Battery:</strong> Apple menu &#8594; System Report &#8594; Power. Look for cycle count (under 100 is excellent, under 300 is acceptable), condition (&#8221;Normal&#8221;), and full charge capacity (85%+ of design capacity). Anything worse: negotiate or return.</p><p><strong>Specs verification:</strong> Apple menu &#8594; About This Mac. Confirm chip, RAM, and storage match exactly what you paid for. Screenshot it. Discrepancy = grounds for return, full stop.</p><p><strong>Physical inspection:</strong> Screen on and off (dead pixels, coating wear, bright spots), keyboard and trackpad feel, hinge smoothness, port integrity. Test every port with an actual device &#8212; don&#8217;t assume.</p><p><strong>Diagnostics:</strong> Restart, hold Power until startup options appear, Command+D runs Apple&#8217;s built-in hardware test. &#8220;No issues found&#8221; is the only acceptable result. Optional: CoconutBattery for detailed battery analysis, Blackmagic Disk Speed Test to confirm SSD performance.</p><p><strong>Return policy:</strong> Back Market offers 30-day returns and a 1-year warranty. Keep all packaging until you&#8217;re certain you&#8217;re keeping the machine. Document everything through their platform &#8212; not email, not phone.</p><p>Immediate return triggers: &#8220;Service Recommended&#8221; battery, mismatched specs, screen damage, non-functional ports, non-genuine parts warnings in macOS.</p><div><hr></div><p><em>This is Part 2 of an ongoing series on building a private, local AI tax assistant &#8212; one hour a week, on consumer hardware, without sending your financial data anywhere.</em></p>]]></content:encoded></item><item><title><![CDATA[Building a Private AI Tax Assistant: In public, on a MacBook!]]></title><description><![CDATA[Why on earth? Is It Possible? How Long Will It Take? What Will It Cost?]]></description><link>https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/building-a-private-ai-tax-assistant</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Tue, 10 Mar 2026 12:39:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mB_o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>WHY on earth would you want to do that?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mB_o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mB_o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mB_o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/def1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26558,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://sahaindranil.substack.com/i/190500692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mB_o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!mB_o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdef1275c-dbd8-4f4d-9110-c9fe6eaf8412_500x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>AI is consuming everything around us&#8202;&#8212;&#8202; and on the face of it, it smells like progress, and most probably it is, but, and here it comes, the ubiquitous BUT, it bothers me how quickly we are giving up on our personal data to gain a little bit of advantage. So, I set out on a personal project: to build a private AI assistant that can help with tax preparation using my own financial data&#8202;&#8212;&#8202;without sharing that data with public models or the cloud.</p><p>In this day and age of ever evolving cyber attacks, which even the biggest companies around the world struggle to prevent, sharing my sensitive data with outside consultants makes me quite uneasy. One could argue &#8220;why do you think you are special?&#8221;, and &#8220;you are just not interesting enough&#8202;&#8212;&#8202;no hacker worth the salt will be interested in your information specifically&#8221;.&nbsp;</p><p>Still combine that with the thought &#8220;why do I pay tax accountants to fill up a form that I myself can fill up?&#8221; and &#8220;I have a pretty good B-school degree, majoring in, wait for it, Finance, I should be able to do this&#8221;. But I don&#8217;t stay up to date with tax laws and sometimes work gets crazy around tax days (just Murphy&#8217;s Law!). So I need help. And when I read about agentic AI, it seemed like the perfect solution. BUT&#8230; if I use just any available agent, my data still goes out into public models, and I don&#8217;t trust these startup-y things to keep my data safe.</p><p>Also, there is the adventure: Can I really do this on a MacBook&nbsp;, with just one hour per week, and without breaking the bank?</p><p>Just for background, I&#8217;m not a techie by any stretch of imagination. I used to be one a very, very, long time back. But not any longer. I just like to dabble and tinker around with the proverbial &#8220;what if&#8230;&#8221; That, plus heard all the buzz about machines coding, and thought, so why not take this idea out for a ride and see how far it goes&#8230;</p><p>Here&#8217;s the breakdown of what I&#8217;m learning, planning, and building.</p><h4>The Idea</h4><p>I&#8217;m building a tax assistant that can:</p><p>- Read my W-2s, 1099s, and expense receipts&nbsp;</p><p>- Reason about eligibility for deductions or credits&nbsp;</p><p>- Give advice based on IRS rules&nbsp;</p><p>- Do it entirely offline, keeping my financial data private</p><h4>Can I Build This on a&nbsp;MacBook?</h4><p>Surprisingly&#8202;&#8212;&#8202;yes.</p><p>Tools like Ollama, LlamaIndex, and Streamlit make it possible to run local models like Mistral 7B or LLaMA 3 directly on my MacBook. By using quantized models, I&#8217;m able to get decent performance even without a GPU.</p><h4>What If I Only Have 1 Hour per&nbsp;Week?</h4><p>I mapped out a 6-month roadmap using just 1 hour per week, breaking it down into phases:</p><p>- Month 1: Setup local LLM + basic Q&amp;A&nbsp;</p><p>- Month 2: Add PDF parsing (W-2s, 1099s)&nbsp;</p><p>- Month 3&#8211;4: Apply simple tax logic (deduction thresholds, filing status rules)&nbsp;</p><p>- Month 5&#8211;6: Build a simple RAG pipeline and Streamlit UI&nbsp;</p><p>With focus and consistent micro-progress, it&#8217;s totally doable.</p><h4>What Will It&nbsp;Cost?</h4><p>So far, almost everything is open source. My only real &#8220;costs&#8221; are:</p><p>- Local compute power (already owned)&nbsp;</p><p>- Electricity (~$10/month max)&nbsp;</p><p>- Time (the real investment)&nbsp;</p><p>If I were to add GPU cloud compute, that might add $50&#8211;$200/month, but so far I&#8217;m staying local.</p><h4>What&#8217;s Next?</h4><p>I&#8217;m documenting the full journey on my substack (here), and posting monthly updates on LinkedIn as I go.</p><p>Coming soon (Note to self: this is a plan that is sure to be disrupted&#8230; being a planner, I know that. It&#8217;s the only thing one can say about plans with some bit of certainty, but nevertheless&#8230; here it goes):</p><p>- &#8220;How I Got an AI Model to Parse My W-2s&#8221;&nbsp;</p><p>- &#8220;Can AI Actually Understand Tax Law?&#8221;&nbsp;</p><p>If you&#8217;re building something similar or have any questions/ideas to share, I&#8217;d love to hear from you. Cheers!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading this article! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[First post]]></title><description><![CDATA[The Road]]></description><link>https://www.marginnotes.indranilsaha.net/p/first-post</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/first-post</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Wed, 14 Jan 2026 03:38:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C_d6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff17c8f27-7bf4-41c5-b52a-56eecdab5bfc_342x342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Any road followed precisely to its end leads precisely nowhere. Climb the mountain just a little bit to test that it&#8217;s a mountain. From the top of the mountain, you cannot see the mountain. Frank Herbert, Dune.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Indranil's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Coming soon]]></title><description><![CDATA[This is Margin Notes.]]></description><link>https://www.marginnotes.indranilsaha.net/p/coming-soon</link><guid isPermaLink="false">https://www.marginnotes.indranilsaha.net/p/coming-soon</guid><dc:creator><![CDATA[Indranil Saha]]></dc:creator><pubDate>Wed, 14 Jan 2026 03:04:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C_d6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff17c8f27-7bf4-41c5-b52a-56eecdab5bfc_342x342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is Margin Notes.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.marginnotes.indranilsaha.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.marginnotes.indranilsaha.net/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item></channel></rss>