<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Bhavya Kashyap | Blog</title>
<link>https://www.bhavyakashyap.com/blog</link>
<description>Writing by Bhavya Kashyap about technology, systems, AI, startups, and other things worth thinking about.</description>
<language>en-us</language>
<atom:link href="https://www.bhavyakashyap.com/blog/rss.xml" rel="self" type="application/rss+xml" />
<lastBuildDate>Wed, 14 Oct 2026 00:00:00 GMT</lastBuildDate>
<item>
<title>Venture capital is booming. For whom?</title>
<link>https://www.bhavyakashyap.com/blog/venture-capital-is-booming-for-whom</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/venture-capital-is-booming-for-whom</guid>
<pubDate>Wed, 14 Oct 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>Record U.S. venture investment is concentrated in AI and large funds. That is a very different story from an easier market for most founders.</description>
<content:encoded><![CDATA[<p>U.S. venture investment reached <a href="https://nvca.org/pitchbook-nvca-venture-monitor/"><strong>$515.8 billion through September</strong></a>, already above any previous full year. That's a lot of money. It is also a slightly frustrating number to read if you're a founder trying to work out whether fundraising has actually gotten easier.</p>
<p>AI companies received 82.7% of the deal value. The remaining 17.3% was split across everything else. Even that distinction is too broad, because an enormous round for a model company and a first check into a small AI startup both end up in the same category.</p>
<p>The conversation around venture tends to swing between “funding is back” and “funding is dead.” I don't find either particularly useful. A record tells me how much money moved. It doesn't tell me how many founders had a realistic chance of receiving any of it.</p>
<p><em><strong>The biggest rounds tell us surprisingly little about everyone else</strong></em></p>
<p>The biggest AI companies can raise sums that used to be associated with public markets. Their capital needs are real: computing infrastructure, research, talent, and distribution are expensive. A large round in that category can move the total for an entire quarter.</p>
<p>That doesn't tell us much about a seed-stage healthcare startup, a hardware company, or an enterprise software team without an obvious AI label. Even within AI, money flowing to a handful of model and infrastructure companies doesn't mean every application startup can raise easily.</p>
<p>If I'm trying to raise a seed round, I care about whether investors who understand my category are writing checks at that stage. I care about what evidence they expect and whether the company I want to build fits the outcomes they need. The industry can deploy another hundred billion dollars without changing those answers very much.</p>
<p><em><strong>The investor side is concentrated too</strong></em></p>
<p>The same <a href="https://nvca.org/pitchbook-nvca-venture-monitor/"><strong>PitchBook-NVCA Venture Monitor</strong></a> reports that funds of $500 million or more received 78.1% of U.S. VC fundraising dollars through Q3, despite making up just 6% of funds closed. First-time funds received about 4.5%.</p>
<p>That matters because a smaller fund can have a different set of interests from a very large one. A check or an eventual exit that would be meaningful to one fund might barely register for another. A newer manager may also have a different network or a reason to spend time in a category that established firms have overlooked.</p>
<p>None of that makes a first-time manager automatically better. It does mean that concentrating fundraising in large, established firms can change the range of companies venture is set up to support. It also doesn't mean a useful business has no financing options. Revenue, angels, smaller funds, and other sources of capital still exist. But “there is more venture money than ever” is a poor substitute for understanding which of those options actually fits.</p>
<p><em><strong>I would rather know how widely the money is reaching</strong></em></p>
<p>I'd rather know how many companies are raising a first round, how many get to a second, and whether that is happening across a wider range of sectors. I'd also want to know whether exits are returning money to investors, because that affects their willingness to commit to the next fund.</p>
<p>The total is still useful. It shows that investors are willing to commit extraordinary amounts to certain opportunities. I just think we should be much more careful about turning that into a statement about what it feels like to raise money right now.</p>]]></content:encoded>
<category>Investing</category>
<category>Startups</category>
<category>Markets</category>
</item>
<item>
<title>Physical AI will be won by boring integration</title>
<link>https://www.bhavyakashyap.com/blog/physical-ai-will-be-won-by-boring-integration</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/physical-ai-will-be-won-by-boring-integration</guid>
<pubDate>Mon, 05 Oct 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>Better robot intelligence matters, but the harder commercial test is getting robots to work reliably inside real factories.</description>
<content:encoded><![CDATA[<p><a href="https://www.reuters.com/legal/transactional/german-robot-startup-robco-hits-1-billion-valuation-ceo-moves-us-2026-10-05/"><strong>RobCo reached a $1 billion valuation</strong></a> today. The obvious story is investor enthusiasm for physical AI and its coming two-armed robot, Alfie. I'm more interested in what RobCo has been shipping around the robot.</p>
<p>Its <a href="https://docs.rob.co/releases/robflow/robflow-8-0/"><strong>RobFlow 8 release</strong></a> moved the platform onto ROS 2. It also introduced guided vision-based calibration and a beta OPC UA server that lets factory software read robot state. Those sound less exciting than a robot learning a new task. They may be closer to what gets one deployed.</p>
<p>I keep coming back to how much work a robot creates for the people who have to maintain it. You can watch a very impressive video without learning whether the factory team can recalibrate the thing themselves, or whether they have to wait for a specialist every time something changes. You also don't learn much about how it talks to the equipment and software already in the building.</p>
<p>Those details affect how much useful work the robot actually gets through. I think they will have a lot to do with which robotics companies become good businesses.</p>
<p><em><strong>Someone still has to get this working in a factory</strong></em></p>
<p>A manufacturing task sits inside a larger process. Parts arrive in a particular way. Another machine needs to know when the robot has finished. Operators need to intervene safely. Maintenance teams need to diagnose failures, replace a component, and resume without guessing what happened to the work in progress.</p>
<p>Better models can help with some of this. But if the production system cannot tell what the robot has done, or the maintenance team cannot work out why it stopped, improving the model alone leaves quite a lot unresolved.</p>
<p>RobCo's OPC UA support is a concrete example. It exposes robot information in a form that manufacturing execution and supervisory systems can consume. Its guided calibration feature addresses a different deployment problem: keeping physical movements aligned with intended positions as equipment and conditions change. I like seeing those things in a release because they address the work a customer has to do after deciding the robot is worth trying.</p>
<p>The two software pieces do different jobs too. ROS 2 is the foundation RobFlow runs on. The OPC UA server lets factory systems read information from the robot. Using ROS 2 underneath does not, by itself, make all the existing factory software understand what the robot is doing.</p>
<p><em><strong>I would want to know what the second installation looks like</strong></em></p>
<p>The first installation proves that a team can get the robot working somewhere. I'd want to know how much of that work carries over to the second customer, and the third. How much custom engineering does each site need? Can operators resolve common problems themselves? What happens to uptime once the pilot team leaves?</p>
<p>If those answers improve with each installation, the company has a way to make deployment easier as it grows. If every site needs another substantial engineering project, selling more robots may also mean taking on much more work.</p>
<p>More capable robots expand the range of tasks worth automating, which is exciting. I just think the adoption question is much more practical than a lot of the discussion makes it sound. A factory has to live with the robot after buying it. How annoying that turns out to be will matter.</p>]]></content:encoded>
<category>AI</category>
<category>Engineering</category>
<category>Startups</category>
</item>
<item>
<title>AI made writing code cheap. Review is now the bottleneck.</title>
<link>https://www.bhavyakashyap.com/blog/ai-made-writing-code-cheap-review-is-the-now-the-bottleneck</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/ai-made-writing-code-cheap-review-is-the-now-the-bottleneck</guid>
<pubDate>Mon, 28 Sep 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>Coding agents can produce more changes than a team can thoughtfully absorb. Engineering leaders need to design for verification.</description>
<content:encoded><![CDATA[<p>I can now ask an agent to implement an idea and come back to a pull request. That's useful. It also means I can create work for a reviewer much faster than I could before.</p>
<p>That changes how I think about the time agents are saving. Getting a first implementation used to take enough effort that it naturally limited how many changes a team could have in flight. Now I can get to that point much faster. Someone still has to understand the change and decide whether it belongs in the system.</p>
<p>A <a href="https://arxiv.org/abs/2603.15911"><strong>study of 278,790 review conversations</strong></a> across open-source projects found that human reviewers exchanged 11.8% more rounds on AI-generated code than on human-written code. That's one study, and open-source review is not every company's workflow. But the direction makes sense to me. A plausible implementation can still miss the reason a system works the way it does.</p>
<p><em><strong>The same people still have to review all of this</strong></em></p>
<p>Imagine five engineers each using agents to produce twice as many pull requests. If the team still has the same two people who understand the tricky parts of the architecture, those people become the queue. The team may report more code written while changes spend longer waiting, or while reviewers skim to keep up.</p>
<p>I don't think asking those engineers to read faster gets us very far. We have to make the changes easier to evaluate. A pull request should say what behavior is meant to change, what constraints matter, how it was tested, and what could break. Smaller changes help, but only when each one has a coherent purpose. Ten tiny PRs with a hidden dependency between them can be harder to review than one clear change.</p>
<p>Tests and static checks can take some work off the human reviewer. They cannot decide whether a new abstraction fits the product, whether an edge case matters to customers, or whether a migration will be safe in production. A passing test suite is useful evidence, but I would still want someone who understands the system to examine those decisions.</p>
<p><em><strong>I would want more of the thinking to happen before the code</strong></em></p>
<p>When an agent is given a vague request, the reviewer can end up working out the requirements after the implementation already exists. At that point, someone has to explain why the code needs to change, and then review the next version too. We have made producing the first version faster without necessarily reducing the work needed to agree on what it should do.</p>
<p>For consequential changes, I'd rather have the engineer specify the expected behavior, boundaries, and failure cases before implementation. Give the agent the existing patterns to follow. Require evidence for claims like “backward compatible” or “safe to retry.” Then use review to examine the decisions that remain, rather than reconstructing what the author intended from a diff.</p>
<p>This also changes how I'd measure the benefit of coding agents. Lines written and pull requests opened tell me very little. I'd look at time from idea to a change safely running in production, review wait time, rework, incidents, and how often the same senior engineers are pulled into every decision.</p>
<p>I would be fairly skeptical of a productivity claim that stops at how much more code the team is producing. If the same people are spending more time reviewing, answering questions, and fixing problems afterward, some of the work has simply moved. I want to know whether the team can get a useful change into production more easily, and whether maintaining it becomes easier too.</p>]]></content:encoded>
<category>AI</category>
<category>Engineering</category>
<category>Engineering Leadership</category>
</item>
<item>
<title>AI agents are relearning what payments already learned</title>
<link>https://www.bhavyakashyap.com/blog/ai-agents-are-relearning-what-payments-already-learned</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/ai-agents-are-relearning-what-payments-already-learned</guid>
<pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>What payment systems already know about uncertainty, idempotency, partial completion, authority, and reconciliation matters even more when agents can move money.</description>
<content:encoded><![CDATA[<p>An agent submits a $5,000 supplier payment. The bank processes it, but the response never reaches the agent. If the agent retries with a new payment instruction, another $5,000 could leave the company. If it gives up and reports a failure, the finance team might arrange a second payment themselves.</p>
<p>The agent may have made the right decision to pay. The supplier is legitimate, the invoice is due, and the amount is correct. We still have a problem, because nobody on our side can yet establish what happened after the request left.</p>
<p>I spent about five years at Chime, and this is the kind of thing I find myself thinking about when I see agents taking on financial work. I want to know what happens when a response goes missing, or when one part of the task succeeds and another fails. Payments teams have spent decades dealing with those situations. Giving an agent the ability to call an API brings it into the same set of problems.</p>
<p>There are two kinds of action to account for. Credits, fee waivers, and balance adjustments can happen on your own ledger. Payouts, purchases, and transfers may also involve outside providers. A workflow can include both. Internal service calls can time out too, but with an outside provider, your own database can't establish whether the other system has committed the action.</p>
<p>The infrastructure for agents to transact is already arriving. In May, <a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-bedrock-agentcore-payments-preview/"><strong>AWS previewed AgentCore Payments</strong></a>, which lets agents pay for digital services within enforced spending limits. As agents gain access to more financial operations, I'd want the following practices built into the systems they use.</p>
<p><em><strong>A timeout does not tell us whether the money moved</strong></em></p>
<p>For a vendor or seller payout through a bank API, a timeout leaves the result unresolved. The payment could have succeeded, failed, or still be in progress.</p>
<p>The integration needs a defined way to recover. Depending on the provider, that might mean looking up the operation or retrying with the same idempotency key and unchanged request. If neither option can resolve the uncertainty safely, the operation should stay unresolved and be escalated for investigation.</p>
<p>An agent shouldn't be able to turn “I don't know what happened” into a fresh instruction to move money. The system executing the transfer needs to enforce that distinction, including when another agent takes over the work.</p>
<p><em><strong>It has to remain the same payment when the agent tries again</strong></em></p>
<p>An idempotency key lets a provider recognize repeated attempts at the same operation. The application should create and store that identity before execution, then reuse it across retries and restarts.</p>
<p>For an invoice payment, that means retaining the link between the approved payment and its attempts even if the model describes it differently on a later run. A newly generated memo shouldn't create a second payment. A changed amount or destination requires a new authorization decision.</p>
<p>Some instructions produce several movements. A supplier payment might require funding the paying account first; a payout batch includes multiple recipients. Give each movement its own identifier linked to the approved instruction, so recovery can pick up the unfinished work.</p>
<p>Provider guarantees have limits too. Stripe, for example, <a href="https://docs.stripe.com/api/idempotent_requests"><strong>can remove idempotency keys after at least 24 hours</strong></a>. Your operation history needs to outlast the provider's retry window.</p>
<p><em><strong>Starting over can make a partial failure much worse</strong></em></p>
<p>An agent processing an order reserves inventory and charges a card, then crashes before confirming the order. Starting over could create another charge or reservation. Recovery needs the identities and outcomes of the steps already attempted.</p>
<p>Save the authorized operation durably before execution, then record each step and its result. <a href="https://docs.temporal.io/workflow-definition"><strong>Temporal's model</strong></a> is a useful reminder of why external actions still need to be safe to retry: activities run outside the replay path and can be retried.</p>
<p>The same issue appears when a supplier payment succeeds but the accounting update fails. Recovery should mark the invoice paid using the existing payment record. Restarting the entire task risks sending the money again.</p>
<p>Cash reservations need care too: release funds only once the payment is known not to have been sent or has been definitively rejected. An unresolved payment may already have consumed those funds, so releasing them could allow them to be spent again.</p>
<p><em><strong>I would want to know what “complete” actually means</strong></em></p>
<p>An internal transfer within one ledger can post its debit and credit together in a database transaction. External payments have their own lifecycles. An ACH payment marked completed can still be returned, and a successful card charge can later become a dispute.</p>
<p>The system needs to follow those later events and update its records and messages accordingly. An agent that submitted a payment should report the status it can establish, including any uncertainty about arrival.</p>
<p>For a batch of payouts, track each recipient separately. Some payments may be complete while others need attention. Recovery should continue with the unresolved items.</p>
<p><em><strong>Each agent can follow its instructions and still exceed the budget</strong></em></p>
<p>Consider a purchasing agent with a $10,000 budget. Two workers can each see that balance and each try to spend $8,000. The service executing purchases needs to check and reserve the budget atomically. Asking the model to remember the cap won't prevent that race.</p>
<p>Authority matters beyond the amount. An agent might be allowed to move money between a company's own accounts but have no authority to send it to a new beneficiary. A support agent might be allowed to waive one eligible fee, without permission to make arbitrary balance adjustments.</p>
<p>The executing service should check the source, destination, amount, currency, and permissions. Human approval needs to remain tied to those exact details across retries. Treasury transfers may also need to leave enough in the source account for upcoming obligations.</p>
<p><em><strong>We still have to check the records against what actually happened</strong></em></p>
<p>For agent-initiated payouts, match the expected movements and ledger entries against the bank's records. A batch may appear as one bank debit and many recipient payments. Fees or currency conversion can make a simple amount comparison insufficient.</p>
<p><a href="https://docs.moderntreasury.com/platform/re/reference/payment-orders"><strong>Modern Treasury separates completion from reconciliation</strong></a>: its completed event reflects bank execution, while a separate reconciled event reports the match to a posted transaction. Those are different facts for an agent to act on.</p>
<p>The <a href="https://www.consumerfinance.gov/enforcement/actions/synapse-financial-technologies-inc/"><strong>CFPB's case against Synapse</strong></a> shows the cost of inadequate records. The bureau alleged that Synapse failed to maintain accurate records of consumer funds and ensure they matched its partner banks'. The banks identified a $60 million to $90 million shortfall, and consumers lost access to their money for weeks or months.</p>
<p>Internal actions need checks too. A fee waiver or account credit should have the corresponding ledger entries even when no money moves through a bank. Differences need an owner who can correct the books, trace a transfer, or investigate with the provider.</p>
<p><em><strong>Agents make it easier to lose track of the original instruction</strong></em></p>
<p>These problems exist in conventional financial software too. Agents add another place where an instruction can be reinterpreted, regenerated after an error, or handed to a different worker. The authorization and operation history need to remain consistent through those changes.</p>
<p>I would want someone investigating a problem to be able to follow the original instruction through the attempts, the actual movement, and the accounting records. That includes seeing what remains unresolved. If a different agent picks up the task tomorrow, it should be able to find the same history.</p>
<p>This is the part I would spend more time on before giving agents broader access to financial operations. Being able to submit a payment is useful. Being able to work out what happened to it, and recover without creating another problem, is what makes me comfortable relying on the system.</p>]]></content:encoded>
<category>AI</category>
<category>Infrastructure</category>
</item>
<item>
<title>Engineering team design in the agentic coding era</title>
<link>https://www.bhavyakashyap.com/blog/engineering-team-design-in-the-agentic-coding-era</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/engineering-team-design-in-the-agentic-coding-era</guid>
<pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>AI can make code cheaper to produce without making software delivery proportionally cheaper. That changes how I think about team size, seniority, review, and ownership.</description>
<content:encoded><![CDATA[<p>There is a version of the AI coding story where engineering teams get dramatically smaller. If one engineer can run several coding agents at once, the obvious conclusion is that a four-person team should eventually be able to produce what an eight- or ten-person team used to produce. I think some version of that will be true in some environments, but I would be careful about designing an org around the assumption that code generation translates directly into engineering productivity.</p>
<p>The data is already messier than the demos. METR's <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">2025 randomized study</a> had experienced open-source developers work on repositories they knew well and found that they took 19% longer when AI tools were available, even though the developers believed AI had made them faster. METR tried to repeat the experiment with newer tools and <a href="https://metr.org/blog/2026-02-24-uplift-update/">said in February 2026</a> that the newer data was too affected by selection effects to give a reliable estimate, although it did suggest that tools had improved. Google's <a href="https://cloud.google.com/blog/products/ai-machine-learning/announcing-the-2025-dora-report">2025 DORA research</a> is more positive, finding a relationship between AI adoption and higher delivery throughput and product performance, but it also still finds a negative relationship with delivery stability.</p>
<p>That does not mean AI coding is useless. I use it constantly and it obviously changes what one engineer can attempt. It means that writing code is only one part of the production function. A model can generate a patch quickly, but someone still has to decide whether the patch solves the right problem, fits the architecture, introduces weird failure modes, can be operated in production, and should be merged at all. METR recently had maintainers review AI-generated patches that had already passed SWE-bench's automated grader and found that <a href="https://metr.org/notes/2026-03-10-many-swe-bench-passing-prs-would-not-be-merged-into-main/">roughly half still would not have been merged</a>. A 2026 longitudinal study of professional engineers also found a shift away from code creation and toward what the authors call <a href="https://arxiv.org/abs/2605.23135">supervisory engineering work</a>: directing, evaluating, and correcting AI output.</p>
<p>That is the org-design problem I find more interesting. If implementation gets cheaper but verification, architecture, product judgment, and coordination do not get cheaper at the same rate, then the scarce resources on a team move. The team should be designed around those scarce resources rather than around how many people can physically type code.</p>
<p>In the pre-AI model, it was normal to think about capacity in engineers. A squad with six engineers could take on more implementation than a squad with three, even if the relationship was never perfectly linear. With agents, the unit gets fuzzier because one engineer can have several implementation threads moving at once. But that does not mean the team can safely accept several times as much change. Review queues can get longer, test failures can multiply, architectural inconsistency can creep in, and the number of things somebody has to keep in their head can increase faster than the useful output does.</p>
<p>I think this argues for smaller teams only when the surrounding system is strong enough to support them. A mature codebase with good tests, clear service boundaries, safe deployment, useful observability, and an internal platform that makes the right thing easy is a much better candidate for a small agent-heavy team than a tightly coupled system with slow feedback and a lot of tribal knowledge. DORA's 2025 work makes a similar point: high-quality internal platforms are strongly associated with organizations getting more value from AI.</p>
<p>It also changes what I would optimize for in the humans on the team. I want engineers who can own a problem end to end, decompose it well, give an agent enough context to do useful work, recognize when the output is subtly wrong, and make good tradeoffs when the requirements are ambiguous. Technical depth still matters, but the value of judgment goes up when producing another implementation is cheap. The person who can generate five patches is less useful than the person who knows which two should exist and can tell whether either is actually safe.</p>
<p>That does not mean every team should become a collection of senior engineers. I already think <a href="https://www.bhavyakashyap.com/blog/what-senior-heavy-teams-make-harder">senior-heavy teams have their own problems</a>, and AI can make the opportunity problem worse if all of the interesting judgment work gets concentrated in the most experienced people while everyone else becomes an agent operator. Junior and mid-level engineers still need real ownership, debugging experience, design work, and chances to build taste. If we automate away every piece of work that used to teach those skills, we eventually create a team full of people who are very good at supervising systems they never learned how to build.</p>
<p>The manager and technical lead roles change too. If an engineer can have three or four agents producing changes in parallel, review capacity and change coordination become things you have to manage deliberately. I would rather have fewer concurrent changes with clear ownership than maximize the number of agents running. The goal is not to keep the model busy. The goal is to move a coherent product or system forward without creating a pile of verification debt for the humans.</p>
<p>This also changes how I would measure whether a smaller AI-native team is actually replacing the output of a larger pre-AI team. Lines of code, pull request count, and agent task completion are almost useless for this. I would look at how long it takes to get a meaningful change from decision to healthy production, how much review time it consumes, how often it gets rolled back, what happens to incident rates and support load, whether the system stays maintainable, and whether users actually get more value. If those things improve with fewer people, then the team really is more productive.</p>
<p>My guess is that the near-term win from agentic coding is not going to be "every engineering team can immediately be half the size." It is more likely that good teams can hold headcount flatter while taking on more scope, or that a small team can own something that previously would have required a larger one if the architecture and tooling are already good. In messy systems, AI may just let us produce mess faster.</p>
<p>So I would not start team design with a target headcount reduction. I would start by asking what work remains scarce after code generation gets cheap. Right now that still looks a lot like judgment, context, review, architecture, product understanding, and operational responsibility. The smallest useful engineering team is not the smallest group of people that can generate the code. It is the smallest group that can carry all of those things without quality collapsing.</p>]]></content:encoded>
<category>AI</category>
<category>Engineering Leadership</category>
</item>
<item>
<title>The web is becoming an unstable dependency for AI assistants</title>
<link>https://www.bhavyakashyap.com/blog/the-web-is-becoming-an-unstable-dependency-for-ai-assistants</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/the-web-is-becoming-an-unstable-dependency-for-ai-assistants</guid>
<pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>I liked Meta Muse more than I expected. Two weeks later, I was already running into the thing that may limit assistants like it: the web does not have to cooperate.</description>
<content:encoded><![CDATA[<p>A couple of weeks ago I tried Meta Muse and liked it more than I expected to. The UX is slick. I liked the way it handled passwords and credentials. I liked that it could keep working through a browser without making me babysit every step. The <a href="https://stripe.com/newsroom/news/stripe-helps-meta-muse-shop-with-link"><strong>Stripe Link integration</strong></a> was particularly smart. It gives Muse a way to pay across sites without handing the agent your underlying card details directly.</p>
<p>I went in somewhat skeptical because it is Meta. Meta has enough history around privacy that I am not naturally inclined to hand it more personal information (though I have technically been a W-2 employee of theirs- can’t really get more personal than that). To its credit, Muse is designed around a dedicated secure VM, encrypted credential storage, approval before sensitive actions, and controls over which services it can access. <a href="https://about.fb.com/news/2026/09/introducing-muse-personal-ai-agent/"><strong>Meta has made privacy and security a fairly central part of how it is positioning the product</strong></a>.</p>
<p>I still have reservations about trusting Meta with that much context. But as a product, I liked Muse. Then I tried to use it.</p>
<p><em><strong>Ultimately, you’re in the web’s house</strong></em></p>
<p>One of the things I asked Muse to do was close an old Etsy store of mine. This was not an ambitious task. I was doing some personal housekeeping and had an old store I no longer needed. It was exactly the kind of annoying, low-value administrative task I want an assistant to take off my hands.</p>
<p>Muse got blocked. That changed how I thought about the product pretty darn quickly.</p>
<p>The interesting part of an agent is not that it can tell me how to close an Etsy store. A chatbot could already do that. The interesting part is that I can say, or should be able to say, “Please take care of this,” and stop thinking about it. If the agent gets to the site and cannot proceed, a lot of that value disappears.</p>
<p>Muse is already running into this problem elsewhere. Less than two weeks after its launch, <a href="https://www.axios.com/2026/09/21/amazon-meta-muse-ai-agentic-shopping"><strong>Amazon blocked Muse from accessing its shopping site</strong></a>. Amazon has also taken a restrictive stance toward other third-party shopping agents. This is probably not going to be an isolated fight.</p>
<p><em><strong>I have started thinking about my own automations differently</strong></em></p>
<p>I am currently in the market for a car. I have an agent workflow that automatically checks for new listings matching what I care about and sends me the interesting ones. It is useful because I do not have to repeatedly search the same sites. I can define what I want once and let the software watch for changes.</p>
<p>A few months ago, I would have thought mostly about whether the workflow was reliable. Now I also find myself wondering how long the underlying access will continue to exist. Maybe the listing site changes its markup. Maybe it rate-limits automation more aggressively.</p>
<p>Maybe it adds a bot challenge. Maybe it decides agents are bad for its business model and blocks them outright.</p>
<p>My automation currently works. I am basically waiting for the day it does not.</p>
<p>The current generation of agents depends heavily on infrastructure they do not control. The browser is theirs. The model is theirs. The agent loop is theirs. The website is not, which matters more as agents become capable of doing useful things.</p>
<p>When bots mostly indexed the web, sites had a fairly legible relationship with them. Search engines crawled pages and sent people back- but agents are different. An agent can potentially sit between the customer and the site. It can compare products without showing the customer the full storefront. It can bypass carefully designed upsells. It can transact without the person seeing an ad. It can decide which vendors the user ever encounters.</p>
<p>From the website’s perspective, that is not necessarily an uncomplicated win. I may want my assistant to shop across twenty stores for me. Each of those stores may prefer that I arrive personally. That tension is going to matter a lot for users.</p>
<p><em><strong>Capability is not the same as usefulness</strong></em></p>
<p>A lot of AI discussion still focuses on model capability. Can the agent reason through a task? Can it use a browser? Can it fill out a form? Can it recover when something changes?</p>
<p>An agent can be perfectly capable of completing a task and still be unable to do it because the service on the other side refuses access. The assistant gets smarter, but the environment becomes more hostile. We may end up with agents that can theoretically do almost anything a person can do online while being permitted to do a much smaller subset of it. The growing gap between capability and permission is starting to look important.</p>
<p><em><strong>We are adopting and abandoning products incredibly quickly</strong></em></p>
<p>There is another part of this I find interesting. The agent ecosystem is moving so quickly that my relationship with software feels less durable than it used to. A new product appears. It solves something I care about. I spend a few days imagining all the workflows I can move onto it. Then a model changes, an API changes, a site blocks it, the product changes direction, or something better appears. I move again. The adoption cycle is incredibly fast, but so is the abandonment cycle.</p>
<p>That makes it difficult to know how deeply to integrate any of these products into my life. Muse is a good example. I liked it enough that I immediately started looking for boring tasks to hand over. Within days, I was also seeing the boundaries of where it could operate. That does not make Muse a bad product. It makes the environment around Muse unstable.</p>
<p><em><strong>I am not sure where this ends</strong></em></p>
<p>There are several plausible outcomes. Sites could build official interfaces for agents and decide exactly which actions they want to allow. Large assistant platforms could negotiate direct integrations one company at a time. Payments standards and identity systems could make agents more recognizable and trustworthy to websites.</p>
<p>Some sites may simply decide that third-party agents are useful distribution and welcome them. Others may insist that users interact through their own assistants. We could end up with something that looks a little like the mobile app ecosystem, where the dream of a broadly interoperable layer gradually turns into a set of controlled platforms and bilateral integrations. I do not know yet.</p>
<p>What I do know is that I am becoming more cautious about treating agent capabilities as durable. When I see an assistant perform an impressive task now, my next question is increasingly not just “can it do this?” It is “who has to keep allowing it to do this?” That feels like a much more consequential question than it did even a few weeks ago.</p>]]></content:encoded>
<category>AI</category>
<category>Product</category>
</item>
<item>
<title>KEDA gets more interesting in the accelerator era</title>
<link>https://www.bhavyakashyap.com/blog/keda-gets-more-interesting-in-the-accelerator-era</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/keda-gets-more-interesting-in-the-accelerator-era</guid>
<pubDate>Thu, 24 Sep 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>KEDA could get a lot more useful as Kubernetes gets better at scheduling GPUs and other accelerators.</description>
<content:encoded><![CDATA[<p>I used to think of KEDA as a useful answer to one pretty specific problem: CPU and memory are often bad signals for autoscaling. That still describes it. But the more I look at GPU-heavy clusters, the more I think KEDA is going to get a lot more useful.</p>
<p>KEDA is not a GPU scheduler. It does not decide which accelerator a Pod gets or where that Pod should land. It helps answer a simpler question: how much work should we be running right now?</p>
<p>For a normal web service, CPU might be good enough. For inference or batch workloads, the thing you actually care about could be requests waiting, tokens waiting, queue depth, latency, or jobs that have not started yet.</p>
<p>KEDA already works well with that kind of signal. <a href="https://keda.sh/docs/2.21/concepts/scaling-deployments/">ScaledObjects</a> can scale Deployments and StatefulSets from external events and metrics. <a href="https://keda.sh/docs/2.21/reference/scaledjob-spec/">ScaledJobs</a> can create Jobs as work shows up. If the signal you want is not built in, KEDA also supports <a href="https://keda.sh/docs/2.21/scalers/external/">external scalers</a>.</p>
<p>People are already trying this with GPUs. A recent <a href="https://www.cncf.io/blog/2026/05/27/gpu-autoscaling-on-kubernetes-with-keda-building-an-external-scaler/">CNCF post</a> used a KEDA external scaler to scale on GPU utilization, memory, temperature, and power draw.</p>
<p>I think the more interesting version is when KEDA scales on the work itself, and the cluster handles the hardware underneath it. That second part is getting better quickly. Kubernetes <a href="https://kubernetes.io/docs/concepts/resource-management/dynamic-resource-allocation/">Dynamic Resource Allocation</a> is now stable and gives the cluster a richer way to describe and allocate devices such as accelerators. Kubernetes 1.37 also made DRA-backed extended resources generally available, so workloads can keep asking for familiar resources like GPUs while DRA handles the allocation underneath.</p>
<p>A node provisioner such as Karpenter can handle another part of the problem by adding capacity when the cluster cannot place the workloads it already has. So I would not make KEDA understand the whole accelerator stack. I would let it stay focused on demand.</p>
<p>The application knows whether there is work piling up. KEDA can turn that into more or fewer Pods and Jobs. Kubernetes can figure out which hardware can run them. The node layer can decide whether more machines need to exist.</p>
<h2 id="where-this-gets-fun">Where this gets fun</h2>
<p>An inference service could scale on requests waiting instead of CPU. A batch system could create GPU Jobs as items arrive instead of keeping workers sitting around. A model with sporadic traffic could scale to zero and let expensive GPU nodes disappear when there is nothing to do.</p>
<p>It also gets more useful as clusters become less uniform. We are moving toward environments with different GPU models, partitions, memory sizes, and other accelerators rather than one big pool of interchangeable hardware.</p>
<p>KEDA does not need to understand all of that. It can ask for more work to run. The lower layers can decide how to place it.</p>
<p>There are still hard problems below that boundary. Multi-node training, gang scheduling, topology, device placement, and accelerator allocation are not things KEDA solves.</p>
<p>But that is kind of the point. KEDA can stay simple while the hardware layer gets much more sophisticated. I think that gives us a pretty nice way to build autoscaling around what the application actually needs instead of trying to make one layer understand everything.</p>]]></content:encoded>
<category>Engineering</category>
<category>Infrastructure</category>
</item>
<item>
<title>More people are built to scale than build</title>
<link>https://www.bhavyakashyap.com/blog/more-people-are-built-to-scale-than-build</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/more-people-are-built-to-scale-than-build</guid>
<pubDate>Fri, 28 Aug 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>Starting from zero and improving something that already works are different entrepreneurial skills. I increasingly think more people are suited to the second than we usually assume.</description>
<content:encoded><![CDATA[<p>I have been developing a stronger opinion over the last year: more people are probably built to scale than build. By "build," I mean the true zero-to-one version.</p>
<p>No product. No customers. No obvious distribution. Maybe not even a clearly defined problem yet.</p>
<p>You have to decide what to make, who it is for, why they should care, how to reach them, what to charge, and whether the market is real before there is much evidence to guide you. That is a very specific skill set.</p>
<p>We talk about entrepreneurship as though people are either entrepreneurial or they are not, but I think that collapses several very different capabilities into one label. Some people are unusually good at finding an idea in a messy market and turning it into something real.</p>
<p>A lot more people seem good at taking something that already has a goal, customers, constraints, and some evidence of demand, then making it better. Those are not the same job.</p>
<h2 id="zero-to-one-asks-you-to-invent-the-map">Zero to one asks you to invent the map</h2>
<p>The hardest part of starting from nothing is that almost everything is ambiguous at once. You can spend months building the wrong thing.</p>
<p>You can solve a real problem for a market that is too small. You can find a good market and still pick the wrong distribution channel.</p>
<p>You can get early users who like the product but will never pay enough for the business to work. There is no scoreboard yet.</p>
<p>Even deciding what progress means is part of the work. That is where a lot of otherwise very capable people struggle.</p>
<p>Give them a team, a target, some existing customers, a messy process, and a set of constraints, and they can make enormous progress. Give them a blank page and ask them what company should exist, and they freeze.</p>
<p>I do not think that means they are less entrepreneurial. It may mean they are better at a different phase.</p>
<h2 id="we-already-know-this-happens-inside-companies">We already know this happens inside companies</h2>
<p>This distinction is obvious when you look at larger organizations. There are people who are excellent at taking a product from 100 customers to 100,000.</p>
<p>There are operators who can improve margins, build a sales motion, make an organization more reliable, introduce better systems, or turn a chaotic process into something repeatable. There are leaders who are much better when the objective is concrete.</p>
<p>Give them a clear goal and enough room to operate, and they are very good at finding the path. This is not lesser work.</p>
<p>In many companies, it is the work that actually creates most of the value after the initial idea survives. But entrepreneurship still tends to romanticize the person who comes up with the idea in the first place. That biases people toward starting from zero even when zero is the part they are least suited to.</p>
<h2 id="browsing-small-businesses-changed-how-i-think-about-this">Browsing small businesses changed how I think about this</h2>
<p>I did not always feel this way. Part of what changed my mind was spending time looking through businesses for sale on places like Acquire.com and Flippa.</p>
<p>What surprised me was not just the volume. It was the variety.</p>
<p>There are the obvious small SaaS businesses, but there are also profitable newsletters, e-commerce stores, courses, content businesses, agencies, directories, and tiny service businesses. I even saw tarot reading businesses.</p>
<p>That matters because it broadens the idea of what "buying a business" can mean. I used to think about acquisition entrepreneurship mostly in terms of buying a traditional small business or doing a search fund.</p>
<p>But there is a much wider range of businesses where the core question is not "can I invent something from scratch?" It is "can I understand why this already works and make it work better?" For some people, that is a much more natural question.</p>
<h2 id="existing-traction-changes-the-problem">Existing traction changes the problem</h2>
<p>Buying a business does not make entrepreneurship easy. You can still overpay.</p>
<p>The revenue can be fragile. The seller can be more important to the business than they admit.</p>
<p>A traffic source can disappear. Customers can churn.</p>
<p>The numbers can look much better in a marketplace listing than they do once you actually inspect the business. But you are starting with information.</p>
<p>There is already a product. There are already customers.</p>
<p>There is usually some evidence of what they are willing to pay for. There may be a distribution channel that already works, even if it is underdeveloped.</p>
<p>You can see where the bottlenecks are. That changes the nature of the challenge.</p>
<p>Instead of simultaneously inventing the market, product, and business model, you can spend more of your energy on diagnosis and improvement. Maybe the newsletter has strong engagement but weak monetization.</p>
<p>Maybe the store has good products but terrible retention. Maybe the course sells consistently through one channel and has never tried another.</p>
<p>Maybe a service business has demand but the operating process is still entirely manual. Those are scaling problems. A lot of people are very good at scaling problems.</p>
<h2 id="this-is-especially-interesting-for-people-who-want-to-be-entrepreneurial-but-do-not-have-an-idea">This is especially interesting for people who want to be entrepreneurial but do not have an idea</h2>
<p>There is a weird assumption that wanting to run a business should come with an original business idea. I do not think those things are necessarily related.</p>
<p>Someone can be great at product, operations, marketing, finance, sales, or execution without being particularly good at noticing unmet markets. They may also be bad at choosing between ideas because there is no external signal yet.</p>
<p>That person can spend years saying, "I would love to do something entrepreneurial, but I do not know what to start." Buying something changes that starting point.</p>
<p>The market and the existing customers have already made at least part of the decision. The question becomes whether you can make a good business better. That seems like a much larger pool of people.</p>
<h2 id="the-idea-is-not-that-everyone-should-buy-a-business">The idea is not that everyone should buy a business</h2>
<p>I am not trying to push people toward acquisitions. Some people genuinely love zero-to-one work.</p>
<p>Some people should absolutely start from scratch because their best advantage is seeing something before anyone else does. Some people would hate inheriting someone else's product, customers, or constraints.</p>
<p>And a bad acquisition can be much more expensive than a bad side project. I just think we treat "starting a company" as the default expression of entrepreneurial ambition when there are other paths that may fit more people.</p>
<p>The more I look at small businesses, the more obvious that feels. There are a lot of existing things that are not broken.</p>
<p>They are just underdeveloped. And there are a lot of people who may never be the person who comes up with the idea, but who would be extremely good at taking something with real demand and making it much larger, cleaner, or more durable.</p>
<p>That is still entrepreneurship. It just starts at a different point on the curve.</p>]]></content:encoded>
<category>Startups</category>
<category>Investing</category>
</item>
<item>
<title>Too much feeling, not enough restraint</title>
<link>https://www.bhavyakashyap.com/blog/my-friends-was-a-little-too-much-for-me</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/my-friends-was-a-little-too-much-for-me</guid>
<pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>I liked what Fredrik Backman was trying to do more than I liked the book itself.</description>
<content:encoded><![CDATA[<p>I wanted to like <em>My Friends</em> more than I did. There is a lot in it that should have worked for me. Louisa is a teenage artist who has bounced through foster homes and is still grieving Fish, her best friend. She sneaks into an auction just to see <em>The One of the Sea</em>, a famous painting that has meant something to her for years, gets thrown out, and then more or less accidentally meets the artist who painted it.</p>
<p>That is a great setup. The problem is that the book keeps turning every emotional beat up to maximum volume.</p>
<p>Louisa does not just meet the artist behind the painting. She meets him when he is dying. He does not just talk to her about art. He leaves the painting to her. She does not just learn who the teenagers in the painting were. She ends up traveling with Ted while he tells her the story of this intense, formative group of friends and everything they survived together.</p>
<p>And the past timeline is full of the same kind of escalation. Joar is living with a violently abusive father and starts carrying a knife because he thinks killing him may be the only way to save himself and his mother. Kimkim is closeted, isolated, and hiding drawings that he thinks nobody will understand. Ted loses his father. Christian, the school janitor who encourages Kimkim's art, dies. Ali eventually drowns. Even the story of how Kimkim gets a chance at art school involves the friends breaking into a museum to hang his work themselves.</p>
<p>Any one of those things could carry a novel. In <em>My Friends</em>, they stack.</p>
<p>Backman is clearly interested in friendship as something almost sacred: the people you meet young can save you, wound you, shape your entire life, and live inside everything you make afterward. I actually like that idea. I also liked the connection between the painting and the ordinary moment it captures. The point is not that the sea is beautiful. The point is that the people sitting together are the thing that matters.</p>
<p>But the book kept telling me how much it mattered. That was where it lost me.</p>
<p>There are scenes I probably would have found genuinely moving if the story had given them a little more room. Instead, grief leads into sacrifice, which leads into another revelation, which leads into another life-altering act of friendship. By the end I felt strangely less emotional than I did near the beginning because I had started anticipating the next attempt to devastate me.</p>
<p>I can see why people love this book. If you like Backman's very open, sentimental style, there is a lot here.</p>
<p>For me, it crossed over into melodrama often enough that I could see the machinery. I liked what <em>My Friends</em> was about more than I liked <em>My Friends</em>.</p>]]></content:encoded>
<category>Books</category>
</item>
<item>
<title>The control boundary for agents in software delivery</title>
<link>https://www.bhavyakashyap.com/blog/where-i-would-put-an-agent-in-an-argocd-pipeline</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/where-i-would-put-an-agent-in-an-argocd-pipeline</guid>
<pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>The important decision is not whether an agent can deploy. It is where the company chooses to put authority, review, and production access.</description>
<content:encoded><![CDATA[<p>If I were deciding how a company should introduce agents into software delivery, I would start with a governance question before a tooling question: where do we actually want the agent to have authority? An agent can technically be given a kubeconfig, an Argo CD token, or access to an internal deployment API. That does not mean it should be. The architecture should assume that agents will sometimes misunderstand intent, produce an incomplete change, or make a locally reasonable decision that is wrong for the larger system.</p>
<p>For that reason, I would put the agent on the proposal side of the deployment boundary rather than the production side. In a GitOps environment, the agent can interpret a request, inspect the repository and the operational context it is allowed to see, propose a narrow change, and open a pull request. CI and policy systems validate the artifact, humans or automated approval rules decide whether it should merge, and Argo CD remains responsible for reconciling the approved desired state into the cluster. This is less about distrusting AI than it is about preserving a control model the organization already understands.</p>
<p>The architecture I would want looks roughly like this:</p>
<pre class="language-text"><code class="language-text code-highlight"><span class="code-line">issue / alert / deployment request
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">         agent runner
</span><span class="code-line">              |
</span><span class="code-line">              |  proposes a change
</span><span class="code-line">              v
</span><span class="code-line">        branch + commit
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">         pull request
</span><span class="code-line">              |
</span><span class="code-line">       +------+------+
</span><span class="code-line">       |             |
</span><span class="code-line">       v             v
</span><span class="code-line">   CI checks     review / policy
</span><span class="code-line">       |             |
</span><span class="code-line">       +------+------+
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">            merge
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">        config repository
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">           Argo CD
</span><span class="code-line">              |
</span><span class="code-line">              v
</span><span class="code-line">       Kubernetes cluster
</span></code></pre>
<p>The strategic point is what is deliberately missing from the left half of that diagram. The agent does not have a kubeconfig, it does not call <code>kubectl apply</code>, and it does not need permission to call <code>argocd app sync</code>. Argo CD already knows how to watch Git and reconcile the application after the desired state changes, so I would keep execution inside that existing control plane. The <a href="https://argo-cd.readthedocs.io/en/latest/user-guide/ci_automation/">Argo CD CI documentation</a> already treats updating Git as the normal deployment path, and an explicit sync call is unnecessary when automated synchronization is enabled.</p>
<p>At the implementation level, a simple Application for this pattern could look like this:</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> argoproj.io/v1alpha1
</span><span class="code-line"><span class="token key atrule">kind</span><span class="token punctuation">:</span> Application
</span><span class="code-line"><span class="token key atrule">metadata</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">name</span><span class="token punctuation">:</span> payments
</span><span class="code-line">  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> argocd
</span><span class="code-line"><span class="token key atrule">spec</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">project</span><span class="token punctuation">:</span> production
</span><span class="code-line">
</span><span class="code-line">  <span class="token key atrule">source</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">repoURL</span><span class="token punctuation">:</span> https<span class="token punctuation">:</span>//github.com/example/platform<span class="token punctuation">-</span>config.git
</span><span class="code-line">    <span class="token key atrule">targetRevision</span><span class="token punctuation">:</span> main
</span><span class="code-line">    <span class="token key atrule">path</span><span class="token punctuation">:</span> environments/prod/payments
</span><span class="code-line">
</span><span class="code-line">  <span class="token key atrule">destination</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">server</span><span class="token punctuation">:</span> https<span class="token punctuation">:</span>//kubernetes.default.svc
</span><span class="code-line">    <span class="token key atrule">namespace</span><span class="token punctuation">:</span> payments
</span><span class="code-line">
</span><span class="code-line">  <span class="token key atrule">syncPolicy</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">automated</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token key atrule">enabled</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
</span><span class="code-line">      <span class="token key atrule">prune</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
</span><span class="code-line">      <span class="token key atrule">selfHeal</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
</span><span class="code-line">    <span class="token key atrule">syncOptions</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token punctuation">-</span> ApplyOutOfSyncOnly=true
</span></code></pre>
<p>I would probably start with <code>prune: false</code> for an agent-authored path unless there were a strong reason not to. Updating an image or changing a resource limit is one class of action; deciding that a resource should no longer exist is a different blast radius. That distinction matters at the policy level because one of the easiest mistakes in agent adoption is granting an entire capability just because the platform supports it.</p>
<p>The config repository itself does not need to become more complicated because an agent is involved. I would prefer to keep the structure boring and make the agent operate inside an explicit surface area:</p>
<pre class="language-text"><code class="language-text code-highlight"><span class="code-line">platform-config/
</span><span class="code-line">  apps/
</span><span class="code-line">    payments/
</span><span class="code-line">      base/
</span><span class="code-line">        deployment.yaml
</span><span class="code-line">        service.yaml
</span><span class="code-line">
</span><span class="code-line">  environments/
</span><span class="code-line">    staging/
</span><span class="code-line">      payments/
</span><span class="code-line">        kustomization.yaml
</span><span class="code-line">
</span><span class="code-line">    prod/
</span><span class="code-line">      payments/
</span><span class="code-line">        kustomization.yaml
</span><span class="code-line">
</span><span class="code-line">  ci/
</span><span class="code-line">    validate-agent-diff.py
</span></code></pre>
<p>For a routine deployment, the agent may only need to change an image reference. That is a much easier action to reason about organizationally than granting a generic "deploy" permission because the proposed state is reviewable before anything reaches production:</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> kustomize.config.k8s.io/v1beta1
</span><span class="code-line"><span class="token key atrule">kind</span><span class="token punctuation">:</span> Kustomization
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">resources</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token punctuation">-</span> ../../../apps/payments/base
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">images</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> ghcr.io/example/payments
</span><span class="code-line">    <span class="token key atrule">newName</span><span class="token punctuation">:</span> ghcr.io/example/payments
</span><span class="code-line">    <span class="token key atrule">newTag</span><span class="token punctuation">:</span> 9f13c42
</span></code></pre>
<p>I would also treat agent-created changes as a distinct trust class in CI. The point is not that an agent is inherently malicious. The point is that generation is cheap, so it is easy to produce a syntactically valid change whose blast radius is much larger than the request that triggered it. A company-wide agent strategy should define the kinds of changes agents are allowed to propose, not just the systems they can technically reach.</p>
<p>For example, even a very small policy check can demonstrate the boundary:</p>
<pre class="language-python"><code class="language-python code-highlight"><span class="code-line"><span class="token comment"># ci/validate-agent-diff.py</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">from</span> pathlib <span class="token keyword">import</span> Path
</span><span class="code-line"><span class="token keyword">import</span> subprocess
</span><span class="code-line"><span class="token keyword">import</span> sys
</span><span class="code-line"><span class="token keyword">import</span> yaml
</span><span class="code-line">
</span><span class="code-line">ALLOWED_PREFIX <span class="token operator">=</span> <span class="token string">"environments/prod/"</span>
</span><span class="code-line">BLOCKED_KINDS <span class="token operator">=</span> <span class="token punctuation">{</span>
</span><span class="code-line">    <span class="token string">"ClusterRole"</span><span class="token punctuation">,</span>
</span><span class="code-line">    <span class="token string">"ClusterRoleBinding"</span><span class="token punctuation">,</span>
</span><span class="code-line">    <span class="token string">"CustomResourceDefinition"</span><span class="token punctuation">,</span>
</span><span class="code-line">    <span class="token string">"Namespace"</span><span class="token punctuation">,</span>
</span><span class="code-line"><span class="token punctuation">}</span>
</span><span class="code-line">
</span><span class="code-line">changed <span class="token operator">=</span> subprocess<span class="token punctuation">.</span>check_output<span class="token punctuation">(</span>
</span><span class="code-line">    <span class="token punctuation">[</span><span class="token string">"git"</span><span class="token punctuation">,</span> <span class="token string">"diff"</span><span class="token punctuation">,</span> <span class="token string">"--name-only"</span><span class="token punctuation">,</span> <span class="token string">"origin/main...HEAD"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
</span><span class="code-line">    text<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span>
</span><span class="code-line"><span class="token punctuation">)</span><span class="token punctuation">.</span>splitlines<span class="token punctuation">(</span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">for</span> filename <span class="token keyword">in</span> changed<span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token keyword">if</span> <span class="token keyword">not</span> filename<span class="token punctuation">.</span>startswith<span class="token punctuation">(</span>ALLOWED_PREFIX<span class="token punctuation">)</span><span class="token punctuation">:</span>
</span><span class="code-line">        sys<span class="token punctuation">.</span>exit<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"agent may not modify </span><span class="token interpolation"><span class="token punctuation">{</span>filename<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword">if</span> <span class="token keyword">not</span> filename<span class="token punctuation">.</span>endswith<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token string">".yaml"</span><span class="token punctuation">,</span> <span class="token string">".yml"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token keyword">continue</span>
</span><span class="code-line">
</span><span class="code-line">    <span class="token keyword">with</span> Path<span class="token punctuation">(</span>filename<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token builtin">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token keyword">for</span> doc <span class="token keyword">in</span> yaml<span class="token punctuation">.</span>safe_load_all<span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">:</span>
</span><span class="code-line">            <span class="token keyword">if</span> <span class="token keyword">not</span> doc<span class="token punctuation">:</span>
</span><span class="code-line">                <span class="token keyword">continue</span>
</span><span class="code-line">
</span><span class="code-line">            kind <span class="token operator">=</span> doc<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"kind"</span><span class="token punctuation">)</span>
</span><span class="code-line">            <span class="token keyword">if</span> kind <span class="token keyword">in</span> BLOCKED_KINDS<span class="token punctuation">:</span>
</span><span class="code-line">                sys<span class="token punctuation">.</span>exit<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"agent may not create or modify </span><span class="token interpolation"><span class="token punctuation">{</span>kind<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">            pod_spec <span class="token operator">=</span> <span class="token punctuation">(</span>
</span><span class="code-line">                doc<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"spec"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">                   <span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"template"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">                   <span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"spec"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">            <span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">            <span class="token keyword">for</span> container <span class="token keyword">in</span> pod_spec<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"containers"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
</span><span class="code-line">                security <span class="token operator">=</span> container<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"securityContext"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</span><span class="code-line">                <span class="token keyword">if</span> security<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"privileged"</span><span class="token punctuation">)</span> <span class="token keyword">is</span> <span class="token boolean">True</span><span class="token punctuation">:</span>
</span><span class="code-line">                    sys<span class="token punctuation">.</span>exit<span class="token punctuation">(</span>
</span><span class="code-line">                        <span class="token string-interpolation"><span class="token string">f"agent may not enable privileged mode in </span><span class="token interpolation"><span class="token punctuation">{</span>filename<span class="token punctuation">}</span></span><span class="token string">"</span></span>
</span><span class="code-line">                    <span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"agent diff is inside the allowed deployment surface"</span><span class="token punctuation">)</span>
</span></code></pre>
<p>That is not meant to be a complete Kubernetes security policy. In a mature environment I would rather express durable rules in an existing policy system, but the principle is the important part: the agent gets a defined change surface. It should not be able to turn "update the payments image" into "also modify a cluster role and create a privileged container" just because both actions happen to be possible through the same repository.</p>
<p>The corresponding CI job can remain conventional, which is another reason I like this design. The organization does not have to invent a second deployment system for agent-authored changes; it can reuse the same validation machinery and add narrower controls where needed:</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">name</span><span class="token punctuation">:</span> validate deployment change
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">on</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">pull_request</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">paths</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token string">"environments/**"</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">permissions</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">contents</span><span class="token punctuation">:</span> read
</span><span class="code-line">  <span class="token key atrule">pull-requests</span><span class="token punctuation">:</span> read
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">jobs</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">validate</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest
</span><span class="code-line">
</span><span class="code-line">    <span class="token key atrule">steps</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v4
</span><span class="code-line">        <span class="token key atrule">with</span><span class="token punctuation">:</span>
</span><span class="code-line">          <span class="token key atrule">fetch-depth</span><span class="token punctuation">:</span> <span class="token number">0</span>
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Install Python dependencies
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> pip install pyyaml
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Apply agent<span class="token punctuation">-</span>specific policy checks
</span><span class="code-line">        <span class="token key atrule">if</span><span class="token punctuation">:</span> contains(github.event.pull_request.labels.<span class="token important">*.name</span><span class="token punctuation">,</span> 'agent<span class="token punctuation">-</span>authored')
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> python ci/validate<span class="token punctuation">-</span>agent<span class="token punctuation">-</span>diff.py
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Render production manifests
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
</span></span><span class="code-line"><span class="token scalar string">          kubectl kustomize environments/prod/payments > /tmp/rendered.yaml</span>
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Client<span class="token punctuation">-</span>side Kubernetes validation
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
</span></span><span class="code-line"><span class="token scalar string">          kubectl apply \
</span></span><span class="code-line"><span class="token scalar string">            --dry-run=client \
</span></span><span class="code-line"><span class="token scalar string">            -f /tmp/rendered.yaml</span>
</span></code></pre>
<p>The agent workflow itself should have Git permissions, not deployment permissions. In the simplest version it can create a branch and a pull request, but it cannot bypass branch protection or directly mutate cluster state. That keeps the model replaceable and prevents the agent framework from becoming part of the production control plane:</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">name</span><span class="token punctuation">:</span> deployment agent
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">on</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">workflow_dispatch</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token key atrule">request</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token key atrule">description</span><span class="token punctuation">:</span> <span class="token string">"What deployment change should be proposed?"</span>
</span><span class="code-line">        <span class="token key atrule">required</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">permissions</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">contents</span><span class="token punctuation">:</span> write
</span><span class="code-line">  <span class="token key atrule">pull-requests</span><span class="token punctuation">:</span> write
</span><span class="code-line">
</span><span class="code-line"><span class="token key atrule">jobs</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">propose</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest
</span><span class="code-line">
</span><span class="code-line">    <span class="token key atrule">steps</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v4
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Run deployment agent
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
</span></span><span class="code-line"><span class="token scalar string">          python tools/deployment_agent.py \
</span></span><span class="code-line"><span class="token scalar string">            --request "${{ inputs.request }}"</span>
</span><span class="code-line">
</span><span class="code-line">      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Create branch and commit
</span><span class="code-line">        <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
</span></span><span class="code-line"><span class="token scalar string">          BRANCH="agent/deploy-${GITHUB_RUN_ID}"</span>
</span><span class="code-line">
</span><span class="code-line">          git config user.name "deployment<span class="token punctuation">-</span>agent"
</span><span class="code-line">          git config user.email "deployment<span class="token punctuation">-</span>agent@example.com"
</span><span class="code-line">
</span><span class="code-line">          git switch <span class="token punctuation">-</span>c "$BRANCH"
</span><span class="code-line">          git add environments/
</span><span class="code-line">          git commit <span class="token punctuation">-</span>m "Propose deployment change"
</span><span class="code-line">          git push origin "$BRANCH"
</span><span class="code-line">
</span><span class="code-line">          gh pr create \
</span><span class="code-line">            <span class="token punctuation">-</span><span class="token punctuation">-</span>base main \
</span><span class="code-line">            <span class="token punctuation">-</span><span class="token punctuation">-</span>head "$BRANCH" \
</span><span class="code-line">            <span class="token punctuation">-</span><span class="token punctuation">-</span>title "Agent<span class="token punctuation">-</span>proposed deployment change" \
</span><span class="code-line">            <span class="token key atrule">--body "Generated from</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> inputs.request <span class="token punctuation">}</span><span class="token punctuation">}</span>" \
</span><span class="code-line">            <span class="token punctuation">-</span><span class="token punctuation">-</span>label "agent<span class="token punctuation">-</span>authored"
</span><span class="code-line">        <span class="token key atrule">env</span><span class="token punctuation">:</span>
</span><span class="code-line">          <span class="token key atrule">GH_TOKEN</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> github.token <span class="token punctuation">}</span><span class="token punctuation">}</span>
</span></code></pre>
<p>I left the model-specific implementation inside <code>deployment_agent.py</code> on purpose. Whether the company uses one model provider, an internal model, or a more elaborate tool-calling framework should not change the deployment trust model. If the AI layer can be swapped without redesigning production access, the architecture is less coupled to today's agent stack.</p>
<p>The same separation applies when the agent needs operational context. GitHub Actions can use OIDC to obtain short-lived cloud credentials instead of storing long-lived keys, and the role can be limited to the metrics, logs, or metadata the agent needs to inspect. The <a href="https://docs.github.com/en/actions/concepts/security/openid-connect">GitHub OIDC documentation</a> is useful here because the workflow identity can be constrained by repository and workflow claims rather than sharing a permanent AWS credential.</p>
<p>I would also make the approval model risk-based rather than treating every agent-authored change the same way. Image updates and bounded configuration changes may eventually be good candidates for automatic approval if the organization has enough confidence in its tests and policy layer. Cluster-scoped RBAC, namespace deletion, CRDs, network policy changes, production database changes, and anything that materially expands privileges should have a different path. The company should decide those boundaries deliberately rather than letting the agent framework define them by accident.</p>
<p>For multi-step deployments, I would keep sequencing declarative where possible instead of teaching the agent an imperative production runbook. Argo CD already supports hooks and sync phases, so a migration that must happen before an application rollout can remain part of the declared deployment:</p>
<pre class="language-yaml"><code class="language-yaml code-highlight"><span class="code-line"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> batch/v1
</span><span class="code-line"><span class="token key atrule">kind</span><span class="token punctuation">:</span> Job
</span><span class="code-line"><span class="token key atrule">metadata</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">name</span><span class="token punctuation">:</span> payments<span class="token punctuation">-</span>migrate
</span><span class="code-line">  <span class="token key atrule">annotations</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">argocd.argoproj.io/hook</span><span class="token punctuation">:</span> PreSync
</span><span class="code-line">    <span class="token key atrule">argocd.argoproj.io/hook-delete-policy</span><span class="token punctuation">:</span> HookSucceeded
</span><span class="code-line"><span class="token key atrule">spec</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token key atrule">template</span><span class="token punctuation">:</span>
</span><span class="code-line">    <span class="token key atrule">spec</span><span class="token punctuation">:</span>
</span><span class="code-line">      <span class="token key atrule">restartPolicy</span><span class="token punctuation">:</span> Never
</span><span class="code-line">      <span class="token key atrule">containers</span><span class="token punctuation">:</span>
</span><span class="code-line">        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> migrate
</span><span class="code-line">          <span class="token key atrule">image</span><span class="token punctuation">:</span> ghcr.io/example/payments<span class="token punctuation">:</span>9f13c42
</span><span class="code-line">          <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"./bin/migrate"</span><span class="token punctuation">]</span>
</span></code></pre>
<p>Argo CD runs <code>PreSync</code> hooks before applying the normal sync resources and stops the sync if the hook fails. From a leadership perspective, that is the kind of separation I want: the agent can decide that the desired state should include a migration, but the existing deployment system owns sequencing, failure behavior, and reconciliation.</p>
<p>The broader company decision is not whether agents are capable of deploying software. They are. The more important question is whether introducing agents requires us to discard the controls, auditability, and separation of responsibility we already built around production. I do not think it should.</p>
<p>If the agent is wrong in this model, the failure mode is usually a failed check, a rejected pull request, or a proposed change that never merges. That is a much better organizational default than turning a reasoning error directly into a production incident. The technical design follows from that leadership choice: let agents interpret intent and accelerate proposals, but keep production authority inside systems whose behavior and blast radius the company already knows how to govern.</p>]]></content:encoded>
<category>AI</category>
<category>Engineering Leadership</category>
<category>Infrastructure</category>
</item>
<item>
<title>When the system finally stops working for you</title>
<link>https://www.bhavyakashyap.com/blog/strangers-was-interesting-but-i-kept-wanting-more-self-awareness</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/strangers-was-interesting-but-i-kept-wanting-more-self-awareness</guid>
<pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>Belle Burden&apos;s divorce memoir is compelling, but I kept getting stuck on how often she seemed surprised by dynamics she had been unusually well equipped to question.</description>
<content:encoded><![CDATA[<p>I found <em>Strangers</em> genuinely interesting. The premise is brutal. Belle Burden is quarantining with her husband and two of their children at their house on Martha's Vineyard in March 2020 when she gets a voicemail from a stranger telling her that her husband is having an affair with his wife. By the next morning, the husband Burden had been with for twenty years tells her he wants a divorce, packs a bag, and leaves.</p>
<p>It is easy to understand why that would completely destabilize someone. What I had a harder time with was how often Burden seemed completely helpless in situations where, from the outside, she appeared unusually equipped to ask better questions.</p>
<p>She is not someone who had never encountered contracts, money, or powerful institutions. She went to Harvard Law School and worked as a corporate lawyer at Davis Polk. That does not mean she should have understood matrimonial law or predicted that her husband would leave her. But it made some of her choices harder for me to understand.</p>
<p>The prenup is the clearest example. Before they married, James pushed to change their agreement so that income earned during the marriage would remain separate unless it was deliberately put into joint ownership. Burden's own lawyer advised her against the change. She signed it anyway.</p>
<p>Then, over the course of the marriage, she used money from her family trusts to help buy their New York apartment and Martha's Vineyard house and put both properties in joint ownership. James, meanwhile, kept much of what he earned in his own name.</p>
<p>She also let him take over the family's finances. Again, I understand how these things happen inside a marriage. Trust is the point. You do not make every decision while imagining how it will look in a divorce proceeding twenty years later.</p>
<p>But Burden actually had more warning than most people do. She had a lawyer telling her the agreement was a bad idea. She had legal training herself. She knew enough to be uncomfortable with the prenup change, and by her own account she avoided talking about it with people who might have challenged her decision.</p>
<p>That is where my sympathy started running alongside frustration. The same thing happened with the book's treatment of privilege.</p>
<p>Burden is very explicit that she grew up with enormous advantages. She comes from an extremely wealthy, prominent New York family. The marriage includes a Tribeca apartment, a house on Martha's Vineyard, private schools, inherited trusts, and a level of financial insulation most people going through a divorce could not imagine.</p>
<p>She knows this. But there were still stretches where she seemed surprised by how power worked until it was being used against her.</p>
<p>The pandemic setting makes this especially visible. Her family escapes New York to an isolated house on Martha's Vineyard while hospitals in the city are overflowing. Burden acknowledges how lucky they are. At the same time, the book is so tightly centered on the collapse of her own sense of safety that the surrounding crisis often feels like scenery.</p>
<p>I had a similar reaction when she starts reexamining the women in her family after James leaves. Her grandmother and other women she grew up around had endured infidelity, silence, and unequal marriages. Burden begins to see that history differently once the same kind of betrayal happens to her. That reflection is one of the more interesting parts of the memoir, but I also kept thinking: you had been surrounded by examples of this your entire life. Why did it require your own marriage exploding before you really questioned the arrangement?</p>
<p>That is probably the contradiction at the center of the book. Burden's privilege protected her from a lot of consequences, but it may also have made certain systems feel benign because they had mostly worked for her. A husband managing the money could feel like being taken care of. A traditional marriage could feel safe. A restrictive prenup could remain theoretical. The social expectation that women absorb unpleasant things quietly could look like good manners.</p>
<p>Then the marriage ended, and all of those things suddenly looked different. One of the strongest realizations in the book is Burden's eventual understanding that what she had experienced as protection could also be control. I believed that realization. I just sometimes wished the memoir pushed harder on why someone with her education, resources, and access to advice had been so willing not to look.</p>
<p>None of that made the betrayal less awful. Her husband's behavior after the affair is cold enough that the book becomes genuinely difficult to put down. The abruptness of his departure, his refusal to give her a satisfying explanation, and the transformation from husband into legal adversary are all unsettling. I also respected that Burden does not turn him into a cartoon villain. She spends a surprising amount of time trying to understand what happened rather than simply prosecuting a case against him.</p>
<p>But I did not come away from <em>Strangers</em> thinking primarily about the danger of women trusting their husbands too much. I came away thinking about how easy it is not to question a system when that system has mostly made your own life comfortable.</p>
<p>Burden eventually questions a lot of it. I just found myself wishing she had done so before it happened to her personally.</p>]]></content:encoded>
<category>Books</category>
</item>
<item>
<title>I am not sure the SpaceX deal was good for Cursor</title>
<link>https://www.bhavyakashyap.com/blog/i-am-not-sure-the-spacex-deal-was-good-for-cursor</link>
<guid isPermaLink="true">https://www.bhavyakashyap.com/blog/i-am-not-sure-the-spacex-deal-was-good-for-cursor</guid>
<pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate>
<dc:creator>Bhavya Kashyap</dc:creator>
<description>The acquisition makes financial sense and gives Cursor enormous compute. I am less convinced it makes sense for the product Cursor had become.</description>
<content:encoded><![CDATA[<p>SpaceX <a href="https://www.reuters.com/legal/transactional/spacex-buy-anysphere-60-billion-2026-06-16/">announced plans to acquire Cursor</a> last month in an all-stock deal reportedly valuing the company at $60 billion. The strategic case is straightforward: SpaceX has enormous compute capacity, and Cursor could use that access to train stronger models more cheaply.</p>
<p>That is a real advantage. I am still not convinced the acquisition was the best move for Cursor as a product.</p>
<p>Obviously, I understand why the founders and investors would take the deal. A $60 billion outcome is an extraordinary result for a company that is only a few years old.</p>
<p>But the thing I valued most about Cursor was not that it had its own model. It was that Cursor sat above the model layer.</p>
<h2 id="cursor-benefited-from-not-having-to-pick-a-winner">Cursor benefited from not having to pick a winner</h2>
<p>One of Cursor's strongest positions was that it could simply use whatever model was best. OpenAI gets better at one kind of coding task? Use OpenAI.</p>
<p>Anthropic gets better at long-running agents? Use Claude.</p>
<p>Google ships something better? Add Gemini.</p>
<p>Cursor can train its own models where that makes sense and use third-party models everywhere else. That is a very attractive position in a market where the underlying models keep leapfrogging each other.</p>
<p>The product does not need to predict who wins the model race. It just needs to make the best models useful.</p>
<p>I think that neutrality was strategically important. Once Cursor is owned by SpaceX, which now has its own AI ambitions through xAI, that position gets more complicated.</p>
<p>Even if Cursor continues offering competing models, it is no longer an independent layer sitting above them. There is now a parent company with a very obvious interest in making its own models better and more widely used.</p>
<p>That does not mean Cursor will suddenly become a Grok-only product. It does mean the incentives have changed.</p>
<h2 id="the-compute-argument-is-compelling-but-it-cuts-both-ways">The compute argument is compelling, but it cuts both ways</h2>
<p>The acquisition announcement talks heavily about compute. Cursor says SpaceX gives it access to the largest fleet of GPUs in the world and will let it build stronger models at lower cost.</p>
<p>That matters. Model training is expensive, inference is expensive, and coding agents are increasingly doing long-running work rather than producing a few autocomplete tokens.</p>
<p>Owning or having privileged access to large amounts of compute can materially change the economics. But I am not sure Cursor needed to become part of a model company to get that benefit.</p>
<p>It could buy compute. It could sign infrastructure partnerships.</p>
<p>It could raise more money. It could continue using external models while selectively training its own. Those options may be more expensive, but they preserve something that is difficult to get back once it is gone: strategic independence.</p>
<h2 id="i-think-cursors-application-layer-may-be-more-valuable-than-its-model-layer">I think Cursor's application layer may be more valuable than its model layer</h2>
<p>There is a tendency right now to treat model ownership as the highest form of defensibility. I am not sure that is true for Cursor.</p>
<p>Cursor built an unusually good interface between developers and models. It understood codebases.</p>
<p>It built the workflows around editing, agents, context, review, and iteration. It became the place where developers could benefit from model competition without having to care very much about which company trained the model underneath.</p>
<p>That relationship with the developer is incredibly valuable. The models may become more interchangeable over time.</p>
<p>The workflow does not necessarily become interchangeable. If that happens, owning the developer surface could be more strategically important than owning another frontier model.</p>
<p>That is why selling Cursor to a company with a model agenda feels strange to me. The independent version of Cursor could have been the Switzerland of coding models. The acquired version has a home team.</p>
<h2 id="there-is-also-a-trust-question">There is also a trust question</h2>
<p>Developer tools occupy a weirdly sensitive position. Cursor can potentially see a huge amount of a company's source code, architecture, internal systems, and engineering behavior.</p>
<p>Enterprise customers already care about where that data goes and which models receive it. Adding a large parent company with its own AI business does not automatically make Cursor unsafe.</p>
<p>But it does add another question to procurement. Who ultimately controls the product?</p>
<p>What incentives does the parent company have? Will model selection remain neutral?</p>
<p>Will data boundaries remain exactly the same over time? Those questions existed before. I think acquisition makes them more salient.</p>
<h2 id="the-obvious-counterargument-is-that-independence-was-going-to-get-harder-anyway">The obvious counterargument is that independence was going to get harder anyway</h2>
<p>Cursor is competing against some of the best-capitalized companies in the world. OpenAI, Anthropic, Google, Microsoft, and others all have strong incentives to own more of the developer workflow themselves.</p>
<p>The coding assistant is becoming too important to remain a peripheral feature. An independent Cursor would have had to keep paying for models and compute while competing with the companies selling it those inputs.</p>
<p>That is not a comfortable position either. SpaceX gives Cursor capital, compute, distribution, and the ability to train models without being completely dependent on external providers.</p>
<p>I can see the strategic logic. I just think the price of that security is higher than the acquisition announcement makes it sound.</p>
<h2 id="the-founders-probably-made-an-excellent-decision-for-themselves">The founders probably made an excellent decision for themselves</h2>
<p>I want to separate two things that often get collapsed. A great acquisition outcome for founders is not necessarily the same thing as the best long-term outcome for the product.</p>
<p>Selling at $60 billion is an astonishing financial result. If I were sitting across the table from that offer, I am not going to pretend the decision would be easy to reject.</p>
<p>But from the perspective of Cursor itself, I think something important was given up. Cursor had become valuable partly because it did not need to belong to any particular model company.</p>
<p>It could be the layer that benefited no matter who won underneath. Now it belongs to one of the competitors.</p>
<p>Maybe the compute advantage ends up mattering more. Maybe Cursor becomes dramatically better because it can train models at a scale that would have been difficult independently.</p>
<p>Maybe SpaceX leaves the product unusually autonomous. All of that could happen.</p>
<p>I just think the independent position was more valuable than it looked. And unlike compute, independence is not something Cursor can easily buy back later.</p>]]></content:encoded>
<category>AI</category>
<category>Engineering</category>
<category>Startups</category>
</item>
</channel>
</rss>