Enerji ve Tabii Kaynaklar Bakanı: “Elektrik faturalarının yüzde 55’i, doğalgaz faturalarının ise yüzde 45’i devlet tarafından karşılanıyor.

Enerji ve Tabii Kaynaklar Bakanı: "Elektrik faturalarının yüzde 55

Enerji ve Tabii Kaynaklar Bakanı: "Elektrik faturalarının yüzde 55'i, doğalgaz faturalarının ise yüzde 45'i devlet tarafından karşılanıyor.Enerji ve Tabii Kaynaklar Bakanı Alparslan Bayraktar, katıldığı bir programda, “Elektrik faturalarının yüzde 55’i, doğal gaz faturalarının ise yüzde 45’i devletimiz tarafından karşılanıyor. Yaşanan kriz kaynaklı oluşan fiyat seviyesi yıl sonuna kadar devam ederse, bu sübvansiyonların bütçeye ilave maliyeti 620 milyar lirayı bulacak.” dedi. Bakan Bayraktar, “1 Nisan itibarıyla elektrik ve doğal gaza zam var mı?” sorusuna ise, “Nisan ayı içerisinde hem doğal gaz hem de elektrikte bir değerlendirme yapabiliriz.” cevabını verdi. Elektrik fiyatlarına zam yapılması, ev ve işletmeler yanında elektrikli otomobillerin şarj fiyatlarını da artıracaktır. Yerli otomobil girişimi Togg tarafından işletilen Trugo, ocak ayında yaptığı zamla birlikte 150 kW’a kadar DC şarjı 10,60 TL’den 13,78 TL’ye, 150 kW ve üzeri DC şarjı 11,82 TL’den 15,36 TL’ye, 22 kW ve altı AC şarjı ise 8,49 TL’den 9,95 TL’ye çıkarmıştı. Elektrik faturalarının %55’i, doğal gaz faturalarının ise %45’i devletimiz tarafından karşılanıyor. Yaşanan kriz kaynaklı oluşan fiyat seviyesi yıl sonuna kadar devam […]

Enerji ve Tabii Kaynaklar Bakanı: “Elektrik faturalarının yüzde 55’i, doğalgaz faturalarının ise yüzde 45’i devlet tarafından karşılanıyor. yazısı ilk olarak Teknoloji haberleri – LOG üzerinde yayınlandı.

What’s the Best Way to Vibe Code a SaaS in 2026?

Sean Nam

You’ve probably seen the tweets, the YouTube tutorials, and the “I built a SaaS in 24 hours with AI” posts. But if you’ve actually tried to vibe code a SaaS, you know the reality is much messier than that.

Luckily, there are a bunch of tools, SaaS boilerplate starters, and workflows that you can use to build a profitable (side) business with, as long as you know how to apply them correctly.

So let’s take a look at what’s out there, and what really works.

TL;DR

  • AI-native platforms (Replit, Lovable, Bolt) are great for prototyping but hit a ceiling as complexity grows. Code is coupled to their infra, and it quickly becomes expensive and difficult to maintain.
  • AI coding tools (Claude Code, Cursor, Codex) give you great code and full control, but they need the right foundation and you’ll need some fundamental understanding of the underlying tools to work well with them.
  • The winning combo: Claude Code paired with a well-structured SaaS boilerplate like Open SaaS is the best way to vibe code a SaaS in 2026, giving you coherent code generation, along with better control as your app grows.
  • Two key techniques for effective vibe coding: (1) LLM-friendly docs (llms.txt and beyond), (2) full-stack debugging visibility.

The Vibe Coding Landscape in 2026

AI-assisted coding tools come in different flavors, and understanding their differences is key to picking the right approach.

In the table below, we quickly compare the two approaches. In the sections below that, we go into more detail about each approach.

AI-Native Platforms AI Coding Tools
Examples Replit, Lovable, Bolt.new Claude Code, Cursor, Codex
Setup Zero-config, browser-based Local install, terminal/code-focused
Best for Quick prototypes and demos Production apps and SaaS businesses
Code control Limited — AI makes structural decisions Full — you own and control everything
Vendor lock-in High — coupled to platform infra None — works with any stack
Scalability Scalability degrades as complexity grows Scales with your codebase. No limitations.
Deployment Platform-hosted (limited options) Deploy anywhere (Railway, Fly.io, VPS)
Cost at scale Monthly fee + additional costs for debugging, storage, hosting, etc. Cheaper — monthly fee + choose your favorite hosting solution

AI-Native Platforms

Tools like Replit Agent, Lovable, Bolt.new, and v0 aim for a “zero-config”, purer “vibe coding” approach, where you describe what you want and get a working app. They aim to remove setup, config, and having to touch the code and/or terminal as much as possible. They’re impressive for demos and fast prototyping.

The catch here is that most of these apps are then locked-in to their hosting, auth, and storage solutions. This isn’t always bad, but things can easily get complicated and expensive as your app grows:

  • The “70% problem”: these tools get you roughly 70% of the way to a working product. The last 30% — auth hardening, error handling, performance, deployment config — requires significant manual effort. One estimate puts the cost of making Bolt.new output production-ready at $5,000-$20,000 in professional dev work.
  • Infrastructure coupling: the code you export is tightly coupled to a specific service stack. Lovable, for example, generates code deeply wired into Supabase, a separate service for auth, storage, realtime, edge functions, etc. Leaving Lovable/Supabase means rewriting all of those integrations. Replit similarly relies on its default Auth, Storage, and database options.
  • Code quality degrades at scale: Bolt.new projects with 15-20+ components experience severe AI context degradation — duplicated code, forgotten patterns, and inconsistencies. Replit Agent has been flagged for generating “non-idiomatic or messy” code that becomes harder to maintain as projects grow. Multiple developers report spending $1,000+ in tokens just debugging AI-generated bugs.
  • Limited architectural control: the AI makes structural decisions for you, and those decisions compound. Data models get rigid, logic gets tightly coupled, and by the time you want to refactor, you’re looking at a near-rewrite anyway.

In the end, the most common feedback from users of these tools is that they allow you to move fast and to easily build initial prototypes, but maintainence and upgrades quickly become complex and expensive.

To solve this, working on code locally, instead of a platform, is the first step.

AI Coding Tools

Tools like Claude Code, Cursor, GitHub Copilot, and Codex work directly with your local files, and are better at generating production-ready code that you control.

The pros here are: full control, no lock-in, works with any stack, and the added bonus is that it will be cheaper. You can version it, test it, deploy it anywhere, and switch tools whenever you want.

But these tools require a bit more work to get the most out of them. You’ll have to be comfortable using the terminal, install a few more underlying tools, and its good to have a general understanding of the fundamentals when working with them. But, luckily, these tools can help you each step of the way, and if you set things up right (which we will show you how to do in this article) you can go all the way with them.

In comparison to the AI-native platforms, if you’re serious about building something substantial these tools give better results at cheaper prices.

We’ll use Claude Code as the driving example throughout this post, but the same principles apply to Cursor, Codex, and others.

The Winning Combo: Claude Code + SaaS Boilerplate

Most of the tedious parts of building a SaaS are routine, boilerplate tasks like setting up authentication, payments, email sending, file uploads, admin dashboard, etc. These are the things that are time-consuming to set up, aren’t very creative or interesting, but are 100% necessary for a functional SaaS.

Luckily, tons of SaaS boilerplate starter kits exist, giving you a solid foundation to build your SaaS on top of. They provide all the necessary integrations, plumbing, and glue code, along with some nice extras, so you can just focus on building the fun part of your app.

A well-structured boilerplate has some key benefits: it allows you to start working on the actual business logic of your SaaS from day one. It also gives the AI patterns, structure, and conventions to follow, making it easier for tools like Claude Code to generate clean, consistent code.

It’s like giving a skilled carpenter a well-organized workshop instead of an empty shed. The tools are there, the materials are laid out, and there’s a clear plan to follow.

You keep the full control, but you skip the part where you (or your AI) have to make a hundred decisions about project structure, auth patterns, payment integration, and deployment config. That’s all solved for you already by the starter kit.

But, because so many boilerplate starters exist, choosing the right one can be a pain.

Choosing Your SaaS Boilerplate

There’s no shortage of SaaS boilerplates out there. The real question isn’t just “which one has the best features?”, it’s which one sets you (and your AI coding tool) up for long-term success. A few factors matter more than you’d think: cost, deployment flexibility, community support, and how well the codebase structure plays with AI.

In the table below, we quickly compare some popular, battle-tested starters. In the sections below that, we go into more detail about each of them.

Paid Boilerplates (ShipFast, Supastarter) Open SaaS
Price $250-$800+ Free, open-source
Auth Third-party providers (Clerk, Supabase auth, Better Auth) Built-in (email/password, Google, GitHub, Microsoft, Slack, etc.)
Payments Stripe, Lemon Squeezy, or Polar.sh, etc. Stripe, Lemon Squeezy, or Polar.sh
Deployment Vercel + Supabase (typically) Railway, Fly.io, or any VPS
Community 1-2 maintainers 13,000+ GitHub stars, active open-source community
LLM-friendly docs llms.txt llms.txt
Codebase structure Multiple apps/packages with separate configs and third-party integrations wired together Single app, feature-based organization with fullstack code colocated

Paid Boilerplates

Options like ShipFast ($250) and Supastarter (starting at $299) are popular choices. They’re packed with lots of features and have a strong history of adoption and support.

But there are a few things to consider:

  • Upfront cost: $250-$800+ before you’ve written a line of business logic
  • Vendor-leaning stacks: many are built on top of Vercel + Supabase + third-party auth services. That’s more vendor lock-in and recurring hosting costs on top of the purchase price. You’re not just paying for the boilerplate, but you’re also committing to a specific infrastructure stack.
  • Code Quality: most paid boilerplates are maintained by a one or two developers. An open-source project, on the other hand, is maintained by many more people, and the community input is much larger, making it more robust and reliable.
  • Stack fragmentation: ShipFast is a flat Next.js app where auth, payments, email, and database are each handled by separate third-party libraries you wire together yourself. Supastarter is a Turborepo monorepo with 4 separate Next.js apps and 8+ shared packages, each with its own config. Both approaches mean more files for an AI tool to navigate, more indirection to follow, and more context needed to make a single cross-cutting change.

None of this means paid boilerplates are bad. They can absolutely save you time. But it’s worth understanding what you’re signing up for beyond the purchase price.

Open SaaS — a free, open-source, production-ready SaaS boilerplate starter

Open SaaS is free, and open-source. It’s powered by Wasp — a batteries-included full-stack framework for React, Node.js, and Prisma apps.

Here’s what you get out of the box:

  • Auth: email/password, Google, GitHub, all pre-configured and without third-party providers
  • Payments: Stripe, Lemon Squeezy, or Polar.sh. Take your pick.
  • Email, file uploads, admin dashboard, analytics, e2e tests: the full SaaS toolkit.
  • Deploy anywhere: Railway, Fly.io, or any VPS. No vendor lock-in.
  • 13,000+ GitHub stars and an active open-source community backing it.
The documentation is a million times better for Open SaaS than for ShipFast… I got frustrated with ShipFast’s terrible code and terrible documentation (or just the lack of) and I found Open SaaS. It’s looking like it will be a better experience.

★
★
★
★
★
Sean Nam

Sean Nam
Founder @ NotePulse

Because Open SaaS is built on Wasp, everything lives under one roof. React frontend, Node.js backend, and Prisma database layer are all managed by a single framework, with a declarative config (main.wasp or main.wasp.ts) that defines your routes, pages, operations, auth, and background jobs. The codebase is organized by feature (e.g. auth, payments, file uploads) with backend logic and frontend components sitting side by side. When an AI coding tool reads main.wasp, it immediately understands the full app structure without having to jump between separate apps, packages, or third-party service abstractions. One framework, one config, one mental model for the AI to follow.

Effectively Vibe Coding Your SaaS

So we’ve got our AI-assisted coding tool and our SaaS boilerplate starter, but to get the most out of AI-assisted development, you need two more things working together. Note that these tips come from real-world experience building full-stack apps with Claude Code and Wasp, and we covered them in depth on the Wasp blog.

1. LLM-Friendly Documentation

LLMs don’t always get things right, and may sometimes be out-of-date with the latest features of the tools you’re using. For example, if you’re using a framework that shipped a new version last week, your AI tool probably doesn’t know about it, unless you give it the docs.

But how you give it docs matters a lot, because LLMs don’t have a long-term memory, rather they have context windows, which is like a limited memory of only the most recent conversations. So with each new session, you have to remind them of what you’re working on, with, and what you want to do.

One of the best solutions is to use llms.txt files. These are structured docs in a single, machine-readable plain text file that’s purpose-built for LLMs.

Open SaaS and Wasp both provide these:

Just add these URLs to your AI coding tool’s chat session or “memory” (e.g. CLAUDE.md, AGENTS.md). When the AI needs to, for example, understand how Wasp auth works or how to set up Stripe payments in Open SaaS, it has the full, up-to-date docs right there.

And it’s not just Open SaaS and Wasp. Most developer tools and integrations have adopted the llms.txt standard. Try appending /llms.txt to any tool’s docs URL and see what comes back. You’d be surprised how many services already support it. When you’re implementing a new integration, pass its llms.txt to your coding agent so it has good guardrails for development.

Another pro tip: when you’re working on a specific feature, search the tool’s docs for the relevant guide and look for a “Copy for LLMs” button. Many doc sites now offer this. Or just try adding .md to the end of a specific URL to get an LLM-friendly version of that page. For example, Stripe’s guide on SaaS subscriptions is available at https://docs.stripe.com/get-started/use-cases/saas-subscriptions.md. Pass that to your agent and it’ll have the knowledge it needs to implement Stripe subscriptions correctly.

2. Full-Stack Debugging Visibility

AI can write code all day, but if it can’t tell whether the code actually works, you’re constantly stuck in the middle, running the app, checking the browser, copying error messages back and forth.

The fix is giving your AI tool full-stack visibility into what’s happening when the code runs, so it can see the errors, and fix them without you having to always intervene.

  • Background dev server: Run your dev server as a background task so the AI can see server logs, compilation errors, and runtime exceptions in real time. In Claude Code, you can use background tasks (Ctrl+B) to keep wasp start running while you work, or just tell it to “start the dev server as a background task”.
  • Browser automation: Tools like Chrome DevTools MCP or Vercel’s agent browser let AI see what’s actually rendering in the browser — console errors, network requests, DOM state — without you having to screenshot anything. The AI can verify that the button it just added actually appears on the page and handles clicks correctly.

Together, these create a tight feedback loop: AI writes code → sees the result → spots the error → fixes it → verifies the fix. This improves the quality of the code it generates, and makes the entire process less tedious and more efficient.

Getting Started: From Zero to Vibe Coding

Ready to try it? Here’s how to go from nothing to vibe coding a SaaS in a few minutes.

Step 1: Install Wasp and Get the Template

npm i -g @wasp.sh/wasp-cli
wasp new my-saas -t saas
cd my-saas

This scaffolds a new Open SaaS project with auth, payments, email, file uploads, an admin dashboard, a landing page, and more — all pre-configured and ready to go.

Step 2: Set Up Claude Code with the Wasp Plugin

After installing Claude Code, add the Wasp plugin so that it has deep knowledge of the framework, as well as skills and instructions on how to properly use full-stack debugging visibility, llms.txt docs, and more:

claude plugin marketplace add wasp-lang/wasp-agent-plugins
claude plugin install wasp@wasp-agent-plugins --scope project

NOTE: Other coding agents

If you’re using a coding agent like Codex, OpenCode, Cursor, etc. you can get the same set of agent skills by running:

npx skills add wasp-lang/wasp-agent-plugins

Then, in a new session, run the plugin initialization skill command to initialize the plugin with Wasp best practices for your project:

/wasp-plugin-init

Step 3: Get Integrations Working (Stripe, Email Sender, OpenAI, etc)

Next, you’ll want to get your payment, email sender, and other integrations working (Stripe, Email Sender, OpenAI, etc) before you start building features.

Luckily for you, we’ve got a complete walkthrough video that guides you step-by-step through creating accounts, adding your API keys, and getting each integration working:

Or if you want your agent to help guide you through the process, you can ask it to fetch the “getting started” guide from the Open SaaS LLMs.txt docs and follow the instructions step-by-step.

Step 4: Start Building

Fire up your database and dev server:

wasp start db
wasp start

Or just tell Claude Code to run start the dev server as a background task and it will run the correct commands for you 🙂

Now it’s finally time to give Claude Code a real feature request — “add a user settings page where users can update their profile” — and watch it reference the Wasp config file(s) to understand your app’s structure, reference the right patterns from the boilerplate, and implement the feature correctly.

Because Wasp is opinionated, Claude won’t have to guess where to put files, how to wire up routes, or which patterns to follow. It reads the config file(s), sees the existing conventions, and follows them. You get consistent, working code on the first try — or pretty close to it.

Remember, if you’re using Cursor, Copilot, or another tool, the same principles apply. Check out our Vibe Coding guide more info.

FAQ

What’s the difference between AI-native platforms and AI coding tools?

AI-native platforms like Replit, Lovable, and Bolt.new aim for a zero-config experience where you describe what you want and get a working app. AI coding tools like Claude Code, Cursor, and Codex work directly with your codebase, giving you full control and no vendor lock-in. AI-native platforms are great for quick prototypes but hit a ceiling as complexity grows, while AI coding tools require more setup but produce more maintainable, production-ready code, and can actually be cheaper in the long run.

Can I export my code from Replit, Lovable, or Bolt.new?

Yes, all three platforms let you export your code via GitHub sync or ZIP download. However, the exported code is often tightly coupled to their infrastructure — for example, Lovable generates code wired into Supabase, and Replit uses proprietary auth, storage, and database solutions. This means significant refactoring is needed if you want to deploy elsewhere or switch services.

What is llms.txt and why does it matter for vibe coding?

llms.txt is a structured documentation file in plain text format, purpose-built for LLMs. It gives AI coding tools like Claude Code up-to-date knowledge about the frameworks and tools you’re using, reducing hallucinations and outdated code suggestions. Most developer tools now support it — just append /llms.txt to any tool’s docs URL to check.

What is the best free SaaS boilerplate starter for AI-assisted development?

Open SaaS is a free, open-source SaaS boilerplate for React, Node.js, and Prisma apps powered by the Wasp framework. It comes with auth, payments (Stripe, Lemon Squeezy, or Polar.sh), email sending, file uploads, an admin dashboard, and more, all pre-configured. Because it’s built on Wasp, the entire stack is managed by a single framework with a declarative config file. The codebase is organized by feature with backend and frontend code colocated, so AI tools can understand the full app structure from one file instead of navigating multiple apps, packages, and third-party integrations.

Does codebase structure matter for AI-assisted development?

Yes, significantly. AI coding tools work best when they can quickly understand the full picture of your app. A codebase organized by feature with colocated fullstack code — like Open SaaS, where backend logic and frontend components sit side by side — gives the AI one clear mental model to follow. In contrast, boilerplates that split code across multiple apps, packages, and third-party integrations require the AI to navigate more files and follow more indirection, which increases the chance of inconsistencies and errors.

How do I set up Claude Code for full-stack SaaS development?”,

Install Claude Code, then add the Wasp plugin for deep framework knowledge. Create a new Open SaaS project with ‘wasp new my-saas -t saas’, set up your integrations (Stripe, email, etc.), and run ‘wasp start’ as a background task so Claude Code can see server logs and errors in real time. Pair this with browser automation tools like Chrome DevTools MCP for full-stack debugging visibility.”

Conclusion

The best way to vibe code a SaaS in 2026 isn’t about finding the flashiest AI tool, it’s about giving your AI tool the right foundation to work with.

We suggest using Claude Code and giving it three things: a strong SaaS boilerplate starter kit, like Open SaaS, that gives AI a solid foundation to work with, LLM-friendly docs that help AI stay grounded without burning context, and full-stack debugging visibility that closes the feedback loop.

Open SaaS + Claude Code gives you all of this: a free, open-source, production-ready SaaS foundation, the structure and conventions AI needs to generate clean, consistent code, complete LLM-friendly docs for both the template and the framework, and the tools for full-stack debugging visibility. And because it’s all free and open source there’s no upfront cost, no vendor lock-in, and you can deploy wherever you want.

You spend your time on business logic and product, not the boring stuff.

The Software Architect Elevator

I don’t think it’s necessary to introduce Gregor Hohpe. I’m a big fan, having read Enterprise Integration Patterns, and I’ve recommended the book ever since. When I spoke at the Software Architecture Gathering in 2024, I was fortunate enough to meet him and purchase this book. I’m the happy owner of a signed copy.

Modern architects don’t try to be the smartest people in the room–they make everyone else smarter. They ride the Architect Elevator from the penthouse, where the business strategy is set, to the engine room, where the enabling technologies are implemented. They shun popular buzzwords in favor of decision discipline and clear communication across levels.

Facts

Chapters

  1. Architects
    1. The Architect Elevator
    2. Movie-Star Architects
    3. Architects Live in the First Derivative
    4. Enterprise Architect or Architect in the Enterprise?
    5. An Architect Stands on Three Legs
    6. Making Decisions
    7. Question Everything
  2. Architecture
    1. Is This Architecture?
    2. Architecture Is Selling Options
    3. Every System Is Perfect…
    4. Code Fear Not!
    5. If You Never Kill Anything, You Will Live Among Zombies
    6. Never Send a Human to Do a Machine’s Job
    7. If Software Eats the World, Better Use Version Control!
    8. A4 Paper Doesn’t Stifle Creativity
    9. The IT World Is Flat
    10. Your Coffee Shop Doesn’t Use Two-Phase Commit
  3. Communication
    1. Explaining Stuff
    2. Show the Kids the Pirate Ship!
    3. Writing for Busy People
    4. Emphasis Over Completeness
    5. Diagram-Driven Design
    6. Drawing the Line
    7. Sketching Bank Robbers
    8. Software Is Collaboration
  4. Organizations
    1. Reverse-Engineering Organizations
    2. Control Is an Illusion
    3. They Don’t Build ‘Em Quite Like That Anymore
    4. Black Markets Are Not Efficient
    5. Scaling an Organization
    6. Slow Chaos Is Not Order
    7. Governance Through Inception
  5. Transformation
    1. No Pain, No Change!
    2. Leading Change
    3. Economies of Speed
    4. The Infinite Loop
    5. You Can’t Fake IT
    6. Money Can’t Buy Love
    7. Who Likes Standing in Line?
    8. Thinking in Four Dimensions
  6. Epilogue: Architecting IT Transformation
    1. All I Have to Offer Is the Truth

Pros and cons

You might have noticed that there are lots of chapters. Yet, the book isn’t “big”. Thus, each chapter is between 5 and 10 pages. To me, it’s a big plus: I can focus much better on a small chapter before going to sleep than to slice a chapter between multiple sessions or increase my reading span.

The author speaks from experience. Many sections in the book spoke to me, as something I had experienced in my professional life. Think “experience distilled” in a book.

If you are into technical stuff, you’ll be disappointed. The book is strictly about organization-related matters. On this side, it’s a trove of wise advice.

The book is segmented into chapters, but I think they can be read in any order, as each is cohesive enough. Early chapters tend to reference later chapters less than the opposite. That might be the only reason for the sequence.

The book’s advice, just like any other, can’t be applied blindly. Experience is hard to transmit as it is. You need to carefully read each advice multiple times, analyze its context, evaluate your context, try to apply it, then measure. Rinse and repeat. Yes, organizational matters are more complex to handle than technical ones.

While the subject is serious and the anecdotes relevant, the tone is humorous. Some might like it, some might not. I belong to the former crowd.

Conclusion

If you already have a couple of years of experience and feel your technical skills aren’t enough, I’d definitely recommend this book.

To go further:

Originally published at A Java Geek on March 22nd, 2026.

Hybrid AI Workbench: The $10M Exit Asset CTOs Miss

When Private Equity firms evaluate AI-driven companies in 2026, they’re no longer asking “Does it use AI?” They’re asking “Can we audit it? Can we scale it? Can we sell it?” Most startups fail this test because they’ve built chatbots, not systems. The difference costs millions at exit.

The Hybrid AI Workbench is not just a software application; it is a standardized operating system for high-volume, high-variance knowledge work. Whether it is due diligence, market mapping, or regulatory audits, the Hybrid AI Workbench provides a repeatable framework to convert unstructured human labor into an “audit-ready,” high-margin digital asset. This architectural approach transforms operational AI implementation from a cost center into a defensible competitive moat.

1. The Core Framework: A Five-Layer Reference Architecture

To avoid architectural sprawl and technical debt—especially in a portfolio context—CTOs should adopt a layered approach. This ensures that individual “agents” can be swapped as models improve, while the core business logic remains stable.

Layer 1: The Engagement Layer (Intent & SLA)

This is the interface where humans define the mission. It is more than a chat box; it is a Structured Task Definition engine.

  • Function: Captures the “Brief,” sets compliance constraints, and establishes Service Level Agreements (SLAs).
  • Value for PE: Standardizes inputs across different business units, a core tenet of effective Business Process Optimization, allowing for portfolio-wide performance benchmarking.

Layer 2: Orchestration & Agentic Mesh (The Brain)

Using frameworks like LangGraph Enterprise, this layer breaks the brief into a Directed Acyclic Graph (DAG).

  • The Planner: A high-reasoning model (e.g., GPT-5 or Claude 4) that decomposes tasks.
  • The Workers: Specialized agents (SQL experts, web navigators, data cleaners).
  • The Critic: A dedicated verifier agent that audits the output before it ever touches a human.

Layer 3: The Human-in-the-Loop (HITL) Layer

This is the “Safety Valve.” It manages the handoff between AI uncertainty and human expertise.

  • Function: Routes sub-tasks to internal employees or external experts based on skill tags and availability.
  • Objective: In 2026, the goal is 10x Employee Efficiency. Instead of “doing” the work, employees move to a “review and refine” model.

Layer 4: Data & Knowledge Layer (Memory & Lineage)

Every action, tool call, and human correction is stored as a structured event.

  • Tech Stack: Postgres (Relational), pgvector (Memory), and Snowflake/DuckDB (Analytics).
  • Provenance: Every cell in a final deliverable must link back to its source URL or raw data point.

Layer 5: Platform & Security (The Foundation)

The “Boring but Critical” layer.

  • Function: Multi-tenant isolation, secret management, and Micro-VM Sandboxing (e.g., E2B or Fly.io) to ensure agents can execute code without compromising the host network.

2. Strategic Views for Stakeholders

The Logical View: The Task Lifecycle

A request flows from Ingestion (Brief) → Planning (Decomposition) → Execution (Parallel Agentic Work) → Verification (AI-Critic) → Escalation (Human QA) → Delivery (Export). This flow ensures that the system is self-correcting. If an agent fails a task, the state is persisted, allowing a human to “unblock” the agent and resume the loop.

The Implementation View: The 2026 Stack

For an exit-ready architecture, CTOs should prioritize frameworks with strong “Durable Execution” and “Auditability.”

  • Orchestration: LangGraph Enterprise. Why? It offers a managed control plane that records every transition in the state machine. For a PE firm, this is the “Black Box Recorder” that proves the value of the AI during due diligence.
  • Backend: Python (FastAPI/PydanticAI) or TypeScript (NestJS).
  • Storage: S3 for artifacts, Neon/Supabase for stateful data.
  • Human Interface: Next.js 16 with real-time “Context-Streaming” so reviewers see exactly what the AI saw.

The Operating Model View: Hybrid Strategy

The architecture supports two distinct business strategies:

  1. Efficiency Play (Internal): Focus on deploying the “Human Layer” to existing employees. Success is measured by Cycle Time Reduction and Output per FTE.
  2. Scalability Play (External): Plug in a global marketplace of experts (The “Tendem Model”). Success is measured by Margin Expansion and Elastic Capacity.

3. The Agentic Maturity Model

PE firms and CTOs can use this 5-level model to benchmark portfolio companies and justify investment in AI infrastructure.

Maturity Level Characteristics Value Driver
Level 1: Manual Ad-hoc human experts using basic AI chat (ChatGPT). Basic labor.
Level 2: Point AI Disparate teams use custom scripts or single agents. Incremental speed.
Level 3: Orchestrated Central LangGraph-style state machines; AI-to-AI verification. Consistency & reliability.
Level 4: Full Hybrid Seamless human-agent handoff; 10x productivity gains. High-margin scale.
Level 5: Portfolio Hub Shared intelligence across assets; “Clean Room” data sharing. Compounding Moat.

4. Why the Hybrid AI Workbench Architecture Wins at Exit

When a Private Equity firm prepares a company for exit in 2026, a “wrapper” is a liability, but an “Agentic Workbench” is a core asset.

  1. Auditability: Because we use LangGraph Enterprise, every decision the AI made is traceable. A buyer can verify the accuracy and safety of the system’s history.
  2. Portability: By modularizing the “Agent Mesh” (Layer 2) from the “Data Layer” (Layer 4), the company can swap models as they become cheaper or faster without rewriting the business logic.
  3. Governance as Code: Security and compliance are not “add-ons”; they are baked into the state machine transitions, reflecting a mature approach to AI Governance & Risk Advisory.

Conclusion: The Path Forward with the Hybrid AI Workbench

The “Hybrid AI Workbench” is the blueprint for the next generation of service and software companies. It acknowledges that while AI can handle 90% of the volume, the final 10%—the human judgment—is where the real value (and the liability) lives.

CTOs: Your priority is building the “Durable State Machine”—a foundational piece of modern AI Architecture. Don’t build another chatbot; build a system that can pause, wait for a human, and resume without losing context.

PE Firms: Look for the “Uncertainty Gap.” The most valuable companies in your portfolio will be those that have successfully automated the “grunt work” of knowledge tasks while maintaining a high-fidelity human “Critic” layer.

Due Diligence Checklist for Private Equity Firms Evaluating Agentic AI

This is a framework for evaluating a portfolio company’s AI architecture based on the reference model. Concept aimed at successful AI-driven assets in 2026, with clear, affirmative answers to the questions.

Phase 1: Product & Market Fit (The Opportunity)

Problem Definition

  • Is the AI solution targeting high-volume, high-variance knowledge work like market research, due diligence, compliance audits, or process verification?
  • PE Goal: Ensure significant labor-arbitrage or massive scalability potential.

Addressable Market

  • Is the target market large and currently reliant on manual labor or inefficient services?
  • PE Goal: Verify the ‘Uncertainty Gap’ for value creation.

Use Case Clarity

  • Are primary use cases: well-defined with clear inputs (briefs) and outputs (standardized deliverables)?

Phase 2: Technical Architecture (The Core Reference Model)

Orchestration Maturity (Layer 2)

  • Does the architecture use a standard, exit-ready state machine framework like LangGraph Enterprise?
  • Is the agent workflow modeled as a Durable State Machine, where a task can be paused, wait for human input, and resume without losing context?
  • Is there a central ‘Critic Agent’ that audits all outputs before reaching the human layer?
  • Red Flag: Is the solution a monolithic wrapper around a single API, or does it have specialized agents?

Platform & Security (Layer 5)

  • Are all untrusted agents/tools executed in isolated, ephemeral micro-VMs (e.g., E2B, Fly.io)?
  • Is there multi-tenant isolation with clear data access controls between clients or business units?
  • Is there egress filtering to prevent agents from exfiltrating data or attacking external websites?

Data & Memory (Layer 4)

  • Is there a full Provenance Chain tracing every data point in a deliverable back to its source URL and timestamp?
  • Does the database (e.g., Postgres with pgvector) have Hybrid RAG capabilities for contextual memory?
  • Is the data structure standardized for portfolio-wide learning or ‘Clean Room’ data sharing at Level 5 maturity?

Observability (Layer 5)

  • Does the system provide comprehensive, trace-based evaluation (e.g., LangSmith, Arize Phoenix)?
  • Does it also allow ‘replay’ of failing tasks to identify hallucinations or failed tool calls?

Phase 3: Human Capital & Operations (The Integration)

Integration of the Human Layer (Layer 3)

  • Is the human review interface deeply integrated into the state machine, providing interactive full context (source URLs, AI ‘thoughts’) for efficient review?
  • What is the escalation logic? Is it based on quantitative confidence scores?
  • What is the strategy for the human layer: internal for 10x efficiency, or an external global marketplace for elastic scale?

Operational KPIs

  • Can the company track Cost per Task, Cycle Time Reduction, and Output per FTE?
  • What is the historical error rate? How has it changed with architectural improvements?
  • What percentage of tasks require human touch?

Phase 4: Investment & Exit Strategy (Value Creation)

  • Maturity Benchmarking: At what level is the company on the Agentic Maturity Model (1-5)?
  • PE Goal: Identify clear milestones for investment to move from Level 3 to Level 4/5.
  • Audit Readiness: Does the current architecture provide a full audit trail of every decision, tool call, and human action?
  • PE Goal: Ensure the asset can withstand a buyer’s due diligence regarding AI safety and data provenance.
  • Portability: Is the agent mesh (Layer 2) decoupled from the data layer (Layer 4) to allow model swapability for managing future costs?

Further Reading

Written by Dr Hernani Costa | Powered by Core Ventures

Originally published at First AI Movers.

Technology is easy. Mapping it to P&L is hard. At First AI Movers, we don’t just write code; we build the ‘Executive Nervous System’ for EU SMEs.

Is your architecture creating technical debt or business equity?

👉 Get your AI Readiness Score (Free Company Assessment)

The Netherlands Just Banned Scottish Folds and Sphynx Cats — And a Global Regulatory Wave for Pets Is Following

The Cat Breeds You Can No Longer Buy in the Netherlands

In a quiet apartment in Amsterdam, a Scottish Fold cat named Mochi sits on a windowsill, her signature folded ears giving her the wide-eyed, owl-like expression that made the breed an internet sensation. Mochi is legal — she was microchipped before the deadline. But as of January 1, 2026, no one in the Netherlands can buy, import, or breed another cat like her.

The Dutch government’s ban on Scottish Fold and Sphynx cats is one of the most aggressive animal welfare measures any country has taken against specific pet breeds, and it reflects a growing global consensus that the aesthetics humans find adorable in pets can mask serious suffering. Scottish Folds carry a genetic cartilage defect called feline osteochondrodysplasia (FOCD) — the same mutation that gives them their endearing folded ears also causes painful, progressive joint disease throughout their bodies. Sphynx cats, bred for their striking hairlessness, struggle to regulate body temperature and are prone to skin conditions.

The ban, announced by the Dutch Ministry of Agriculture, Fisheries, Food Security and Nature (LVVN), doesn’t require current owners to surrender their pets. But the rules are strict: existing cats must have been verifiably microchipped before January 1, and they can no longer appear in exhibitions or competitions. Violations carry a €1,500 fine.

“The aim of the ban is to improve animal welfare and prevent the breeding or sale of new cats with harmful physical traits. Folded-ear cats have a genetic cartilage defect which can lead to pain, stiff joints, limping, and in severe cases, paralysis.”
— Dutch Ministry of LVVN

What makes the Dutch move significant is that it isn’t happening in isolation. It’s part of a sweeping campaign called “Zo schattig dat het pijn doet” — “So cute that it hurts” — urging people to consider animal welfare before choosing a pet based on appearance. And the Netherlands isn’t alone. Belgium is already debating whether to follow suit, and the broader European Union is pushing legislation that could reshape pet ownership across the continent.

Europe’s Landmark Pet Welfare Law Takes Shape

The Netherlands’ breed ban is just one tile in a much larger mosaic. The European Union reached a provisional agreement on its first-ever comprehensive legislation on the welfare of dogs and cats — a landmark regulation that, once published in the Official Journal later in 2026, will fundamentally change how pets are bred, sold, and tracked across all member states.

The regulation’s centerpiece is mandatory microchipping for every dog and cat in the EU, linked to interoperable national databases. Sellers, breeders, and shelters will have four years to comply; private owners will have ten years for dogs and fifteen for cats. But the law goes far beyond identification. It introduces strict breeding restrictions: no mating between parents and offspring, grandparents and grandchildren, or siblings. It sets minimum and maximum breeding ages and limits how frequently animals can be bred. And critically, it bans breeding practices that produce exaggerated physical traits leading to significant health risks — a provision that could eventually affect brachycephalic breeds like French Bulldogs and Pugs across the continent.

The timing is no accident. A rabies case in Germany in early 2026 exposed the dangers of the current system. A dog imported from Russia through Latvia — one of a consignment of 24 animals (22 dogs and 2 cats) distributed by an animal charity — died on January 25, with rabies confirmed on February 10. Post-mortem examination revealed the dog was younger than declared, making it an illegal import despite having a microchip and vaccination records. The case triggered alarm across Europe: Belgium’s food safety agency contacted 50 owners of dogs adopted through the same Russian organization, and on March 18, Latvia’s Agriculture Minister formally called on the EU to impose a temporary ban on all commercial dog and cat imports from Russia and Belarus.

Germany, which had considered rabies eradicated since 1996, was shaken. The country’s Environmental Ministry issued an urgent recommendation for regular vaccination boosters for all dogs, cats, and ferrets — a reminder that in a world of cross-border pet adoption, diseases once considered vanquished can return with a single shipment.

Russia Prepares for Mandatory Pet Registration

Across the border, Russia is confronting its own pet governance challenges — from the opposite direction. While Europe tightens import controls, Russia is building the domestic infrastructure to track its pets for the first time.

A bill supported by the Duma’s Committee on Ecology in January 2026 would introduce mandatory registration and marking of all cats and dogs beginning September 1, 2026. Pet owners will submit their information to the state veterinary system (FGIS VetIS), and every animal must be physically identified — by collar, plastic tag, or subcutaneous microchip. Registration will be free, but owners bear the cost of marking, averaging 1,300 to 2,000 rubles (roughly $13–$20) in Moscow.

The urgency is clear from the numbers. Russia has an estimated 80 million domestic pets, but only about 30% are vaccinated — a figure that authorities say cannot improve without a unified federal tracking system. The law’s language also leaves room to expand beyond cats and dogs to ferrets, mini-pigs, and exotic pets in the future.

The vaccination gap is not just a Russian problem. It underscores a global reality: without knowing how many pets exist and who owns them, public health campaigns — from rabies prevention to parasite control — operate in the dark.

The United Kingdom’s War on Puppy Farms

Across the English Channel, the United Kingdom published its Animal Welfare Strategy on December 22, 2025 — described by Defra as the “biggest animal welfare reforms in a generation.” The strategy’s most emotionally charged provision targets puppy farming, the practice of keeping breeding dogs in appalling conditions, overbreeding them, and denying proper veterinary care.

The government will consult on reforming dog breeding practices to end puppy farming, with public consultations launched in early 2026. The RSPCA and Association of Cats and Dogs Homes have been lobbying for licensing of rescue centres and rehoming organisations, arguing that the unregulated rescue sector can inadvertently enable poor welfare. Additional measures include a proposed ban on electric shock collars and new requirements for pet sellers.

The strategy arrives as the RSPCA reports that more than 1,200 animals are currently housed in private boarding facilities at the charity’s expense because its own rescue centres are full — a sign that the demand for animal welfare services continues to outpace capacity.

Bolivia’s Street Dog Crisis Forces Action

Half a world away, the city of El Alto, Bolivia — perched at 4,000 meters above sea level on the Altiplano — is grappling with a crisis of a different kind. Of the approximately 270,000 dogs in the municipality, an estimated 100,000 roam the streets. Nationally, 8 out of every 10 dogs in Bolivia are “semi-domesticated” — they have an owner and a home, but spend much of their time unsupervised outdoors.

In March 2026, El Alto’s municipal government began socializing a draft law on responsible pet ownership with local institutions including the Forest and Environmental Preservation Police and the Departmental Health Service. The legislation would mandate pet registration and introduce sanctions to curb overpopulation, updating an existing municipal ordinance that authorities describe as inadequate.

The contrast with Europe is stark. While the Netherlands debates which cat breeds to ban and the EU designs continent-wide microchip databases, Bolivia is still trying to establish the most basic framework for knowing which dogs belong to whom. But the underlying challenge is the same everywhere: without registration, there is no accountability, and without accountability, animal welfare remains aspirational.

Parasites Don’t Respect Borders Either

In the United States, the threat isn’t regulatory but biological. The Companion Animal Parasite Council (CAPC) released its 2026 forecast in March, warning that vector-borne disease risk continues to expand geographically — and the organization’s forecasts have historically been 94% accurate.

Lyme disease, transmitted by blacklegged ticks, is spreading beyond its traditional strongholds in the Northeast and Upper Midwest into Ohio, Kentucky, West Virginia, Tennessee, and the Carolinas, with continued westward movement into the Northern Plains. Heartworm disease remains entrenched in the Southeast but is pushing northward along the Mississippi River corridor and the Atlantic coast, with emerging pockets in the Mountain West and Northern California. Ehrlichiosis risk is sustained across the South and Southwest, driven by the northward expansion of lone star ticks.

“Areas of higher canine Lyme risk often mirror areas where people contract Lyme disease, reinforcing the One Health connection between pets, people, and the environment.”
— Companion Animal Parasite Council

The CAPC’s message is blunt: year-round parasite prevention is no longer optional, regardless of geography. The old assumption that northern climates offered a winter reprieve from ticks and mosquitoes is increasingly obsolete. For the 83% of American pet owners who report that rising living expenses are a top source of stress, this creates a painful trade-off — preventive care costs money, but treating heartworm or Lyme disease costs far more.

Innovation on the Horizon

Not all the news is about threats and regulations. Elanco Animal Health received USDA approval in January 2026 for TruCan Ultra B (Oral), the first oral Bordetella vaccine formulated at a half-milliliter volume — a significant advance for dogs and owners who dread the traditional intranasal kennel cough vaccination. Built with Elanco’s PureFil technology to reduce adverse reactions, the vaccine launched in Q1 2026.

In Spain, the Purina PRO PLAN Calming Care Symposium held on March 13 brought together veterinary professionals to explore the gut-brain axis — the emerging science of how a pet’s digestive microbiome influences behavior, stress responses, and mental well-being. The symposium examined how specific probiotics can modulate canine anxiety, a topic that resonates as behavioral problems remain one of the leading reasons pets are surrendered to shelters.

And in China, where the pet market surpassed 300 billion yuan ($41 billion) in 2024 and is projected to reach 361 billion yuan by 2026, the Beijing International Pet Fair drew over 1,500 exhibitors across 150,000 square meters in March. The event featured the 7th Chinese Pet Preventive Medicine Forum, focusing on stress management, behavioral health, and gut health — themes that echo the European symposium and suggest a global convergence in how we think about pet wellness.

Meanwhile, Japan is quietly advancing pet disaster preparedness. On March 23, the All Japan Animal Professional Education Association signed an agreement with the city of Nobeoka in Miyazaki Prefecture on pet evacuation support during disasters — the latest step in a country that has been refining its approach since the 2011 tsunami left an estimated 30,000 animals in evacuation shelters. A separate survey by Ipet Insurance found that compliance with pet disaster preparedness guidelines remains low, prompting a complete overhaul of the company’s pet disaster resources in mid-March.

What It All Means for Pet Owners

The threads connecting these stories — from Amsterdam to El Alto, from the German-Russian border to the American Southeast — weave a single narrative. The era of casual, unregulated pet ownership is ending. Governments are building systems to track animals, restrict harmful breeding, and hold owners accountable. Diseases are shifting their geography, demanding year-round vigilance. And science is revealing that the bond between pets and their owners runs deeper than affection — it runs through the gut, the microbiome, and the nervous system.

For the estimated half-billion pet dogs and cats worldwide, 2026 may be remembered as the year the world stopped treating them as accessories and started treating them as what they are: members of the family who deserve the same thoughtfulness we bring to our own health, safety, and well-being.

Framer Crash Course 2026

This course will help you learn Framer as a beginner if you’re looking to get into Web Design. I go into how to start using Framer with Stacks, Rows, Framers, I cover components, effects and responsive design:

  • Chapter 1 – Framer Crash Course
  • Chapter 2 – Login and Setup Framer
  • Chapter 3 – Frames Stacks and Grids
  • Chapter 4 – Typography Color and Styling
  • Chapter 5 – Bonus Design Course
  • Chapter 6 – Components in Framer
  • Chapter 7 – Responsive Design
  • Chapter 8 – Content Management System (CMS)
  • Chapter 9 – Effects Animations and Transitions
  • Chapter 10 – Marketplace and Templates
  • Chapter 11 – Publishing Website

Youtube Video: Framer Crash Course 2026

Framer Crash Course Introduction

Framer in 2026 is one of the best website builders you can use, in this video I’m going to give you a crash course on how to get started using Framer as a beginner. Learn Framer from Scratch with this tutorial that will cover how to use frames, text, blocks, effects and much more. We will be recreating a website with responsive design, hover effects, rows and columns, lets begin!

Follow and support me:

Special thanks if you subscribe to my channel 🙂

Tech watch with AI: a concrete workflow and honest limitations

I had 47 RSS feeds. Yes, 47. Plus three daily newsletters, GitHub Trending bookmarked, and a half-open Twitter/X tab “just to follow a few devs”. The result: two hours per week scrolling, a vague sense of being up to date, and discovering in production a breaking change in a Go lib that I should have caught six weeks earlier.

I changed my approach. Not because AI is magic — it isn’t — but because the problem wasn’t the volume of information. It was that I was reading without synthesizing, consuming without retaining. I restructured my tech watch around that observation, and AI became a tool in the process, not the core of it.

The problem with traditional tech watch

GitHub Trending is useful for discovering interesting projects on a Friday evening. It’s a terrible source for tracking an ecosystem’s evolution. What surfaces there is whatever got a lot of stars that week — usually a well-marketed side project, a README generator with a slick demo, or an “awesome-something” resource list. Meaningful changes in the language itself, silent deprecations, API migrations: none of that shows up.

Newsletters are the same story. Golang Weekly sends 15 links per week. I’d read three in full, skim the titles of the rest, and feel like I’d done my homework. In reality, I was just collecting open tabs. The signal-to-noise ratio is poor because these aggregators optimize for engagement, not for relevance to your specific stack and current projects.

The real problem: we consume information passively, never asking ourselves “what does this actually change for me, concretely, this week?”. Nobody asks that question for you — unless you build a system that does.

The method in practice

I didn’t delete everything. I sorted out what deserved to stay as a primary source, and defined what would go through an AI filter.

What I kept, unfiltered:

What goes through AI:

  • Summarizing long changelogs (Go release notes sometimes run 3,000 words)
  • Detecting potential breaking changes against my specific stack
  • Targeted questions after reading an intriguing headline I don’t have time to dig into

The frequency is weekly, not daily. Daily is noise disguised as discipline. One structured session per week, with a concrete output (a markdown digest file), makes all the difference.

Prompts I actually use:

# After a Go release
"Here are the Go 1.25 release notes. My main work involves goroutines,
channels, sync/atomic, and the net/http package for REST APIs. Which changes
directly affect me? What deprecations should I plan for?
Give me a prioritized list, not a general summary."

# After a PostgreSQL update
"Here is the PostgreSQL 17.x changelog. My use cases: heavy JSONB queries,
partial indexes on tables with > 10M rows, pg_partman for partitioning.
What changes for me? Are there any behaviors that could alter existing
query plans?"

# For a one-off question
"In Go 1.24, what changed in garbage collector behavior compared to 1.22?
I'm specifically looking for the impact on high-allocation-frequency
applications (Kafka message processing)."

The difference from a Google search: I’m asking a question contextualized to my stack, not a generic one. The AI maps the raw changelog to my actual needs. That’s where the value is.

The automated workflow

After a few weeks of doing this manually, I wrote a bash script that runs as a cron job every Sunday morning. It fetches sources, builds a prompt, calls the Claude API, and generates a digest file in ~/veille/.

#!/bin/bash
# weekly-digest.sh — Automated tech watch
# Requires: ANTHROPIC_API_KEY as an environment variable
# Usage: chmod +x weekly-digest.sh && ./weekly-digest.sh

set -euo pipefail

DIGEST_DIR="$HOME/veille"
DATE=$(date +%Y-%m-%d)
OUTPUT="$DIGEST_DIR/digest-$DATE.md"
mkdir -p "$DIGEST_DIR"

echo "=== Tech watch digest — $DATE ===" > "$OUTPUT"
echo "" >> "$OUTPUT"

# --- Fetch Go release notes (official releases page) ---
echo "[*] Fetching Go release notes..."
GO_RELEASES=$(curl -s "https://go.dev/doc/devel/release" 
    | grep -oP '(?<=<h2 id=")[^"]+' 
    | head -5)

# Fetch the text content of the latest release note
LATEST_GO=$(echo "$GO_RELEASES" | head -1)
GO_CONTENT=$(curl -s "https://go.dev/doc/go${LATEST_GO#go}" 2>/dev/null 
    || curl -s "https://tip.golang.org/doc/go${LATEST_GO#go}" 2>/dev/null 
    || echo "Content unavailable via curl — see https://go.dev/doc/devel/release")

# --- Fetch PostgreSQL changelog ---
echo "[*] Fetching PostgreSQL changelog..."
PG_CONTENT=$(curl -s "https://www.postgresql.org/docs/release/" 
    | grep -A 2 'class="title"' 
    | grep -oP '(?<=>)[^<]+' 
    | head -20 
    | tr 'n' ' ')

# --- Build the prompt ---
PROMPT="You are a tech watch assistant for a senior Go/PostgreSQL/PHP developer.

Here is the information retrieved this week:

## Go — Recent releases
$GO_RELEASES

## PostgreSQL — Recent versions
$PG_CONTENT

My main stack:
- Go: REST APIs, goroutines/channels, sync/atomic, net/http, kafka-go
- PostgreSQL: JSONB, partial indexes, partitioning, pg_partman
- PHP/Symfony: secondary APIs, batch processing

Generate a structured weekly digest with:
1. Go changes that directly affect me (if a recent release exists)
2. PostgreSQL changes to watch
3. Watch points / potential breaking changes
4. What I can safely ignore this week

Format: Markdown. Be concise and prioritized. If you don't have enough info on a specific version, say so clearly rather than making things up."

# --- Anthropic API call ---
echo "[*] Calling Claude API..."
RESPONSE=$(curl -s https://api.anthropic.com/v1/messages 
    -H "x-api-key: $ANTHROPIC_API_KEY" 
    -H "anthropic-version: 2023-06-01" 
    -H "content-type: application/json" 
    -d "{
        "model": "claude-opus-4-6",
        "max_tokens": 1024,
        "messages": [
            {
                "role": "user",
                "content": $(echo "$PROMPT" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
            }
        ]
    }")

# Extract the response text
DIGEST_CONTENT=$(echo "$RESPONSE" | python3 -c "
import json, sys
data = json.load(sys.stdin)
if 'content' in data and len(data['content']) > 0:
    print(data['content'][0]['text'])
else:
    print('API error:', data.get('error', {}).get('message', 'Unexpected response'))
    print('Raw:', json.dumps(data, indent=2))
")

# --- Write the digest ---
echo "$DIGEST_CONTENT" >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "---" >> "$OUTPUT"
echo "*Generated on $DATE — verify primary sources before taking action.*" >> "$OUTPUT"

echo "[OK] Digest written to $OUTPUT"

To automate it every Sunday at 8am:

# crontab -e
0 8 * * 0 ANTHROPIC_API_KEY=your_key_here /path/to/weekly-digest.sh >> /var/log/veille.log 2>&1

Note: I put the API key directly in the cron rather than in a .env to avoid sourcing a file in a cron context. On a shared server, use a credentials file with proper permissions (chmod 600) instead.

The digest opens automatically in my editor on Sunday morning via another cron line. Ten minutes of focused reading instead of two hours of scrolling.

What it actually changes

Three real examples since I started using this workflow:

sync/atomic in Go: the digest flagged the changes in the sync/atomic package early enough — the introduction of generic types (atomic.Int64, atomic.Pointer[T]). I had code using the low-level functions (atomic.AddInt64) in a metrics counter. I was able to plan the migration calmly, before it became invisible technical debt.

PostgreSQL JSONB: the query planner changes around JSONB in PG16/17 have implications for indexes. Without the digest, I’d probably have discovered the changed behavior reading a confusing EXPLAIN ANALYZE on a Tuesday night at 11pm. With the digest, I read the release note and adjusted my indexes ahead of time.

The main gain isn’t detection: it’s the mindset. I no longer read changelogs in anxious mode — “did I miss something important?” I have a process. That changes your relationship with information.

The real limitations

It would be dishonest not to address these. AI in this workflow has genuine blind spots.

Hallucinations on version numbers. This is the number one problem. Claude — like all LLMs — can invent a version number, conflate two releases, or assert that a feature has been available since Go 1.21 when it actually landed in 1.23. The rule: the digest is a starting point, never a source of truth. Every point flagged as important must be verified in the official release note before acting on it. I added an explicit instruction in the prompt (“if you don’t have enough info on a specific version, say so clearly”) — it helps, but doesn’t eliminate the risk.

Confirmation bias. When I ask “what affects my Go stack”, the AI tends to tell me what it thinks I want to hear. If I work heavily with channels, it will over-index on concurrency changes. It won’t spontaneously tell me that the real novelty in a release is an improvement to the profiling tooling — if I haven’t mentioned that I care about it. The prompt needs regular calibration to avoid building an echo chamber.

What it doesn’t replace. A GopherCon conference is three days of hearing people dealing with problems at a scale I haven’t hit yet, and understanding how they solved them. No digest replaces that. A senior colleague saying “watch out, I tried that approach in 2023 and it bites” — that either. And reading a post-mortem in full, with the timeline, the decisions made under pressure, the mistakes owned up to: that’s a form of knowledge transfer that doesn’t survive a summary.

Cost and dependency. The Anthropic API costs money. Not much for a weekly digest (a few cents per call with claude-opus-4-6), but it’s an external service with its own availability and pricing uncertainties. And if the API changes, the script breaks.

The risk of no longer really reading. This is the most insidious one. Delegating synthesis means risking delegating understanding as well. If I never read a release note in full again, I’ll lose the eye for detail, the ability to spot what matters on my own. The digest must stay an intake filter, not a substitute for reading.

What it replaces, and what it doesn’t

This workflow replaces reading 3,000-word raw changelogs when I’m looking for two specific pieces of information. It also replaces manually synthesizing ten articles that all say the same thing in different words. It freed me from the obligation to read everything for fear of missing something.

It doesn’t replace curiosity. If I don’t ask “what changed in Go’s memory management over the last two versions”, no script will ask it for me. AI executes a process — it doesn’t generate one.

It doesn’t replace experimentation. Truly understanding a change in the Go scheduler means writing a benchmark, observing the behavior — not reading a summary.

It doesn’t replace conversations between developers. The most useful tech watch I did this year was a thirty-minute conversation with another dev who had migrated a large PostgreSQL database to native partitioning. No LLM could have given me the same nuance on what went wrong and why.

The real meta-observation: tech watch has always been a question of method. The best developers I know never had 47 RSS feeds — they had three carefully chosen sources they actually read. AI hasn’t changed that fundamental principle. It just made it more visible by forcing me to formalize what I wanted to learn, for whom, and at what frequency. That might be the most lasting contribution.

MiniStack v1.0.4: API Gateway v2, Lambda Warm Workers, SNS SQS Fanout, State Persistence

MiniStack is a free, open-source, MIT-licensed drop-in replacement for LocalStack — 21 AWS services on a single port, no account, no license key, no telemetry.

v1.0.4 is out today. This post covers everything that landed across the v1.0.2–v1.0.4 wave: the big features, the architectural decisions behind them, and the fixes that got us to a clean 379-test run.

docker run -p 4566:4566 nahuelnucera/ministack

Why this exists

LocalStack moved its core services behind a paid plan. If you were using LocalStack Community for local dev and CI/CD, you now hit a paywall for S3, SQS, Lambda, and most things that matter.

MiniStack covers the same surface — and goes further in a few areas — at $0, MIT licensed, forever. The full comparison is on ministack.org, but the short version: same developer experience, 150 MB image vs ~1 GB, ~30 MB RAM at idle vs ~500 MB, ~2 s startup vs 15–30 s.

What shipped in v1.0.2–v1.0.4

API Gateway HTTP API v2 — full control plane + data plane

This was the biggest missing piece. v1.0.2 delivered the complete API Gateway v2 implementation.

Control plane covers the full resource tree:

  • APIs: CreateApi, GetApi, GetApis, UpdateApi, DeleteApi
  • Routes: full CRUD, including {param} path parameter placeholders and {proxy+} greedy matching
  • Integrations: AWS_PROXY (Lambda) and HTTP_PROXY (arbitrary HTTP backends)
  • Stages, Deployments, Authorizers (JWT + Lambda), Tags

Data plane is the part most emulators skip. In MiniStack, execute-api requests are dispatched by host header — {apiId}.execute-api.localhost — before normal service routing. That means your actual API calls hit the right Lambda function with a proper payload format 2.0 envelope:

import boto3

apigw = boto3.client("apigatewayv2", endpoint_url="http://localhost:4566",
                     aws_access_key_id="test", aws_secret_access_key="test",
                     region_name="us-east-1")

api = apigw.create_api(Name="my-api", ProtocolType="HTTP")
api_id = api["ApiId"]

apigw.create_route(ApiId=api_id, RouteKey="GET /hello")
apigw.create_integration(
    ApiId=api_id,
    IntegrationType="AWS_PROXY",
    IntegrationUri=f"arn:aws:lambda:us-east-1:000000000000:function:my-func",
    PayloadFormatVersion="2.0",
)

import requests
resp = requests.get(f"http://{api_id}.execute-api.localhost:4566/hello")
print(resp.json())

Route matching supports path parameters and {proxy+} greedy segments. There was a subtle bug in the initial implementation: re.escape was applied before {param} substitution, which meant every parameterised route silently fell through to a 404. Fixed in v1.0.2.

Authorizers ship with full CRUD — JWT and Lambda authorizer types, with identitySource stored and returned as an array of strings matching the AWS spec (was incorrectly a single string in the initial cut).

Lambda warm/cold start worker pool

Prior to v1.0.2, every Lambda invocation spawned a fresh subprocess. That’s fine for correctness but misses a whole class of bugs that only appear when your handler module is imported once and invoked repeatedly.

core/lambda_runtime.py now maintains a persistent Python subprocess per function. The handler module is imported on first invocation (cold start), and subsequent calls reuse the warm worker without re-importing. Workers respawn automatically on crash.

This matters for three reasons:

  1. Correctness — module-level state (caches, connection pools, counters) behaves the same as in real Lambda
  2. Speed — warm invocations are significantly faster in CI
  3. Bug surface — you’ll catch issues with global state that a fresh-subprocess model would mask
import boto3

_client = None

def handler(event, context):
    global _client
    if _client is None:
        _client = boto3.client("s3", endpoint_url="http://localhost:4566",
                               aws_access_key_id="test", aws_secret_access_key="test",
                               region_name="us-east-1")
    return {"buckets": [b["Name"] for b in _client.list_buckets()["Buckets"]]}

In MiniStack, that _client initialization happens exactly once per function, just like AWS.

SNS → SQS fanout and SNS → Lambda dispatch

sqs protocol subscriptions now deliver messages directly to SQS queues with the standard SNS JSON notification envelope. lambda protocol subscriptions invoke the Lambda function via _execute_function() with a Records[].Sns event structure. Both were stubs in v1.0.1 — SNS→SQS was wired in v1.0.2, SNS→Lambda was a no-op that got fixed in the same release.

sns = client("sns")
sqs = client("sqs")

topic = sns.create_topic(Name="events")["TopicArn"]
queue = sqs.create_queue(QueueName="consumer")
queue_url = queue["QueueUrl"]
queue_arn = sqs.get_queue_attributes(
    QueueUrl=queue_url, AttributeNames=["QueueArn"]
)["Attributes"]["QueueArn"]

sns.subscribe(TopicArn=topic, Protocol="sqs", Endpoint=queue_arn)
sns.publish(TopicArn=topic, Message="hello fanout")

msgs = sqs.receive_message(QueueUrl=queue_url)
body = json.loads(msgs["Messages"][0]["Body"])
print(body["Message"])  # hello fanout

Fanout is synchronous within the same process — consistent with how LocalStack handles it and good enough for unit/integration testing.

SQS → Lambda event source mapping

Full ESM lifecycle: CreateEventSourceMapping, DeleteEventSourceMapping, GetEventSourceMapping, ListEventSourceMappings, UpdateEventSourceMapping.

A background poller picks up messages from the configured SQS queue and delivers them to the target Lambda as batched events. Batch size and enabled state are configurable.

lam = client("lambda")
sqs = client("sqs")

queue_url = sqs.create_queue(QueueName="trigger-queue")["QueueUrl"]
queue_arn = sqs.get_queue_attributes(
    QueueUrl=queue_url, AttributeNames=["QueueArn"]
)["Attributes"]["QueueArn"]

lam.create_event_source_mapping(
    EventSourceArn=queue_arn,
    FunctionName="my-processor",
    BatchSize=10,
    Enabled=True,
)

sqs.send_message(QueueUrl=queue_url, MessageBody=json.dumps({"event": "order_placed"}))

State persistence

PERSIST_STATE=1 enables atomic state snapshots to disk. Writes go to a temp file first, then rename — so a crash mid-write doesn’t corrupt the saved state. STATE_DIR controls where (default /tmp/ministack-state).

API Gateway state is fully persisted across container restarts. The persistence framework is designed so other services can adopt the same get_state() / load_persisted_state() pattern incrementally.

The reset endpoint (POST /_ministack/reset) clears in-memory state and, when PERSIST_STATE=1, also deletes STATE_DIR/*.json and S3_DATA_DIR contents — so a restart doesn’t reload stale state. Also used in the test suite as a session-scoped autouse fixture to keep tests idempotent across repeated runs.

DynamoDB TTL enforcement

TTL was previously stored — TimeToLiveSpecification accepted and returned without error — but never acted on. Items just sat there forever. A background daemon thread (dynamodb-ttl-reaper) now scans all tables every 60 seconds and deletes items whose TTL attribute value is ≤ current epoch time.

Lambda Function URLs

Full CRUD: CreateFunctionUrlConfig, GetFunctionUrlConfig, UpdateFunctionUrlConfig, DeleteFunctionUrlConfig, ListFunctionUrlConfigs. State persisted in _function_urls. Was a 404 stub before.

SQS queue URL portability (v1.0.4)

QueueUrl values now read MINISTACK_HOST and GATEWAY_PORT env vars instead of hardcoding localhost:4566. This was causing silent failures in CI environments where MiniStack runs as a service container with a network alias.

services:
  ministack:
    image: nahuelnucera/ministack
    environment:
      MINISTACK_HOST: ministack
      GATEWAY_PORT: 4566
  app:
    environment:
      AWS_ENDPOINT_URL: http://ministack:4566

Before this fix, queue URLs returned http://localhost:4566/... regardless of configuration, and any SQS operation using that URL from another container would fail.

Bug fixes worth calling out

Several of these look fine in smoke tests but break real workloads.

execute-api credential scope misrouted to lambda — In core/router.py, the credential scope for execute-api requests was mapped to lambda instead of apigateway. Any data plane request was dispatched to the Lambda handler instead of the API Gateway data plane. Fixed in v1.0.2.

routeKey always "$default" in Lambda proxy events — The routeKey field was hardcoded to "$default" regardless of which route was matched. If your handler branched on event["routeKey"] — common in single-function routers — every request hit the default branch. Fixed to reflect the actual matched route key (e.g. "GET /users/{id}").

identitySource wrong type on Authorizers — Stored and returned as a plain string instead of an array of strings. boto3 raised a shape validation error on the response. Now returns ["$request.header.Authorization"] as the AWS spec requires.

DeleteFunctionUrlConfig returning {} body on 204 — boto3 expects an empty body on 204. The non-empty body caused a RemoteDisconnected exception. Fixed to return a true empty 204.

/_ministack/reset not cleaning disk — When PERSIST_STATE=1, reset cleared in-memory state but left STATE_DIR/*.json and S3_DATA_DIR intact. On the next restart, old state was reloaded. Fixed to delete persisted files as well.

Test idempotency — Tests with hardcoded resource names failed on a second run because the resources already existed. Fixed by wiring POST /_ministack/reset into a session-scoped autouse fixture in conftest.py.

Test suite: 54 → 379

v1.0.1 shipped with 54 integration tests. v1.0.4 has 379, all passing against both the in-process server and the Docker image.

The growth came from:

  • 10 new tests covering previously untested paths: health endpoint, STS GetSessionToken, DynamoDB TTL, Lambda warm start, API Gateway execute-api Lambda proxy, $default catch-all, path parameter matching, 404 on missing route, EventBridge → Lambda dispatch
  • 25 new tests for operations added post-v1.0.1: Kinesis shard split/merge, SSM label/tag operations, CloudWatch Logs retention/subscription/metric filters/Insights, CloudWatch composite alarms, EventBridge archives/permissions, DynamoDB UpdateTable, S3 versioning/encryption/lifecycle/CORS/ACL, Athena workgroup and batch operations
  • Full coverage of all v1.0.2 features: API Gateway control + data plane, SNS→SQS fanout, SQS→Lambda ESM, Lambda warm start, persistence, reset

Tests run against the Docker image — no mocking, no monkeypatching, real boto3 calls over the wire.

What’s still on the roadmap

  • API Gateway REST API (v1)
  • Cognito — user pools, sign-up/sign-in
  • Route53 — hosted zones, record sets
  • ACM — certificate management
  • Firehose
  • Virtual-hosted style S3 (bucket.localhost:4566 routing)

Getting started

docker run -p 4566:4566 nahuelnucera/ministack

# With persistence and Redis sidecar
git clone https://github.com/Nahuel990/ministack
cd ministack
docker compose up -d

curl http://localhost:4566/_localstack/health

Works with boto3, AWS CLI, Terraform, CDK, Pulumi. Point endpoint_url at http://localhost:4566, credentials test/test, and you’re done.

GitHub: github.com/Nahuel990/ministack
Docker Hub: hub.docker.com/r/nahuelnucera/ministack
Site: ministack.org

Stars, issues, and PRs welcome. Each service is a single self-contained Python file — adding a new one is straightforward.

7 Years of Angular Made Me Realize I Don’t Actually Know Web Development

I used to introduce myself as “a Senior Angular Developer.”

Seven years of components, RxJS streams, NgModules, Signals, Nx monorepos, CI pipelines, performance audits — the whole thing.

On paper, I looked production‑ready.

Then I started building my own AI‑driven SaaS.

No corporate backend team. No DevOps department. No “someone else” handling auth, storage, or migrations.

Just me, Supabase, Stripe, AI integrations… and a lot of gaps I didn’t know I had.

Suddenly it became painfully obvious:

I know how to operate Angular.

I don’t really know the web — and it’s actively blocking me.

My AI SaaS Forced Me to Wear a Backend Hat

On client projects, there’s always a safety net.

You have a backend squad, a DevOps person, maybe a database architect. I could stay in my lane: fix Angular apps generalists broke, do Component Detoxes , tame Signals, squeeze TBT and LCP, and ship features.

On my own product, there is no “lane”. It’s just reality:

  • AI‑driven SaaS that needs real users ,
  • real payments,
  • real dashboards,
  • and real‑time data.

No one else is coming to wire it together.

I picked Supabase to move fast. “Serverless Postgres with auth, storage, and real‑time built in” sounded perfect.

Except here’s what that actually meant in practice.

The Non‑Angular Concepts That Exposed Me

Here’s the exact breakdown of the non‑Angular and advanced web development concepts I had to learn/use for this project — and where the lack of them slowed me down.

1. Backend, Database, and Real‑time Infrastructure

Even though I’m not writing a custom C# or Node API, I still had to wear the Backend Developer hat.

PostgreSQL & database design

I’m using Supabase, which means:

  • designing tables for things like orders, settings, s_ubscriptions_,
  • deciding how relations should work,
  • thinking about migrations and how to evolve the schema without breaking production.

This isn’t “just clicking in the UI”. It’s real database design.

Seven years of Angular didn’t prepare me for writing a schema that won’t bite me six months from now.

Real‑time WebSockets

In my orders.service.ts, the app subscribes to live database changes via something like:

this.supabase
  .channel('public:orders')
  .on('postgres_changes', { event: '*', schema: 'public', table: 'orders' }, ...)
  .subscribe();

This isn’t Angular magic.

It’s WebSockets, pub/sub, and real‑time event streams.

To use it well, you need to understand:

  • how channels work,
  • what happens when the network drops,
  • how to avoid memory leaks and duplicate subscriptions,
  • how to reconcile real‑time updates with local state.

Angular gives me Observables. Supabase gives me events.

But thinking through real‑time architecture? That’s on me.

Cloud storage

I’m handling file uploads (car photos, documents) to Supabase Storage buckets:

  • dealing with signed URLs,
  • thinking about public vs private buckets,
  • handling failures and retries,
  • understanding multipart form data and file sizes.

Again: none of this lives in angular/core.

It’s just the web.

Authentication & Row Level Security

Securing the database isn’t just “turn on auth”.

I’m writing PostgreSQL RLS policies so malicious users can’t:

  • query other people’s data,
  • bypass my frontend checks,
  • abuse the public endpoints.

That’s real backend security.

Angular can’t save you if your policies are wrong.

The Hard Truth: I Only Know Angular

Here’s the part I’m not proud of:

I only know Angular.

That’s it. No React, no Svelte, no mobile, no real backend stack.

Seven years in and I basically have one tool.

It’s a powerful tool. I’ve done serious work with it.

But it’s still one tool.

It didn’t really matter when I was:

  • embedded in big teams,
  • focused on one side of the stack,
  • operating inside someone else’s architecture.

It matters a lot when:

  • I’m building my own product,
  • I’m responsible for the entire experience,
  • there is no “backend team” to blame.

Right now, my own lack of broader web skills is a bottleneck in my own company.

And that’s a stupid place to be.

Even My Own Ecosystem Is Pushing Me Out

There’s another uncomfortable trend: Angular freelance opportunities are just fewer.

And the ones that do show up often look like this:

  • “Angular + .NET”
  • “Angular + Java Spring”
  • “Full‑stack Angular dev (C#, SQL)”

That’s not where I want to go. I don’t want to become a .NET or Java backend engineer just to keep using the one framework I know.

So even inside my own ecosystem, the market is basically saying:

Being very good at just Angular isn’t enough anymore.

Bring backend, mobile, or something else to the table.

At the same time, I’ve just started my own solo company:

  • building AI‑driven SaaS ,
  • offering automation consulting.

Both of those need:

  • web that isn’t always Angular,
  • mobile that definitely isn’t Angular.

Right now, I can’t do either outside of Angular without a fight.

That’s not a nice‑to‑have problem anymore. That’s a strategy risk.

I’m Not Ditching AI Tools — I’m Changing How I Use Them

There’s one more twist.

I use Claude Code and Antigravity heavily. And I’m going to keep using them.

They’re not the problem. In fact, they’re the reason I can:

  • move fast with Supabase,
  • scaffold endpoints,
  • debug RLS policies,
  • sketch non‑Angular architecture without spending months reading docs.

The problem is who’s driving.

There are two ways to use tools like Claude Code:

  1. As the primary brain :

     — “Write the schema for me.”

     — “Design the RLS policies.”

     — “Give me a Supabase + Angular architecture.”

    You accept what it outputs, maybe tweak a bit, and move on.

  2. As a turbocharger for your own thinking :

     — You decide on the shape of the schema,

     — you define the security model,

     — you outline the architecture…

    Then you ask the tool to implement, optimize, or challenge your idea.

Right now, in pure Angular land, I’m in group 2.

I know what “good” looks like. I use the tools to get there faster.

Outside Angular? I can feel myself slipping into group 1.

That’s dangerous.

I don’t want to be the founder who outsources the core architecture of his own SaaS to a chatbot.

What “Fixing My Stack” Actually Means

So when I say I want to “fix my stack fast”, I don’t mean:

  • memorizing every CSS property manually,
  • hand‑coding everything from scratch without help,
  • pretending I don’t have AI in my toolbox.

I mean something much more specific:

I want to understand web and backend fundamentals well enough

that Claude Code and Antigravity are implementation accelerators ,

not architecture substitutes.

Concretely, that means:

1. Owning my Supabase architecture

  • Designing tables and relations myself, then asking Claude to sanity‑check.
  • Writing my own RLS policies first, then asking the tool to fuzz them for edge cases.
  • Being able to explain why a real‑time channel is wired in a certain way, not just “because the docs said so.”

2. Treating frontend as “web”, not “only Angular”

  • Building some flows without Angular at all, just to refresh my mental model of the DOM and browser APIs.
  • Understanding what the browser is doing before Angular boots.
  • Caring about semantic HTML, accessibility, and CSS performance as much as I care about Signals and change detection.

3. Adding at least one non‑Angular delivery surface

My AI SaaS and automation consulting both need:

  • a marketing site,
  • a simple dashboard,
  • probably a mobile touchpoint at some point.

They don’t all need Angular.

I don’t need to become a React influencer overnight.

But I do need to be able to say:

  • “This one is better as a minimal, framework‑less page.”
  • “This one can be a simple React/Next client.”
  • “This is the part Angular is actually good for.”

4. Using AI to test my understanding, not replace it

For example:

  • I design a schema → ask Claude Code: “Where will this break in 6 months?”
  • I write a security policy → ask it to “think like an attacker and break it.”
  • I sketch a simple SPA without Angular → ask it to critique my state handling.

If I can’t independently evaluate the feedback, that’s a red flag.

That’s the gap I need to close.

Senior Means Being Bigger Than Your Framework

I still fix the Angular apps generalists break.

I still offer surgical Angular interventions as micro‑engagements.

I still like being the person you call when your 500‑line component is blocking an entire release.

But building my own AI‑driven SaaS forced me to admit something:

I became a senior operator of a single framework.

I didn’t become a senior web developer.

Seven years of Angular got me very far.

It paid well. It built my reputation. It opened doors.

Now it’s also the thing that can quietly cap my upside if I let it.

So this is the reboot:

  • keep Angular as my sharpest tool ,
  • rebuild my foundation as an actual web developer,
  • use Claude Code and Antigravity as force multipliers , not autopilots,
  • and make sure my own product doesn’t get blocked by the limits of my comfort zone.

If you’ve spent years living inside one framework, this isn’t an accusation.

It’s a status report from someone in the same position.

Your turn:

What part of your stack is quietly bottlenecking you — and are you driving your tools, or are they driving you?

I fix the Angular apps that generalists break.

Karol Modelski is a senior Angular developer and frontend architect rescuing legacy B2B SaaS frontends.

If your Angular app is slowing your team down, start here: https://www.karol-modelski.scale-sail.io/

Self-Host Speech-to-Text and Use It as Your iPhone Keyboard in 3 Commands

If you’re running a homelab, you’ve probably already got speech-to-text somewhere in your stack.

Maybe you use it for Home Assistant voice commands. Or local LLM integrations. Or just transcribing meeting recordings.

Here’s something you might not have considered: you can use that same transcription server as a keyboard on your iPhone.

The 3 Commands

git clone https://github.com/omachala/diction
cd diction
docker compose up -d

That’s the server running. Now install Diction on your iPhone, point it at your server URL, and you have a voice keyboard backed by your own speech-to-text instance.

What’s Actually Running

The Docker Compose setup spins up two services:

services:
  gateway:
    image: ghcr.io/omachala/diction-gateway:latest
    ports:
      - "8080:8080"

  whisper-small:
    image: fedirz/faster-whisper-server:latest-cpu
    environment:
      WHISPER__MODEL: Systran/faster-whisper-small
      WHISPER__INFERENCE_DEVICE: cpu

whisper-small: the transcription engine — runs open-source speech-to-text via a REST API. CPU works fine for real-time dictation.

gateway: Diction’s open-source Go gateway. Handles communication between the iOS app and the transcription backend — routing, streaming, audio format conversion.

The gateway exposes port 8080. That’s the URL you put into the Diction app.

Making It Accessible From Your Phone

Your phone needs to reach your server. A few options:

Tailscale (easiest): Install Tailscale on both your server and iPhone. You get a private IP accessible from anywhere. No port forwarding, no firewall rules.

http://100.x.x.x:8080

Reverse proxy (for existing homelabbers): If you’re already running Caddy, nginx, or Traefik, add a route to port 8080. Get a subdomain, TLS, the whole thing.

https://diction.yourdomain.com

Direct LAN (simplest for home-only use): Just use your server’s local IP. Works on home WiFi, not outside.

http://192.168.1.100:8080

Configuring Diction

Open the Diction app → Settings → Backend → Self-Hosted.

Enter your server URL. The app tests the connection and shows a green indicator when it’s reachable.

That’s it. The keyboard is now connected to your server.

Choosing a Model

You can swap the transcription model by changing the WHISPER__MODEL environment variable on the speech-to-text container. The model downloads automatically on first use.

Size RAM Speed Notes
Small ~800MB ~3-4s Good default for everyday dictation
Medium ~1.8GB ~8-12s Better with accents and background noise
Large ~3.5GB ~20-30s Highest accuracy, needs a beefy CPU or GPU

For a home server or NAS, the small model is a solid starting point. If you have a GPU, the large model gives you transcription quality that rivals most paid services.

Swap the model in your compose file:

  whisper-small:
    image: fedirz/faster-whisper-server:latest-cpu
    environment:
      WHISPER__MODEL: Systran/faster-whisper-medium
      WHISPER__INFERENCE_DEVICE: cpu

Or add multiple model containers and set DEFAULT_MODEL on the gateway to pick which one handles requests.

Running on Lower-Power Hardware

The small model runs well on modern CPUs. For lower-power devices like a NAS or a Raspberry Pi, try the tiny model variant — it uses less RAM (~350MB) and responds faster, at the cost of some accuracy.

For real-time keyboard use, aim for sub-3 second latency. The small model on a modern CPU or the tiny model on lower-power hardware gets you there.

The App

Diction is an iOS voice keyboard. Download it, enable it in Settings → General → Keyboard → Keyboards, grant Full Access, and connect to your server.

Self-hosted mode is free with no word limits or restrictions. There’s also a cloud option (Diction One) for users who don’t want to run their own server.

Download on the App Store · diction.one · github.com/omachala/diction