Context Engineering as Narration

User profiles are stories compressed into spreadsheets. LLMs let us uncompress them. This is both a context engineering challenge and a storytelling one.

We’ve been building user profiles for a long time.

A resume is a narrative of a career. Law enforcement builds behavioral profiles to predict what suspects might do next. Shows like Mindhunter and Criminal Minds are entirely predicated on investigators constructing psychological profiles and using them to anticipate behavior (or not).

All of these profiles are narratives. They tell stories about people, with motivations, histories, and trajectories.

When we started building software, we had to flatten user profiles into rows in a database. Computers couldn’t reason about prose. They didn’t understand narrative. So we used structured data: fields, values, things they could query and aggregate. 

But now we have systems that can make sense of narrative. The question is how we make the most of these capabilities.

A user profile – both as a set of attributes and as a narrative

The user profile as we know it

We are conditioned to think of a user profile as a set of attributes. 

It might be simple: last purchase date, email preferences, customer tier. Or it might be complex: ML feature vectors, propensity scores, behavioral clusters. User profiles are usually structured, quantitative, and designed for database queries and analytics. They answer questions like “who should we target with this promotion?” or “what products should we recommend?”

This approach has been the foundation of the software ecosystem. Recommendation engines need feature vectors. Segmentation tools need categorical labels. Analytics dashboards need numbers they can aggregate and chart.

But these profiles are snapshots, not stories.

A traditional profile captures what happened, not why. Consider: your profile says a user hasn’t bought ice cream in three months. But it can’t tell you why. Did they go on a diet? Develop lactose intolerance? Move to a colder climate? Simply got bored of it?

Traditional ML can try to infer causality through revealed preferences. Maybe the user has been buying lactose-free milk, or medication for lactose intolerance. A clever feature engineer might connect those dots. But this approach may not scale. 

It’s like looking at a single frame in a comic book. You can see what’s happening in that moment, but you don’t have the panels before and after that give it meaning. 

A graphic novel would show the doctor’s visit, the dietary change, the moment of temptation at the frozen aisle. A database row just shows:

{last_ice_cream_purchase: null, days_since_purchase: 90}.
The difference between a single frame – “I won’t buy ice cream” and a more coherent narrative

LLMs thrive on narratives

Building conversational and personalized AI experiences with large language models (LLMs) allow us to switch from a stats-based user profile to a narrative-based profile. This requirement reshapes how we think about user data.

Let’s address the obvious question: why can’t we just serialize our JSON user object into the prompt? LLMs can parse structured data, after all.

They can. But narrative representation offers something structured data doesn’t.

Narrative captures causality and motivation. Compare:

“She bought the standing desk because she mentioned back pain last month”

To:

{purchased: "standing_desk", category: "furniture"}.

Narrative could also handle ambiguity gracefully. “She seems to prefer premium brands, though she’ll opt for value options when buying in bulk” reads naturally. Encoding the same nuance in structured data requires awkward confidence scores and conditional logic.

And narrative is closer to how humans think about other humans, which is precisely what we’re asking the LLM to do. The profile needs to become something the LLM can reason about, not just reference.

The UX problem

There is a significant catch. We assume that the user would be willing to tell us what they are thinking when they ignore the ice cream and buy lactose-free milk.

This implies a UX shift, not just a data representation shift. 

Clickstream data tells you what users did. Conversational UX lets them tell you why. You need to build an experience where a user feels comfortable saying “I’m looking for a standing desk because I’ve been having back pain” rather than just clicking through product pages.

Look, I know that maybe 10-20% of people might provide further context on their decisions. Nobody likes talking to bots after all. But that 10-20% is gold. And the conversational interface creates the possibility of asking follow-up questions and perhaps building understanding over multiple interactions.

This is a significant departure from traditional eCommerce, which follows a browse → click → buy pattern. We’re moving toward something more like a conversation with a knowledgeable salesperson who remembers you.

There’s a chicken-and-egg challenge here. Users share more when they see value in sharing, but the experience only improves if they share. Solving this is a design problem, not just a technical one.

Looking ahead, this shift toward narrative has implications beyond human-to-AI interactions. As we move toward agentic commerce, users’ agents will decide what parts of their narrative to share with merchant agents. A narrative-based approach opens the door to richer agent-to-agent interactions. But that’s a topic for another post.

From attributes to character descriptions

What does the shift from attributes to narrative actually look like in practice?

Instead of:

{loyalty_tier: "gold", avg_order_value: 142, preferred_category: "electronics"}

You might have:

“Sara is a loyal customer who tends to make considered purchases, typically in the $100-200 range. She gravitates toward electronics and has shown growing interest in home automation over the past six months. Her recent browsing suggests she’s researching smart thermostats, possibly triggered by a move to a new home.”

The narrative captures nuance, temporality, and implied motivation. It allows the LLM to make decisions on a richer set of data.

There is a potential short-cut here: the LLM itself can generate this narrative.

You can use an LLM to transform database rows into prose, and the same LLM (or another) to consume that narrative for personalization. The narrative becomes a kind of intermediate representation, optimized for reasoning rather than storage.

This isn’t free, of course. The LLM generating the narrative needs guidance about what matters, which means you’re still encoding domain knowledge somewhere. You’re moving complexity from feature engineering to prompt and context engineering. But the output is more flexible, and the reasoning that consumes it is more powerful.

The context engineering challenge

Creating the narrative is only the beginning. The harder problems come after.

  • Selection: Which data points matter? A user’s purchase history might have thousands of entries. What belongs in the profile right now? One direction is to distinguish between what’s relevant to the current task versus what belongs in a general standing profile. Using embedding based retrievals, graph representations of user profiles, and other techniques could all be useful here.
  • Prominence: Not all facts are equally important. How do you weight recency versus frequency versus magnitude? Do you apply some sort of “salience algorithm”? Or do you let the LLM itself determine what to emphasize based on the current context.
  • Temporality: If a user mentioned they like chocolate ice cream two years ago, is that still relevant? What if they’ve since developed lactose intolerance? Approaches here include forgetting curves inspired by memory research, explicit decay functions, and contradiction detection that notices when new information conflicts with old.
  • Evolution: As users interact with your application, how do you update their profile? What triggers an update? This might involve event-driven updates, periodic summarization, or distinguishing between explicit signals (the user told you something) and inferred ones (you noticed a pattern).

This is where context engineering comes in. Engineers and designers must determine what’s important for the LLM to know in order to serve the user well. General-purpose tools like ChatGPT, Gemini, and Claude are introducing memory features, but these are designed for general use. Domain-specific applications can do better by encoding domain-specific knowledge about what matters.

Tools like Mem0, Zep, and LangMem are beginning to address these challenges, building memory layers that handle persistence, retrieval, and evolution. I’ll explore these memory architectures in more depth in an upcoming post.

It’s worth noting that dynamic generation adds latency and cost. For high-volume applications, you’ll likely cache narratives and update them periodically or on significant events, which reintroduces some of the “snapshot” quality we’re trying to escape. LLMs may be amazing, but they still demand that we think carefully about tradeoffs.

A different kind of engineering

I believe that building personalized AI experiences is fundamentally a narrative challenge.

We need to think about users the way novelists think about characters. Not as collections of attributes, but as people with stories that are still being written.

This isn’t a trivial problem. Research shows that even frontier models struggle to track dynamic user profiles accurately. The PersonaMem benchmark, which tests whether models can maintain and update user profiles across long conversations, found roughly 50% accuracy on profile evolution tasks.

Narrative profiles aren’t universally superior. For high-frequency, low-latency decisions (fraud detection, real-time bidding), structured profiles remain the right tool. And for brand-new users, you need some data before you can narrate anything. The cold start problem doesn’t disappear. But for the growing category of conversational, personalized experiences, the shift towards a narrative and profile driven approach will be inevitable.

Footnote:
This post is part of a series of posts on building with LLMs. You might find the following posts interesting:

The Lego Model: How Tool Calling Changes the Way We Build AI Applications

“What should I read next?” seems like a simple question. But answering it well requires knowing what the user is currently reading, what they’ve finished recently, and what’s already on their list. When I built QuietReads, a book tracking app with an AI assistant, I faced a choice: pre-load all this context on every request (expensive), build complex routing logic to fetch the right data (brittle), or find a different approach entirely.

In those post, I talk about why I chose this option, the architectural implications, and the tradeoffs involved. 

Conversational Interfaces Are Not Deterministic

A lot of mid-career technologists like me still think deterministically. We reach for decision trees, map out every probable permutation, and write test cases to cover each branch. This works well for forms and structured APIs where you control the inputs.

But QuietReads has a chat interface. Users might ask:

  • “What should I read next?”
  • “I’m in the mood for something like the last book I finished, but shorter”
  • “What were my thoughts on that dystopian novel from last month?”
Asking the QuietReads assistant to recommend some books

Each query requires different context. The first needs the user’s want-to-read list. The second needs their recently finished books plus some understanding of “shorter.” The third requires searching through their notes. I couldn’t predict which context any given question would need, and I didn’t want to fetch everything every time.

The traditional approach would be routing logic. For just the first query, you might write something like:

def get_context_for_recommendation(message, user_id):
    context = {}

    if contains_recommendation_intent(message):
        context['want_to_read'] = get_want_to_read_books(user_id)
        context['recently_finished'] = get_recently_finished(user_id)

        if mentions_specific_book(message):
            book = extract_book_reference(message)
            context['book_details'] = get_book_details(book)

    # ... and this continues for every intent type
    return context

This gets unwieldy fast. Each new question type requires new routing rules. The intent detection functions themselves need maintenance. And you’re constantly guessing what context the model will need.

LLMs allow us to use a different mental model. 

Think of LLMs as expert Lego assemblers. You provide a curated set of bricks (tools), an instruction manual (your system prompt), and let the assembler determine which bricks to use and in what order. You don’t hand them every brick in existence. You give them the right pieces for the task and clear guidance on when to use each one.

Tools as Building Blocks

In QuietReads, I define “context tools” that let the AI retrieve user data as needed:

CONTEXT_TOOLS = [
    {
        "name": "get_user_profile",
        "description": (
            "Get the user's name and reading preferences. Use this when you need to "
            "personalize your response or discuss their reading interests."
        ),
        "input_schema": {"type": "object", "properties": {}}
    },
    {
        "name": "get_want_to_read",
        "description": (
            "Get books on the user's want-to-read list. IMPORTANT: Always call this "
            "BEFORE recommending any books to avoid suggesting books they already have."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "limit": {"type": "integer", "description": "Max books to return (default: 10)"}
            }
        }
    }
]


Each tool has a clear description of when to use it. The model reads these descriptions and decides which tools to call based on the user’s question.

The Agentic Loop

When the model decides to use a tool, we handle that request, execute the tool, and feed the results back. This creates a loop (simplified code below):

async def execute(self, system, messages, tools, tool_handlers, max_tokens=2048):
    response = self.client.messages.create(
        model=self.model,
        max_tokens=max_tokens,
        system=system,
        messages=messages,
        tools=tools
    )

    while response.stop_reason == "tool_use":
        tool_results = []

        for block in response.content:
            if block.type == "tool_use":
                tool_name = block.name
                tool_input = block.input

                # Execute the tool and capture result
                result = await tool_handlers[tool_name](tool_input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result
                })

        # Feed results back and get next response
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})
        response = self.client.messages.create(...)

    return response

The model might call multiple tools, or call the same tool with different parameters, or decide it has enough context after the first call. 

The loop continues until the model has everything it needs to answer. In practice, you should also enforce a maximum iteration count as a guardrail against runaway loops or unexpectedly expensive queries. When the model requests multiple tools in a single response, you can execute them in parallel for performance gains.

This code handles the happy path. Production implementations need additional safeguards: error handling when tools fail or timeout, validation of tool inputs before execution, and graceful handling when the model hallucinates a tool name that doesn’t exist.

Client and Server-side Tools

QuietReads uses two categories of tools. Client-side tools are functions I implement: when the model calls get_want_to_read, my code queries the database and returns formatted results.

Server-side tools are capabilities the AI provider offers (like the web_search tool used below). 

I enable web search so the assistant can look up recent book releases or author news. Anthropic’s infrastructure handles the search; I just control when and how it’s available:

tools:
  web_search:
    type: "web_search_20250305"
    name: "web_search"
    server_side: true
    enabled: true
    config:
      max_uses: 5  # Limit searches per request

With some prompt engineering, the model can integrate custom database queries with real-time web searches, producing responses that feel coherent to the user. 

The system prompt guides how the model synthesizes information from different sources, when to cite web results versus personal reading history, and how to maintain a consistent voice across tool-augmented responses.

Architectural Implications

It is important to recognize where determinism matters and where it doesn’t. Each tool is a testable piece of code. I can unit test get_want_to_read in isolation, verify it returns the right data, and trust it to behave consistently. What I can’t fully predict is which tools the model will call or in what order. In my work, I have found that even cheaper models like the Haiku family of models do a decent job at tool use.

This separation has practical implications. Tool descriptions are instructions the model uses to decide when to call each tool. Writing clear, specific descriptions is as important as the implementation itself. Instead of pre-loading everything a user might need, I provide minimal context upfront and let the model request more, keeping initial requests fast and reducing token costs.

And while the model chooses its tools, I still control the boundaries. QuietReads runs input guardrails before messages reach the assistant and can validate outputs before returning them to the user.

The Tradeoffs

Tool calling introduces real costs that you should weigh against your specific requirements.

  • Predictability. With static context, you know exactly what data the model sees on every request. With tool calling, the model decides what to retrieve. This makes cost and performance harder to predict. A simple question might resolve in one API call; a complex one might trigger four tool calls and five round-trips.
  • Prompt caching. Static context can benefit significantly from prompt caching, where repeated system prompts are stored and reused. Dynamic tool results change with each request, which can reduce or eliminate caching benefits. Depending on your usage patterns, this could meaningfully impact both latency and cost.
  • Quality assurance. Unit testing individual tools is straightforward, but testing the system end-to-end becomes harder. The model might call tools in unexpected combinations, or skip tools you expected it to use. Comprehensive evaluations become essential because tool calling adds non-determinism to the critical path. I’ll write more about evaluation strategies in a future post.
  • Refactoring risk. IDE tooling can automatically update function signatures across a codebase. Tool definitions live in JSON objects that describe behavior and parameters in natural language. If you change a tool’s behavior or modify its parameters, automated refactoring won’t catch the JSON definitions, and the mismatch may not surface until production. LLM-based coding agents like Claude Code handle this well, and adding tool-specific checks to code review agents helps catch these issues.
  • Latency. Each iteration of the agentic loop requires a round-trip to the API. For QuietReads, this is acceptable. For applications where response time is critical, the additional latency may be a dealbreaker.

That said, tool calling offers real advantages beyond flexibility. Token costs can decrease because the model only retrieves data it actually needs. Direct tool calls avoid the protocol overhead of intermediary layers like MCP servers. And tools create a clean separation of concerns: database migrations, API upgrades, or new data providers can happen without touching the prompt.

This pattern fits QuietReads: read-only tools, flexible latency, and context costs that exceed API overhead. Applications with side effects, strict latency, or predictable context needs may want different approaches.

Navigating a Mindset Shift

Building with tool calling requires accepting the risk of non-deterministic code execution. You cannot predict every code path. Instead of mapping out decision trees, you’re designing capabilities and constraints. You’re giving the model a well-stocked toolbox and clear guidance, then trusting it to assemble the right response.

You control what tools exist, what data they access, what the model knows about when to use them, and what guardrails prevent misuse. The model handles the dynamic orchestration that would otherwise require hundreds of lines of if/else chains.

For those of us who’ve spent years thinking in flowcharts, this shift takes practice. But once it clicks, you start asking different questions: not “what are all the paths a user might take?” but “what capabilities does the model need, and how do I describe when to use them?”

Building at the Speed of Thought

On building QuietReads, Claude Code, and the inversion in software economics

I have wanted to build QuietReads for two decades.

The idea is simple: a book tracking application that treats reading as a reflective practice rather than a social performance. Just you, your books, and an AI companion that remembers what you’ve read and can discuss it with you.

Every few years, I would sketch out the features, maybe prototype a database schema, and then abandon the project when the scope overwhelmed the time I could spare. The economics never worked. Building a full-stack application with authentication, third-party integrations, and a sophisticated AI layer would take months of focused effort. I had a day job. I had a family. QuietReads stayed in the drawer.

Then came Thanksgiving 2025. Anthropic rolled out $1000 in API credits for Max subscribers to use with Claude Code, their agentic coding tool. The Opus 4.5 model had just launched. I decided to try again.

Two weeks later, QuietReads was live.

QuietReads organizes books in a Library View

What Changed?

This wasn’t my first attempt at building QuietReads with AI tools. Last summer, I tried vibe-coding the same application using Replit, Cursor, and an early version of Claude Code running Sonnet 4. The results were miserable. The AI agents went off the rails constantly, making changes I didn’t ask for, getting stuck in loops, producing code that looked plausible but broke in subtle ways. I gave up after burning through credits and several frustrating weekends.

The difference with Opus 4.5 was stark. 

Where Sonnet 4 required constant hand-holding, Opus 4.5 understood what I was trying to build. It made architectural decisions that made sense. When I pointed it at a bug, it found the root cause rather than applying band-aids. It demonstrated genuine systems thinking: analyzing trade-offs, proposing multiple approaches with honest assessments of pros and cons, thinking through downstream implications.

Claude Code making suggestions on how to refactor the AI Assistant to make tool calling more consistent

The screenshot above shows Claude Code reasoning through three different implementation approaches for a feature, weighing simplicity against performance against pattern consistency. This is a discussion I would expect to have with a senior developer. The options made sense, and I was able to make an informed decision on how I wanted to structure a key component of the application.

I shipped a full-stack, mobile-responsive application with social login, Google Books integration, and an AI reading companion that maintains persistent memory of your reading history. The companion can engage in literary discussion, reference your previous notes, and connect themes across books you’ve read months apart. You can @mention it in any note or journal entry, and it responds with context. Everything flows into a unified timeline that weaves together notes, reading sessions, and AI conversations.

Eko, QuietReads’s default AI Assistant helps me understand Neil Postman’s work. Books in AI responses are interactive components, allowing me to add them straight to the library.

The Inversion

My experience with QuietReads is a small data point in a larger pattern. We are navigating an inversion in how software gets built.

For decades, every decision about software development has been constrained by the scarcity of labor. Whether to buy or build. Whether to refactor legacy code or start fresh. Whether to ship now or wait for more resources. 

The person has always been the limiting factor, the most expensive line item, the ever-present bottleneck. 

The language of our industry reflects this: we estimate in person-days, bill in person-hours, staff projects in person-months.

That bottleneck is fading faster than I expected.

Boris Cherny, the creator of Claude Code at Anthropic, recently revealed that he didn’t open an IDE for an entire month. Every line of code he shipped during that period (259 pull requests, 497 commits, 40,000 lines added, 38,000 removed) was written entirely by Claude Code powered by Opus 4.5.

“Software engineering is radically changing,” Cherny wrote, “and the hardest part even for early adopters and practitioners like us is to continue to re-adjust our expectations.”

I am not Boris Cherny. I don’t work at Anthropic. I don’t have access to internal builds or institutional knowledge. But my experience over the holidays rhymes with his. And I’m not alone. Developers across the industry spent the holiday break shipping projects that had languished for years, finally made tractable by the combination of Opus 4.5 and Claude Code’s improved agentic capabilities.

Lots of people had “Claude Code” moments over the holidays..

So What Does This Mean for People Like Us?

In March 2025, Anthropic CEO Dario Amodei told the Council on Foreign Relations that he expected AI to be writing 90% of code within three to six months, and essentially all code within twelve months. The industry-wide numbers haven’t hit those marks. But within certain teams and workflows, his timeline looks prescient. Cherny’s experience is evidence. So is mine.

Software engineering as we know it is going to change faster than many of us imagined. The fundamental assumptions that drive economic decisions around building software (hiring models, training investments, vendor selection, build-versus-buy calculations) will all need revisiting. The implications extend beyond individual productivity gains into questions about how power accrues to capital and compute, and what happens to labor markets when a significant category of knowledge work becomes dramatically cheaper to produce (See footnote).

Remember: the models you’re using today are the worst they will ever be.

A User Base of One

On a more personal note: I’ve enjoyed using QuietReads. It is very much an application I built for myself, though perhaps you might enjoy it too (sign up here – let me know what you think). I have a backlog of features I want to add (voice notes, OCR for capturing physical book passages, maybe a Kindle integration to sync highlights) and I’m confident I can build them quickly.

I look forward to building more applications. Maybe something to help train my recalcitrant hound dog to stop stealing food. Maybe something to help my daughters learn Gujarati.

What I know for certain is that my view of how software gets built has shifted faster than I expected. Coming to terms with the pace of improvement has required repeated recalibration.

I am equal parts excited and terrified about what comes next.


Footnote:

There has been a lot of discussion about the macro-economic implications of broad AI adoption. From Dwarkesh Patel and Philip Trammell talking about Capital in the 22nd Century, to many, many posts that swing from breathless excitement to abject terror. Maybe we may even see an acute version of Baumol’s cost disease – where a significant bump in software productivity drives up costs and inflation as lower productivity sectors raise wages to compete leading to a hyper-inflationary spiral? Or perhaps Jevon’s paradox will reign supreme and we will end up with an absolute explosion of software tools. 

What if ASI Leads to Stasis?

I recently read and reviewed Nick Harkaway’s Titanium Noir, a noir detective novel set in a world ruled by Titans, humans made immortal and superhuman through a drug called T7. Harkaway sets the book in a world that is static with technological progress frozen, and controlled by a tiny elite – the Titans. 

The Titans have every incentive to keep it that way. If you intend to live forever, you want predictability. You suppress black swan events. You prevent anyone else from accessing the technology that made you powerful.

Like all good science fiction, Titanium Noir made me think of the current moment – about ASI and what the impact of a powerful new technology might have on society.

The Accelerationist Promise

The dominant narrative around ASI assumes dynamism. 

Ray Kurzweil’s singularity. Dario Amodei’s “Machines of Loving Grace,” which imagines AI compressing a century of scientific progress into a decade. The promise is exponential takeoff: once we build superintelligent systems, growth compounds, scarcity dissolves, and we enter a post-scarcity future.

The doomers share this assumption of exponential takeoff, just with the sign flipped. Eliezer Yudkowsky’s scenarios (as laid out in “If Anyone Builds It, Everyone Dies“) and reports like AI 2027 project rapid, destabilizing change. Whether utopia or catastrophe, the shared premise is acceleration.

But is this a foregone conclusion? What if the incentives point elsewhere?

Infrastructure Investment

Trillions of dollars are being invested right now in AI infrastructure: data centers, chips, power plants. Microsoft is signing 20-year power purchase agreements. NVIDIA’s market cap rivals the GDP of mid-sized nations. The US has imposed export controls on advanced chips to China. This is concrete capital deployed by a small number of companies with the resources to play at this scale.

AI is constrained by compute, which is constrained by power, which is constrained by massive capital investment and regulatory approval. The entities building this infrastructure are building moats. And a sufficiently powerful AI system, controlled by a sufficiently small group, creates interesting incentives. 

Does it make sense to continue to invest trillions of dollars in compute? At what point is the investment enough and are the returns justified?

The Stasis Thesis

Consider an alternative scenario. ASI emerges, powerful but without agency. Think of it as a super-powered, general purpose Claude Code – but without consciousness or autonomous goal-seeking behavior. 

I think this is as plausible as the scenarios involving goal-oriented or “selfish” behavior that keep AI safety researchers up at night. 

The ASI systems in this scenario are transformative, but also controllable, and controlled by those who built and own the infrastructure.

What do they do with it?

Titanium Noir suggests an alternative: freeze the world. 

A small elite controls compute and power. A large population lives in stasis, perhaps supported by something like a Universal Basic Income, pacified and surveilled by these AI systems. 

The technology that could enable abundance instead enables control. Growth stops because those in power benefit from predictability. Black swan events are suppressed. The world becomes static.

This is dystopia in the mundane sense. A world where nothing much changes, ever, because change threatens the position of those who own the infrastructure.

AI and Capital

In late December 2025, Philip Trammell and Dwarkesh Patel published “Capital in the 22nd Century,” arguing that while Piketty was wrong about the past, he may be right about the future. 

Their thesis: once AI and robots can fully substitute for human labor, the economic logic that has historically raised wages breaks down. Capital accumulates indefinitely to those who own it. Wealth concentrates. The gains flow upward without limit.

This is pessimistic, but it still assumes dynamism. Growth continues; it just accrues to the owners of capital. 

The stasis thesis is more pessimistic. What if those who control ASI don’t want continued growth at all? Does generating shareholder returns actually matter when economic growth becomes a non-factor?

ASI could be a technology capable of suppressing and controlling everything. Those who control the infrastructure now have a tool to assert complete dominance. And if maintaining control means ASI induced stasis, then it might be a price worth paying.

The Titans of Titanium Noir froze their world because immortality makes you conservative. Infinite time horizons make you risk-averse. You stop wanting change and start wanting control. Growth itself becomes a threat.

Trammell and Patel worry about inequality spiraling upward forever. I wonder if the ceiling is lower and harder: a world frozen in place by those who got there first.

Book Review: Titanium Noir by Nick Harkaway

Titanium Noir is a noir novel first, set in an interesting world second. World-building and story take a backseat to tone and genre conventions, which is either a feature or a flaw depending on what you came for.

The main character, Cal Sounder, struck me as somewhat ridiculous: no meaningful background, no real character development, just an embodiment of the noir detective archetype. This is likely intentional, a genre conceit where the detective exists primarily as a lens through which we observe the world.

A Chandler Cast in a Strange City

At its heart, this is a murder mystery. A quiet, private man gets killed, and because the victim is a Titan, Cal Sounder gets the call. He is a private investigator who works closely with police on cases involving Titans, the ultra-wealthy elite made superhuman through repeated doses of the life-extending T7 drug. Most of the book follows Sounder as he navigates a cast of characters lifted straight from Raymond Chandler: a nightclub singer, a corrupt cop, a beautiful but neurotic woman, and so on. The core plot feels secondary to atmosphere and world. There are twists, turns, and some surprisingly violent sections, but the mystery exists in service to the setting rather than the reverse. I enjoyed some of the characters, though the plot itself fades from memory faster than the world Harkaway built around it.

The World of Stasis

What I found most compelling was thinking through the implications of a world ruled by a small cadre of superhuman Titans. They are apart from everyone else in how they look, how they act, and crucially, the time horizons that shape their thinking.

The world they rule is static, and that stasis makes perfect sense. If you intend to be immortal, you want predictability and control. You actively suppress black swan events, like widespread access to T7, because such disruptions threaten your position. This stasis manifests throughout the book: repeated references to 20th century films, archaic computing infrastructure, the absence of mobile phones. Some technologies have clearly advanced, medical facilities most notably, but these directly benefit the Titans.

If I were to construct the backstory, I would imagine T7 invented toward the end of the 20th century, with the Titans consolidating control in the early 21st. This explains the new city where they reside, built fresh for their purposes, while the rest of the world still references Brazil, Greece, Beijing, Mumbai. This is not a colony planet. It is Earth, transformed by Titan influence.

Verdict

A solid 6.5. The world stayed with me; the plot did not. I am not certain I would read a sequel if one arrives, though Harkaway clearly has ideas worth following.

A Letter to 2025

Dear Rushi,

This letter comes to you from January, 2026. I know 2024 was rough, and you are wondering about what comes next. I can tell you. Some of it will help. Some won’t. But you should know. 

On Parenting

Being a father will continue to be the hardest and the most rewarding project you take on. The highs will be high: the 5-year-old starting kindergarten, working on her reading, her delight in tales from the Indian Epics – again and again. The 3-year-old starting pre-k and developing an absolutely delightful (and maybe slightly unhinged?) sense of humor. 

The lows will involve too many sleepless nights, epic meltdowns, and becoming adept at catching puke with your bare hands so you don’t have to change the sheets for the fourth time that night. 

You will complain about how they insist on climbing into bed with you in the early hours. 

But, when they don’t, you will wake with a start and tiptoe into their room to make sure they’re okay.

There will be dancing. K-POP. So much K-POP that you will find yourself humming it while walking the dog or waiting to join a Zoom call. Sometimes you will find yourself watching YouTube videos analysing songs from K-POP Demon Hunter and wondering if they will make a sequel. I don’t know yet.

(Image: Petite gare by Isaac Levitan. Wikimedia Commons)

On Grief

Another year will pass with your father gone. The pain will sometimes recede to a background hum and sometimes it will come roaring back. 

Walking into your parents’ house will still be difficult. You’ll wait to hear him call out from his study to come look at something. Wait for the monosyllabic text asking if you’re coming for dinner that night.

Every time you look in the mirror you will see more of him reflected back. The tilt of the head. The slight pout. His impatience will show up when working with the 5-year-old on writing practice. His whimsy when making silly jokes with the 3-year-old.

The grief will settle like sediment at the bottom of a pond. Sometimes it will be disturbed: a photo that surfaces on your phone, a handwritten card found while tidying your office. 

Let it stir and let it settle. It’s a part of you now.

On Love

2025 marks fifteen years of marriage. Adventure, adversity, and now domesticity.

Things will be difficult. Having a 3 and 5-year-old makes time together reliant on the kindness and generosity of loved ones. You will make the most of those moments: a short weekend away for a wedding, a few days spent eating out and making inappropriate jokes, the regrettably few nights watching TV under the covers.

One night up in the hills of West Virginia. Looking at the fire. Drinking bourbon. Feeling like twenty-somethings again. It was only one night, but enough to remind you of what it was and what it will be. One day.

There will be arguments, clenched jaws, silent shrugs. There will be reconciliation, often commiseration over what your little tyrants have put you through. Work stress, travel, adjusting schedules, waving at each other’s planes as you cross paths at Dulles.

You will finish the year strong if tired. Your wife more beautiful than ever. You a little more haggard.

On Meaning

You will spend many evenings in a dark room waiting for your children to fall asleep. Answering for the fifth time that morning time will be in ten hours. Fighting the sentimental inner parent who wants to hold his daughter’s hand every night until she drifts off.

Those dark hours are also when you think and wonder.

You will spend hours thinking about whether you will have a job in the new year and what that job will look like. You will fret about your responsibilities to your peers, your teams, your clients. Wrestle with the importance of process versus the value of output.

You will use the same technology that threatens to upend everything. The foundation models. You’ll use them to build tools and bring ideas to life. 

Oscillating between dread, wonder, and the defiance of knowing that if you can think it, you can build it.

And underneath it all, the questions that don’t resolve: What does it mean to work when twenty years of hard-won knowledge can be summoned with a prompt? What world will your children inherit? Post-scarcity utopia or hyper-capitalist hellscape where all power and wealth accrues to capital and to compute?

You will wonder about your decision to raise your daughters in a country turning from kindness to cruelty, from embracing diversity to strident ethno-nationalism. You will wonder if they will embrace their Indian heritage or find it more expedient to lean into their ethnic ambivalence.

Those won’t be fun thoughts.

On Stillness

After all the hours spent working and reading and fretting, it will be the quiet moments that matter.

Long walks with your not-very-smart dog. Waiting for the coffee maker to stop bubbling before the first 6am call. Moments when the house is quiet, the mind is still and the body is calm.

Treat each moment like a piece of masonry, building a wall against the coming chaos.

Lean into those moments. Shelter against the storm.

You will need it.