<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fascia</title>
    <description>The latest articles on Forem by Fascia (@fasciarun).</description>
    <link>https://forem.com/fasciarun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3789549%2F874f000d-5742-453c-8418-82ebff4db5da.png</url>
      <title>Forem: Fascia</title>
      <link>https://forem.com/fasciarun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fasciarun"/>
    <language>en</language>
    <item>
      <title>Before You Pick a Backend Platform, Ask These Questions</title>
      <dc:creator>Fascia</dc:creator>
      <pubDate>Fri, 06 Mar 2026 14:58:03 +0000</pubDate>
      <link>https://forem.com/fasciarun/before-you-pick-a-backend-platform-ask-these-questions-526d</link>
      <guid>https://forem.com/fasciarun/before-you-pick-a-backend-platform-ask-these-questions-526d</guid>
      <description>&lt;p&gt;I've been building a backend platform for the past year. And before that, I shipped two products on platforms that eventually made decisions I didn't like.&lt;/p&gt;

&lt;p&gt;Parse got shut down. Heroku killed its free tier. PlanetScale dropped its free plan with 30 days notice. If you've been around long enough, you have a story like this.&lt;/p&gt;

&lt;p&gt;The risk isn't hypothetical. Platforms die, pivot, or cut tiers. And when they do, you find out exactly how deep the dependency runs.&lt;/p&gt;

&lt;p&gt;So here are the questions I wish I'd asked before committing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does my data actually live?
&lt;/h2&gt;

&lt;p&gt;This is the most important question, and most platforms bury the answer.&lt;/p&gt;

&lt;p&gt;"Managed database" usually means their servers. Your users' data, business records, and application state are sitting in an infrastructure you don't control. You're trusting their security posture, their compliance certifications, and their word that they won't misuse it.&lt;/p&gt;

&lt;p&gt;For a side project, that's fine. For anything touching financial records, health data, or EU citizen data, it's a structural liability - not just a risk you can accept in a checkbox.&lt;/p&gt;

&lt;p&gt;Ask explicitly: Is my data in their cloud account or mine? If it's theirs, that's the baseline you're working from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to my running app if you shut down tomorrow?
&lt;/h2&gt;

&lt;p&gt;Think through the failure mode concretely. If the platform went offline right now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Would your warm, running instances keep serving requests? Or does every request depend on their control plane?&lt;/li&gt;
&lt;li&gt;Would cold starts fail? (They would if the executor needs to pull its configuration from the platform.)&lt;/li&gt;
&lt;li&gt;Would your app continue to work for hours? Days? Until the next cold start?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers tell you what your actual blast radius is. A platform that gives you warm instance continuity but breaks on cold start is a very different risk profile than one that goes down the moment their API does.&lt;/p&gt;

&lt;p&gt;There's no universally right answer here. But you should know what you're getting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I export everything I need to run independently?
&lt;/h2&gt;

&lt;p&gt;Data export is table stakes. Most platforms offer it. But data alone isn't enough to run your app.&lt;/p&gt;

&lt;p&gt;You also need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your application logic (in a format you can re-deploy)&lt;/li&gt;
&lt;li&gt;Your schema definitions&lt;/li&gt;
&lt;li&gt;Your configuration and secrets&lt;/li&gt;
&lt;li&gt;Your infrastructure setup (or the ability to recreate it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ask: If I exported today and had to rebuild on raw infrastructure, what would I need? How long would it take? What can't be exported?&lt;/p&gt;

&lt;p&gt;Some platforms make this easy. Others make it technically possible but practically painful. The platforms that can't answer this clearly are the ones to worry about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can't I do without you?
&lt;/h2&gt;

&lt;p&gt;Every platform has things you can only do through them. The question is whether you know what those things are upfront.&lt;/p&gt;

&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema migrations (if the platform manages your DB, do you control the migration tooling?)&lt;/li&gt;
&lt;li&gt;Spec or logic modifications (can you edit your application without the platform's build tooling?)&lt;/li&gt;
&lt;li&gt;Debugging and observability (are logs and traces in their system only?)&lt;/li&gt;
&lt;li&gt;Authentication flows (if their auth goes down, do your users lose access?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make a list. Not to avoid platforms with dependencies - that's impossible - but to understand what you're committing to.&lt;/p&gt;

&lt;h2&gt;
  
  
  How hard is the migration if I leave?
&lt;/h2&gt;

&lt;p&gt;Data portability and system portability are different things.&lt;/p&gt;

&lt;p&gt;Data portability means you can get a Postgres dump. Most platforms do this. It's a solved problem.&lt;/p&gt;

&lt;p&gt;System portability means you can re-run your application without the platform. That's harder. If your application logic lives as configurations in the platform's proprietary format, a database dump doesn't help much. You still need to rebuild the application.&lt;/p&gt;

&lt;p&gt;The question to ask: "If I had to migrate away in 30 days, what would the actual work be?" If they can't answer concretely, that's telling.&lt;/p&gt;

&lt;h2&gt;
  
  
  How some popular platforms compare
&lt;/h2&gt;

&lt;p&gt;These aren't exhaustive reviews. Just quick answers to the same questions, based on public documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase:&lt;/strong&gt; Your data lives in their managed Postgres (or you can self-host). If Supabase shuts down, the database is standard Postgres, so data export is straightforward. Auth, Edge Functions, and Realtime depend on their infrastructure. Migration effort is moderate: you keep the database, but need to replace their SDK layer. Open source, so self-hosting is a real option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Railway:&lt;/strong&gt; Your app runs on their infrastructure. Data lives in their managed databases. If Railway shuts down, you need to migrate both your app and database to another host. Export is possible but you're rebuilding deployment config from scratch. Migration effort is higher because the deployment layer is proprietary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase:&lt;/strong&gt; Data lives in Google's infrastructure (Firestore, RTDB). If Firebase changes pricing or drops features, you're migrating away from proprietary data formats. Auth is tightly coupled. Migration effort is high, because Firestore queries and security rules don't map cleanly to standard databases.&lt;/p&gt;

&lt;p&gt;Each platform makes different tradeoffs. None of these answers are inherently wrong. The point is knowing what they are before you commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Fascia answers these
&lt;/h2&gt;

&lt;p&gt;I'll be direct about how my project answers these questions, including the parts that aren't perfect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does the data live?&lt;/strong&gt; In the customer's own GCP project. Every workspace gets its own Cloud SQL instance. Fascia's servers never touch your business data - not in transit, not in storage. That's the whole point of BYOC (Bring Your Own Cloud).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if Fascia shuts down?&lt;/strong&gt; Warm Cloud Run instances keep running. Cold starts fail, because the executor fetches its spec bundle from Fascia's API by default. If you haven't prepared an exported bundle in advance, you can't spin up new instances. This is a real limitation. The file mode exists (one environment variable switch) but requires you to do the infrastructure work ahead of time, not after the platform is gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you export everything?&lt;/strong&gt; You can export the spec bundle - the structured definitions that drive execution. The executor itself is open Go code. The infrastructure is standard GCP resources. But you need to have done the export before you need it. If Fascia is down when you realize you need the bundle, you're stuck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can't you do without Fascia?&lt;/strong&gt; Modify your specs. The design tools (Chat Studio, Flow Studio) live on Fascia's servers. A system you can't evolve is a system with an expiration date. If Fascia disappears, your running app works until the next cold start - but you can't add features or fix logic without the platform. That's a significant dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How hard is the migration?&lt;/strong&gt; The spec format is readable JSON. The executor is Go. The database is standard Postgres. A technically capable team could rebuild the execution layer. But it's not a 30-minute project.&lt;/p&gt;

&lt;p&gt;One more honest note: Fascia is a solo-founder pre-launch project. The bus factor is 1. The specs are readable by anyone, the executor is deterministic, and the infrastructure is standard GCP - those choices were deliberate, partly because of this exact risk. But it's still a risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The universal takeaway
&lt;/h2&gt;

&lt;p&gt;Every platform should be able to answer these questions concretely. Not with "we take security seriously" or "we have 99.9% uptime" - but with specific, technical answers about what happens in each failure mode.&lt;/p&gt;

&lt;p&gt;If they can't, that's your answer.&lt;/p&gt;

&lt;p&gt;The platforms that can answer clearly - whatever their architecture choices are - are the ones that have thought through their own failure modes. That's a signal worth paying attention to.&lt;/p&gt;

&lt;p&gt;Pick the platform that fits your risk tolerance. Just make sure you know what you're tolerating.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>Design-Time Safety: How Fascia's Risk Engine Blocks Unsafe Patterns Before Deployment</title>
      <dc:creator>Fascia</dc:creator>
      <pubDate>Wed, 04 Mar 2026 09:24:15 +0000</pubDate>
      <link>https://forem.com/fasciarun/design-time-safety-how-fascias-risk-engine-blocks-unsafe-patterns-before-deployment-2ojj</link>
      <guid>https://forem.com/fasciarun/design-time-safety-how-fascias-risk-engine-blocks-unsafe-patterns-before-deployment-2ojj</guid>
      <description>&lt;p&gt;Runtime error handling is an admission that your design phase failed.&lt;/p&gt;

&lt;p&gt;If you catch a "payment processed but order not created" error at runtime, the real bug is that your design tool allowed a payment call outside a transaction boundary. The error handler is treating a symptom. The disease is in the architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Risk Levels
&lt;/h2&gt;

&lt;p&gt;Fascia's Risk Engine classifies every Tool (API endpoint) into three levels based on its flow graph patterns:&lt;/p&gt;

&lt;h3&gt;
  
  
  Green — Safe to Deploy
&lt;/h3&gt;

&lt;p&gt;All of the following must be true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only Entity Actions (create, update, transition, soft-delete) — no raw writes&lt;/li&gt;
&lt;li&gt;Explicit transaction boundary around all write operations&lt;/li&gt;
&lt;li&gt;No unbounded queries (all reads have pagination or limits)&lt;/li&gt;
&lt;li&gt;No external calls, OR external calls are outside transaction boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Yellow — Warning, Requires Acknowledgment
&lt;/h3&gt;

&lt;p&gt;Any of the following triggers Yellow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External call (payment, email, HTTP) inside a state transition&lt;/li&gt;
&lt;li&gt;Missing retry configuration on external nodes&lt;/li&gt;
&lt;li&gt;High row impact (&amp;gt; 100 rows in a single write operation)&lt;/li&gt;
&lt;li&gt;Read without explicit limit&lt;/li&gt;
&lt;li&gt;Missing timeout on external nodes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Red — Blocked, Cannot Deploy
&lt;/h3&gt;

&lt;p&gt;Any of the following triggers Red:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw write (SQL without Entity abstraction)&lt;/li&gt;
&lt;li&gt;Unbounded UPDATE (no WHERE clause or row limit)&lt;/li&gt;
&lt;li&gt;Payment call without rollback/compensation mechanism&lt;/li&gt;
&lt;li&gt;Missing transaction boundary around write operations&lt;/li&gt;
&lt;li&gt;Hard delete (instead of soft delete)&lt;/li&gt;
&lt;li&gt;External call with side effects inside a transaction boundary&lt;/li&gt;
&lt;li&gt;Circular dependency in flow graph (not a DAG)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Red signals cannot be acknowledged or dismissed. They must be resolved.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Design-Time, Not Runtime?
&lt;/h2&gt;

&lt;p&gt;The key insight: &lt;strong&gt;unsafe patterns are structural, not behavioral&lt;/strong&gt;. A payment call inside a transaction boundary is always wrong, regardless of the specific data flowing through it. You don't need to wait for runtime to discover this.&lt;/p&gt;

&lt;p&gt;By analyzing the flow graph statically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every developer sees the risk before deployment&lt;/li&gt;
&lt;li&gt;Non-technical stakeholders can understand "this endpoint is Yellow because it sends emails during state transitions"&lt;/li&gt;
&lt;li&gt;Audit logs show risk acceptance decisions, not just runtime errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Auto-Fix Suggestions
&lt;/h2&gt;

&lt;p&gt;When a risk signal is detected, the engine doesn't just flag it — it suggests the fix:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Suggested Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Missing transaction&lt;/td&gt;
&lt;td&gt;Wrap write nodes in a Transaction boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External call in transaction&lt;/td&gt;
&lt;td&gt;Move external call outside transaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing retry&lt;/td&gt;
&lt;td&gt;Add Retry node (max 3 attempts, exponential backoff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unbounded update&lt;/td&gt;
&lt;td&gt;Add WHERE condition or row limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment without error edge&lt;/td&gt;
&lt;td&gt;Add error edge to recovery flow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard delete&lt;/td&gt;
&lt;td&gt;Convert to soft delete (set &lt;code&gt;deleted_at&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Safety Agent (multi-model cross-check) validates these suggestions before presenting them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Execution Contract Enforces It
&lt;/h2&gt;

&lt;p&gt;Even if something slips past the Risk Engine, the 9-step execution contract provides defense in depth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 3 (Policy Check) catches budget/row-limit violations&lt;/li&gt;
&lt;li&gt;Step 6 (Enforce Invariants) catches business rule violations before commit&lt;/li&gt;
&lt;li&gt;Step 7 (Commit/Rollback) ensures all-or-nothing transactions&lt;/li&gt;
&lt;li&gt;Step 8 (Audit Log) records everything unconditionally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the goal is to catch problems at step 0 — before the code even exists.&lt;/p&gt;




&lt;p&gt;Next in this series: &lt;strong&gt;BYOC Architecture — Why Your Data Should Stay in Your Cloud&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fascia.run" rel="noopener noreferrer"&gt;fascia.run&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
      <category>backend</category>
    </item>
    <item>
      <title>AI-Generated Backends Break in Production. We Replaced Code with Specs.</title>
      <dc:creator>Fascia</dc:creator>
      <pubDate>Wed, 25 Feb 2026 18:51:54 +0000</pubDate>
      <link>https://forem.com/fasciarun/why-we-banned-llms-from-runtime-and-what-we-do-instead-7ck</link>
      <guid>https://forem.com/fasciarun/why-we-banned-llms-from-runtime-and-what-we-do-instead-7ck</guid>
      <description>&lt;p&gt;AI backend tools generate code. Fast. The problem is not how the code is generated - it's what's missing from the output.&lt;/p&gt;

&lt;p&gt;Generated code ships without structural guarantees. No enforced transaction boundaries. No mandatory audit logging. No invariant checks before commit. No risk classification before deployment.&lt;/p&gt;

&lt;p&gt;The code works until it doesn't, and when it breaks in production, you're debugging code you didn't write.&lt;/p&gt;

&lt;p&gt;We made a different choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Generated Code
&lt;/h2&gt;

&lt;p&gt;When an AI generates your backend code, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No structural safety&lt;/strong&gt;: Transaction boundaries are optional, not enforced. A payment can process while the order creation fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No audit trail&lt;/strong&gt;: Logging is ad-hoc. "What happened at 3am?" has no guaranteed answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden complexity&lt;/strong&gt;: 6 months later, nobody knows what the generated code does. Including the AI that wrote it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security gaps&lt;/strong&gt;: 45% of AI-generated code contains vulnerabilities (Stanford/UIUC). Not because the AI is bad - because code is too flexible a medium to guarantee safety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No rollback strategy&lt;/strong&gt;: External calls with side effects aren't separated from reversible operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For prototypes, this is fine. For production backends handling payments, reservations, and user data? It's a structural risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Alternative: Specs Instead of Code
&lt;/h2&gt;

&lt;p&gt;Fascia doesn't generate code. It generates structured &lt;strong&gt;specifications&lt;/strong&gt; - and executes them directly.&lt;/p&gt;

&lt;p&gt;When you describe your business in natural language, AI produces specs that define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entities&lt;/strong&gt;: Business objects with fields, relationships, status machines, and invariants&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: API endpoints with typed input/output, trigger types, and flow graphs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policies&lt;/strong&gt;: Design-time rules that block unsafe patterns before deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At runtime, a deterministic &lt;strong&gt;executor&lt;/strong&gt; (written in Go, ~50ms cold start on Cloud Run) reads the spec and follows it. No code interpretation. No LLM inference. No variability.&lt;/p&gt;

&lt;p&gt;The "no LLM at runtime" rule isn't about what competitors do - it's about what production systems need. Determinism. Auditability. Predictable behavior under every condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 9-Step Execution Contract
&lt;/h2&gt;

&lt;p&gt;Every API endpoint follows the same sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Validate input&lt;/strong&gt; against JSON Schema from the spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorize&lt;/strong&gt; - JWT verification, RBAC role check, row-level ownership&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check policies&lt;/strong&gt; - design-time rules enforced deterministically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start transaction&lt;/strong&gt; - explicit boundary, no auto-commit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute flow graph&lt;/strong&gt; - a DAG of typed nodes (Read, Write, Transform, If/Switch)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce invariants&lt;/strong&gt; - business rules checked before commit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit or rollback&lt;/strong&gt; - all-or-nothing, no partial state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write audit log&lt;/strong&gt; - append-only, unconditional, every execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return typed response&lt;/strong&gt; - matches the output schema from the spec&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No shortcuts. No "well, this endpoint is special." The rigidity is the feature.&lt;/p&gt;

&lt;p&gt;With generated code, any of these steps can be missing. With specs, they're mandatory. The format doesn't allow you to skip step 4 or forget step 8.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design-Time Safety
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Risk Engine&lt;/strong&gt; classifies every API endpoint before deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Green&lt;/strong&gt;: All writes in transactions, no unbounded queries, no unsafe patterns. Deploy freely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yellow&lt;/strong&gt;: External call without retry, high row impact. Deploy with acknowledgment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red&lt;/strong&gt;: Payment without rollback, write without transaction, unbounded UPDATE. &lt;strong&gt;Cannot deploy.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Red signals cannot be dismissed. Fix the design.&lt;/p&gt;

&lt;p&gt;This is the key difference from generated code. In a codebase, these patterns are caught by code review (maybe) or by production incidents (definitely). In a spec-driven system, they're caught by static analysis before anything runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tradeoff
&lt;/h2&gt;

&lt;p&gt;All business logic must be captured in the spec at design time. The runtime cannot improvise. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex conditional logic must be modeled as flow graph branches&lt;/li&gt;
&lt;li&gt;Custom business rules use a restricted Value DSL (no arbitrary code)&lt;/li&gt;
&lt;li&gt;External API calls are explicit nodes with retry/timeout configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a real constraint. Generated code is more flexible - you can do anything, including unsafe things.&lt;/p&gt;

&lt;p&gt;We think the constraint is worth it. Production backends should be &lt;strong&gt;provable&lt;/strong&gt;, not &lt;strong&gt;flexible&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specs vs Generated Code
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Generated Code&lt;/th&gt;
&lt;th&gt;Spec-Driven (Fascia)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transaction boundaries&lt;/td&gt;
&lt;td&gt;Optional (developer's choice)&lt;/td&gt;
&lt;td&gt;Mandatory (format enforces)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit logging&lt;/td&gt;
&lt;td&gt;Ad-hoc&lt;/td&gt;
&lt;td&gt;Every execution, unconditional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unsafe pattern detection&lt;/td&gt;
&lt;td&gt;Code review / production incident&lt;/td&gt;
&lt;td&gt;Static analysis before deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Readability at month 6&lt;/td&gt;
&lt;td&gt;Depends on code quality&lt;/td&gt;
&lt;td&gt;Spec is always readable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback strategy&lt;/td&gt;
&lt;td&gt;Hope for the best&lt;/td&gt;
&lt;td&gt;Explicit compensation flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response time&lt;/td&gt;
&lt;td&gt;Varies by implementation&lt;/td&gt;
&lt;td&gt;12-50ms (deterministic executor)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;We're building Fascia in public. Pre-launch, solo founder, 150+ PRs deep.&lt;/p&gt;

&lt;p&gt;Next in this series: &lt;strong&gt;The Risk Engine - How We Classify Green, Yellow, and Red&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fascia.run" rel="noopener noreferrer"&gt;fascia.run&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>architecture</category>
      <category>security</category>
    </item>
  </channel>
</rss>
