AI 资讯
How to Choose Tech Decisions That Serve You (And the "This Must Be False" Rule)
Inspired by Nir Eyal's "beliefs are tools" framework Beliefs are tools, not truths. Tech stacks are too. Pick the ones that work for you. Most "tech debt" is actually "belief debt". We hold onto frameworks, patterns, and processes long after they stop serving the product. To build great software, we need to introduce a core rule: If a tech belief or "best practice" doesn’t solve a real problem for you right now, it must be treated as false. Here is how to audit your tech beliefs using 5 filters. 1. ARE THEY USEFUL? The real question isn’t "Is this the best tech?" It’s "Does this serve the user?" Tools are tools. Keep the ones that ship. Bad belief (Treat as False): "We need Kubernetes because it’s the industry standard." Useful belief (True for Now): "A $5 VPS serves 10k users. We’ll use K8s when we have a scaling problem, not a resume problem." If your architecture choice doesn’t make the core loop faster, cheaper, or simpler for users, it’s not serving you. Delete it. 2. ARE THEY TESTED? A useful stack holds up when the world pushes back. Pay attention to production, not the trending blog posts. Bad belief (Treat as False): "Microservices are inherently more scalable"—said before you even have 2 concurrent users. Tested belief (True for Now): "Our monolith handles 50 req/s perfectly. We’ll split services only when latency exceeds 300ms in prod." Load test it. Dogfood it. If it only works in a conference slide deck, it’s a story, not a tool. 3. ARE THEY OPEN? A tech choice you can’t change has stopped being a tool and has become a cage. Hold opinions firmly, but hold implementations loosely. Bad belief (Treat as False): "We’re a React shop forever." Open belief (True for Now): "React serves us today. If HTMX lets us ship this feature in 2 days instead of 2 weeks, we’ll use HTMX." In a famous study on hope, Curt Richter’s rats swam for 60 hours when they believed rescue was coming. Your team will grind for years on a legacy stack if they believe it can actually be r
AI 资讯
Maybe Coding Agents Don't Need a Bigger Memory. Maybe They Need Continuity.
A practical reflection on why coding agents lose the thread between sessions, and why the repository itself is the right place to preserve it. I used to think the problem was memory. That was the obvious diagnosis. Every new coding-agent session started with the same ritual. Open the repository. Read the README. Inspect the project structure. Search for the files that looked important. Reconstruct the task. Guess which commands mattered. Ask again what had already been tried. Then do the actual work. Sometimes. Because a lot of the work was not work. It was orientation. A coding agent can have a large context window and still lose the operational thread. It can have chat history and still fail to know what happened in the last run. It can retrieve semantically similar notes from a vector store and still miss the one fact that mattered: this command already failed. the previous session stopped here. this file looked relevant, but it was a dead end. the validation was not actually run. One day I stopped thinking about the problem as "agent memory". That word was too broad. Too attractive. Too dangerous. Because once you say memory, the temptation is to build a bigger one. A bigger context window. A bigger note store. A bigger vector database. A bigger archive of everything the agent has ever seen, said, touched, generated, or vaguely implied. That sounds powerful, but it is also how you build a very expensive junk drawer. Context is not continuity Context is what the agent has available now. Continuity is what lets the next execution continue from what actually happened before. Those are not the same thing. Long context helps while a session is alive. It gives the model more text to work with. More files. More prior messages. More implementation details. More room. Although it is really useful it does not automatically produce continuity. When the session ends, gets compacted, moves to another tool, switches from one coding agent to another, or simply starts tomorrow
开发者
ZenQL, KISS And DRY.
imagine you are working in a large codebase. you need to fetch different kinds of data and transforming them, grouping them or sorting them. lets take a closer look at Sorting and Heaps in golang Specifically. we already familiar with heaps and its important interface. the Heap.Interface. a very performant and impressive implementation of heaps and its sorting functionality. type Interface interface { sort . Interface Push ( x any ) // add x as element Len() Pop () any // remove and return element Len() - 1. } as a programming language, it couldnt be done better than what it is today. but most of the time we might not need to implement all the interface items. dont get me wrong the functionalities should exist but mostly all that matters for us is that how the sorting will be done. ZenQL's Implementation In the latest version take advantage of sorting and heaps functionality. in a fast and agile way! result := From ( personList ) . Where ( func ( person Person ) bool { return person . Active == true }) . CollectSorted ( func ( person Person , person2 Person ) bool { return person . Identifier < person2 . Identifier }, true ) In the code snippet above we perform a sort on our collections using the thor engine very easily. we just express our desire about how the sorting needs to be done and wether its ascending or descending. and other functionalities are implemented as below: type Sortable [ T any ] struct { Items [] T less func ( a , b T ) bool desc bool } func ( h Sortable [ T ]) Len () int { return len ( h . Items ) } func ( h Sortable [ T ]) Swap ( i , j int ) { h . Items [ i ], h . Items [ j ] = h . Items [ j ], h . Items [ i ] } func ( h * Sortable [ T ]) Push ( x any ) { h . Items = append ( h . Items , x . ( T )) } func ( h * Sortable [ T ]) Pop () any { old := h . Items n := len ( old ) item := old [ n - 1 ] h . Items = old [ : n - 1 ] return item } be faster and more agile with the Golang ZenQL. Click To Visit ZenQLRepository
AI 资讯
The One TDD Habit That Saved My Sanity (and My Codebase)
The One TDD Habit That Saved My Sanity (and My Codebase) Quick context (why you're writing this) Here's the thing: I used to think I was doing TDD right. I’d write a test, watch it fail, then write just enough code to make it green. Rinse and repeat. Sounds textbook, right? But a few months ago I spent an entire afternoon chasing a bug that only showed up after I refactored a service class. The tests were all passing, yet the app was throwing NullReferenceExceptions in production. I was shocked. How could everything be green and still be broken? Turns out I was testing the inside of my code instead of what it actually did for the outside world. That realization hit me like a truck, and it completely changed how I approach TDD. The Insight Test behavior, not implementation. If your test is coupled to private fields, internal data structures, or the exact way a method accomplishes its goal, you’re not testing what matters—you’re testing how you happen to do it today. When you later refactor to improve performance, swap out a dependency, or even just rename a variable, those tests start failing for no good reason. You end up spending more time fixing tests than delivering value, and you lose confidence in the suite because it feels fragile. The payoff? A test suite that gives you confidence when you change code, not anxiety. You can refactor fearlessly because the tests only care about the contract: given these inputs, the system should produce these outputs or side‑effects . How (with code) Let’s look at a tiny but realistic example: a PasswordValidator service that checks whether a user‑chosen password meets our policy. ❌ The mistake: testing implementation details // PasswordValidator.cs public class PasswordValidator { private readonly IRegexProvider _regex ; // injected for testability public PasswordValidator ( IRegexProvider regex ) { _regex = regex ; } public bool IsValid ( string password ) { // implementation we might want to change later return _regex . IsMa
AI 资讯
My Journey Towards AI and Software Development
My Journey Towards AI and Software Development Hello everyone, My name is Kunal Tiwari, and I am a student who is passionate about technology, artificial intelligence, and software development. Technology has always fascinated me because it allows people to transform ideas into real-world solutions. Over time, I developed a strong interest in understanding how software is built and how AI can help solve everyday problems. I started exploring programming and software development with curiosity and a desire to learn. Although I am still at the beginning of my journey, I believe that consistent learning and practical projects are the best ways to grow as a developer. My current interests include: Artificial Intelligence (AI) Android App Development Software Engineering Problem Solving Building useful applications Through this blog, I plan to share my learning experiences, projects, challenges, and lessons that I discover along the way. My goal is not only to improve my technical skills but also to document my progress and connect with other learners and developers. I know the journey ahead will require patience, dedication, and continuous learning. However, I am excited about the opportunities that technology offers and look forward to building meaningful projects in the future. Thank you for reading my first post. I hope to share valuable insights and experiences as I continue my journey towards AI and software development. Best regards, Kunal Tiwari
AI 资讯
Agentic AI in software development: what's actually production-ready in 2026
Agentic AI in software development: what's actually production-ready in 2025 There's a lot of noise about AI agents right now. This post is an attempt to be precise: what is an agent architecturally, what can it actually do in a dev workflow today, and where does it still break. **What makes something an "agent" vs. a standard LLM call **A standard LLM call is stateless. You send a prompt, you get a response. No memory of previous turns (unless you manage it yourself), no external actions, no loop. An agent is a system built around an LLM that adds: Persistent memory across steps in a task Tool use - structured access to external systems (file I/O, shell execution, HTTP calls, database queries) A planning + evaluation loop - the agent generates a plan, executes a step, checks whether it succeeded, and decides next action Without all three, you don't have an agent. You have a capable model with maybe some extra context. What's actually production-ready today High confidence (use in production): Unit test generation for existing, well-documented code Boilerplate scaffolding (new modules, new endpoints, CRUD patterns) Documentation generation tied to code diffs Code migration tasks (framework upgrades, Python 2→3, ORMs) PR description generation from diffs Bug triage: given an issue, find likely affected files * Works but needs oversight: * Multi-file refactoring Dependency updates with breaking changes Writing integration tests (more surface area for wrong assumptions) Not there yet: Novel architecture decisions Debugging in unfamiliar/undocumented codebases Tasks with genuinely ambiguous requirements Long autonomous chains (>10 steps) without human checkpoints The failure modes to build around Ambiguous task specification Agents optimize for completing the task as specified. If the spec is loose, they'll complete the wrong task confidently. Be more precise with agents than you'd be with a junior engineer - there's no informal Slack thread to resolve ambiguity. Error
产品设计
How a Culture of Data-Driven Conversations Can Support Platform Engineering
To provide SRE as a service, a team built a center of excellence, introducing Federated SREs and roles like production manager and technical tribe lead. They created a culture of data-driven conversations where SLOs and SLAs were democratised. Surviving growing cognitive load meant continuously simplifying architecture and embedding sovereignty and resilience into platform design decisions. By Ben Linders
AI 资讯
AI Integration in Software Development: Addressing Predicted High Costs and Negative Consequences
Introduction: The Controversial Rise of AI in Software Development The software development industry is at a crossroads. On one side, the rapid advancement of AI tools promises to revolutionize coding, automate repetitive tasks, and accelerate project timelines. On the other, a growing chorus of experts, led by figures like George Hotz , warns that the integration of AI agents into software development could become "one of the most costly mistakes in the field’s history." This bold prediction isn’t just hyperbole—it’s a call to scrutinize the mechanisms by which AI adoption could deform the very foundation of software engineering. At the heart of this debate are three critical failure points: over-reliance on AI without human oversight , insufficient real-world testing , and misalignment between AI capabilities and software development demands . Each of these factors acts as a stressor on the system, threatening to heat up development costs, expand systemic vulnerabilities, and ultimately break the delicate balance between innovation and reliability. Consider the causal chain: over-reliance on AI leads to a degradation of human expertise , as developers become less engaged in problem-solving. This, in turn, creates a feedback loop where AI-generated code, lacking nuanced understanding, introduces errors that go unnoticed. Without proper oversight , these errors propagate through systems, causing observable effects like reduced software quality and increased maintenance costs. Similarly, insufficient testing of AI agents in real-world scenarios means their failure modes remain unknown until they’re deployed at scale, risking systemic collapse in critical applications. The stakes are high. If unchecked, AI integration could lead to a loss of institutional knowledge , escalating development costs , and vulnerabilities in critical systems . The question isn’t whether AI has a role in software development—it’s how to implement it without deforming the field’s core princi
AI 资讯
Serverless Framework Deployment: Unleash the Power of AWS Lambda
Let me tell you exactly what happened the first time I tried to set up Lambda manually. Four hours. IAM trust policies I didn't fully understand, ARNs copy-pasted into the wrong fields, an API Gateway that was technically configured but somehow not routing anything correctly, and a deploy that failed with an error message pointing me nowhere useful. I hadn't written a single line of actual business logic yet. That's when someone on my team mentioned the Serverless Framework. My first reaction was honestly skepticism — another abstraction layer sounded like another thing to learn and eventually fight with. I was wrong about that. This isn't a "look how clean this tool is" post. It's more like: here's what I actually did to get a Postgres-backed CRUD API running on Lambda, step by step, including the parts that tripped me up. What the Framework Is Actually Doing Under the Hood Worth knowing before you start: the Serverless Framework isn't magic. It's generating CloudFormation templates and submitting them to AWS on your behalf. Your Lambda functions, API Gateway routes, CloudWatch log groups — all of it gets provisioned from a single config file. It works with other providers too, but the AWS integration is where it really earns its keep. The console clicking and manual ARN-wiring that burns time at the start of every serverless project? Gone. Same deploy workflow whether you're building a REST API, an event processor, or a cron job. Once you've done it once, the second project takes a fraction of the time. What You're Building Four live endpoints backed by PostgreSQL. A Users table. Create, read, update, delete — nothing exotic, but a real enough foundation that you can extend it into something actual once this guide is done. You'll need an AWS account, the AWS CLI installed, and the Serverless Framework installed before starting. That's it. Step 1: Sort Out Your AWS Credentials Run this to create both config files in one go: bash cat << EOF > ~/.aws/credentials [def
开发者
Why Every Developer Should Attend Tech Week at Least Once
Last week, Toronto hosted Tech Week. A city-wide celebration filled with events and workshops...
AI 资讯
TryParse Looks Like a Small Utility Method — Until You Realize It Prevents Entire Classes of Production Failures
Why Senior .NET Engineers Rarely Trust User Input Most beginner C## developers discover TryParse() while learning console applications. It usually appears during a simple exercise: Console . Write ( "Enter quantity: " ); string ? input = Console . ReadLine (); if ( int . TryParse ( input , out int quantity )) { Console . WriteLine ( $"Quantity: { quantity } " ); } At first glance, it looks like a convenience method. A safer version of Parse() . A small utility. Nothing particularly interesting. But experienced .NET engineers see something completely different. They see one of the earliest examples of defensive programming. Because software engineering is not about handling perfect input. It is about surviving imperfect input. And in production systems, imperfect input is the rule—not the exception. TL;DR TryParse() is not just a conversion method. It introduces some of the most important concepts in professional software development: Defensive programming Input validation Runtime safety Exception avoidance Financial precision Domain modeling Reliability engineering Understanding why TryParse() exists is often more valuable than learning how to use it. Every Value in C## Starts With a Type One of the first concepts developers learn is that every variable has a type. int quantity = 10 ; decimal price = 25.99M ; string productName = "Laptop" ; bool isAvailable = true ; Simple. Yet this idea is foundational. Because types are not just containers. They are contracts. Each type defines: Valid values Memory layout Available operations Precision guarantees Runtime behavior When you choose a type, you are making an architectural decision. Why decimal Exists Many developers ask: Why not use double for money? Because financial systems require precision. Consider: double a = 0.1 ; double b = 0.2 ; Console . WriteLine ( a + b ); Expected: 0.3 Reality: 0.30000000000000004 The issue comes from binary floating-point representation. For scientific calculations, this is acceptable. F
AI 资讯
You're Not Paying for Code Generation. You're Paying for Context
The hidden cost of AI isn't generating code. It's understanding your codebase. For a long time, I assumed AI coding tools became expensive because they generated a lot of code. These tools can produce components, tests, SQL queries, documentation, and sometimes entire features on demand. If costs were climbing, the output volume must be the reason. The more I used these tools, the more I realized I was measuring the wrong thing. The expensive part isn't writing code. The expensive part is understanding what code should be written — and that work is mostly invisible. That realization changed how I think about AI-assisted development entirely. Two Prompts, Two Very Different Problems Consider these two requests: "Create a utility function that formats dates" and "Review this feature and suggest improvements." At first glance, both look ordinary. Both might even produce short answers. But they require completely different levels of understanding. The first is narrow and well-defined. The AI needs very little information before it can produce a useful answer. The second is open-ended. Before suggesting a single improvement, the AI may need to read multiple files, understand dependencies, follow existing patterns, compare implementations, and build a mental model of why the feature exists at all. The output might still be small. The work required to reach it is not. Why Agent Workflows Feel Different From Autocomplete This became much clearer when I started using AI agents. Traditional autocomplete is predictive — you type, the AI guesses what comes next. It's fast, cheap, and deliberately context-light. Agents behave differently. When you ask one to improve a feature or review a workflow, it doesn't immediately start generating code. It starts reading. It follows imports, finds related files, and tries to understand the system before touching it. That is exactly what makes agent workflows feel slower and more resource-intensive than autocomplete: they are spending effor
AI 资讯
CAP Theorem Explained
CAP Theorem Explained: Choosing Between Consistency, Availability, and Partition Tolerance in Databases Imagine you're trying to book a flight online, and just as you're about to pay, the website crashes. When you try to book again, you find that the flight is now sold out, even though the website initially showed available seats. This frustrating experience is a classic example of a database trade-off between consistency, availability, and partition tolerance. The CAP theorem, first introduced by Eric Brewer in 2000, states that it's impossible for a distributed data store to simultaneously guarantee more than two out of these three principles. In this post, we'll delve into the world of CAP theorem, exploring its fundamentals, real-world database examples, and design implications. Introduction to CAP Theorem Understanding the Basics of CAP Theorem The CAP theorem is based on three primary principles: Consistency : Every read operation will see the most recent write or an error. Availability : Every request receives a response, without guarantee that it contains the most recent version of the information. Partition Tolerance : The system continues to function and make progress even when network partitions (i.e., splits or failures) occur. Importance of CAP Theorem in Distributed Systems In distributed systems, where data is spread across multiple nodes, the CAP theorem plays a crucial role in understanding the trade-offs between these principles. By grasping the CAP theorem, developers can design more resilient and scalable databases that meet the specific needs of their applications. Brief Overview of the Blog Post This post will explore the CAP theorem in depth, using real-world database examples to illustrate the trade-offs between consistency, availability, and partition tolerance. We'll discuss the fundamentals of CAP theorem, examine CA, CP, and AP systems, and provide guidance on designing for each combination. By the end of this post, you'll have a solid un
AI 资讯
How Do You Design and Develop APIs the Git-Native Way?
Most API teams treat the contract as an afterthought: write code, generate a spec, then watch the two drift apart. Git-native API design reverses that flow. You treat the API contract as source code, version it in Git, and review every change the same way you review application logic. Try Apidog today This guide focuses on implementation discipline, not a single tool. You’ll design contracts in branches, review them in pull requests, and turn a committed spec into mocks, tests, and docs. The goal is simple: your Git history should also be your API history. If you already know what Spec-First tooling looks like and want the product walkthrough, read the companion piece on the git-native API workflow . This article stays focused on practice. What “git-native” means for API work Git-native means your API definition lives in your repository as a plain text file. Not in a proprietary cloud database. Not behind a vendor login. A .yaml or .json file sits next to your code and is tracked by the same version control system your team already uses. In many cloud-locked API design tools, the contract lives in the vendor’s backend. You edit through a web UI, and your repository only contains an export. That export can become stale, and your Git history no longer explains how the API evolved. The git-native model inverts that relationship: The file in main is the contract. Any GUI is a view onto that file. Branches, commits, pull requests, blame, and rollback all apply to your API surface. Mocks, docs, tests, and generated clients derive from the committed spec. A git-native setup has three core properties: The spec is a text file in the repo. Changes flow through normal Git operations: branch, commit, PR, merge. Downstream artifacts derive from the committed file, not from a separate database. Why design and develop APIs in Git You already trust Git with your code. Your API contract deserves the same treatment. 1. History When someone asks, “When did we add the cursor pagination
AI 资讯
Meet Microsoft Scout, Your AI Coworker That Never Logs Off
Microsoft’s OpenClaw-style agent appears in Teams, just like a human colleague, and automates your dull office tasks.
工具
How to Edit, Merge, and Split PDFs With Free Online Tools
You don’t need expensive software for basic PDF tasks. In fact, all you need is a handful of free web-based apps.
AI 资讯
Thinking in Workflows: Balancing agentic, programmatic, and manual steps
A security reviewer finds a critical issue a day or two before the release of an application. While it's an important issue, it sets the team back weeks, frustrating their product management partners and customers. The review came at the most expensive time in the process. There are many examples of how work items move through different processes to deliver software in large companies. While GenAI has allowed us to rapidly create code, it also moved and exposed the bottlenecks in our processes. It has also caused us to re-examine where it is most effective to make certain decisions. This is the challenge, and a deliberate blend of automated, programmatic, and human judgment is well suited to help you solve it. We can borrow from the well-trodden path of value stream mapping here. It is useful for spotting bottlenecks and waste in a given process, but it's also valuable to ask the deeper question of who or what should own each step. Each option earns its place differently. Is there an earlier step that may reduce costs with an agent where it was previously limited by human availability? Or is the stronger determinism of a programmatic step more important for a critical piece of the flow? Some decisions should stay with human judgment, where confidence without context is a liability. The opportunity for security teams and other stakeholders is to scale their impact across these options rather than scaling headcount. Workflow-as-code is not a new idea. There are a number of existing engines where the workflow definition is its own entity, separate from the work itself. GitHub Actions defines pipelines in version-controlled files, while the execution happens on separate runners. Airflow and Temporal follow a similar pattern for data and application workflows. Because the definition lives on its own, a team can change how a given step runs without rebuilding the whole flow. That separation is what makes it practical to adjust who or what owns each step over time. Rather
AI 资讯
Self-Review With AI Before You Open the PR — A Practical Workflow with branchdiff
You know the moment. You push the branch, open the PR, and immediately see it — the undefined return on the refund path, the token logged to the console, the TODO that was supposed to be temporary six weeks ago. The reviewer catches it four hours later and you reply "good catch, fixing now" as if someone else wrote that line. The first reviewer on most pull requests should have been the author. Half the comments you will receive — the missing null check, the untested error branch, the duplicate logic that could be extracted, the import that now goes nowhere — are things you would have caught with one more careful read-through. You skip that read because you have been in the code for two days and your brain completes the sentences for you. You see what you meant to write, not what is on the page. This post is about closing that gap with a structured AI-assisted self-review before the PR opens. Not to skip the human reviewer — to walk into the review with the obvious problems already gone, the test gaps already filled, and the PR description already written. So the reviewer's attention can land on what actually needs a second pair of eyes. The tool is branchdiff : a local browser app that runs your diff on localhost , stores everything in ~/.branchdiff/ , and keeps the AI surface controlled through an explicit branchdiff agent command API. Nothing leaves your machine until you decide to push it. Why "before the PR" is the right moment If you review after opening the PR, every AI fix becomes noise: a force-push, a re-read for your reviewer, another commit in the audit trail. If a teammate is already mid-review when you discover the bug, you look careless. The patch that should have been in the original push becomes a distraction for everyone downstream. If you review before opening the PR, the AI's output is a private workspace. You act on what matters, commit the fixes into your own history (often as fixup! commits you squash before pushing), and the PR that goes up i
AI 资讯
The loop I didn't notice closing
The loop I didn't notice closing Seven weeks ago I started using AI for work. Two weeks after that, I published an article. Seven weeks after that — today — the article is one of sixteen, and they are all in a memory file that the AI reads at the start of every new conversation. I didn't notice the loop until I named it. This is a note about that loop, what it is, what it isn't, and why I keep publishing even though the loop doesn't strictly need me to. The shape It runs like this: I decide what to do. I work it out with the AI — usually in dialogue, sometimes by pasting raw code or data. The dialogue becomes a record. Sometimes a memory entry. Sometimes a published article. The record becomes context for the next conversation, which informs the next decision. It didn't look this clean while it was happening. The numbering is hindsight. From inside, the steps overlap. The first step is the one I keep. Direction is mine: what to build, what to write, what to negotiate. The history that shapes those decisions — twenty-four years of solo work, my company, my family, my health — is also mine. The AI is not setting direction. The second step is where most of the leverage is. I describe what I want to do as completely as I can, sometimes by handing over source code. Then I ask: does this look right? Is there a path I'm missing? Where would this break? I'm opening drawers — possibilities I half-saw in my own head — and checking which ones open cleanly. When one opens cleanly, that is the GO signal. Not "will this succeed" but "this is doable, so do it." The third step happens almost without effort. The conversation already exists as text. Some of it becomes a memory entry I add deliberately. Some of it becomes raw material for an article. The article writes itself partly because I have already explained the thing to the AI. The fourth step is the one that took longest to arrive — and the one I want to be most careful about describing. Three phases, not one The loop didn't
AI 资讯
From vibe coding to clear thinking: what non-technical builders need in the age of AI
Over the past few months, I’ve increasingly noticed something through my network: more people from non-technical backgrounds are building software as AI tooling improves. Designers are prototyping product ideas. Product managers are testing workflows. Founders are building MVPs. Operators are creating internal tools. People who would not have called themselves “technical” a year ago are now using AI to make ideas tangible. I think this is genuinely exciting. It has never been easier to create. I even attended a hackathon where participants only had 20 minutes to build a demoable product! This raises the question: When AI makes building easier, how do we make sure understanding does not disappear? I recently published Thinking in the Age of AI , a guide for software engineers (you can check out my previous post here ). That guide focused on individual reflection for engineers: how to keep developing technical intuition, reasoning, and judgment while using AI tools. But the landscape has changed quickly. AI-assisted building is no longer only an engineering workflow. It is becoming a builder workflow accessible to all. And by builders, I mean anyone using AI to turn ideas into software-like artifacts: vibe coders designers product managers founders operators marketers students non-engineering team members So I wanted to create a new version of the system for this wider builder audience. Thinking in the Age of AI: Builder Edition The opportunity is real I do not think we should dismiss this shift. I have spoken with people from all kinds of backgrounds who are actively building now. People who previously had to wait for engineering time can now create something concrete. That changes the conversation. Instead of describing an abstract idea, you can show a flow. Instead of writing a long product spec, you can prototype the interaction. Instead of asking “would this work?”, you can test a rough version. That is powerful. But there is a trap. A prototype can look much mor