<?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>DEV Community: Cristian Barragan</title>
    <description>The latest articles on DEV Community by Cristian Barragan (@cristian_barragan_f2f519e).</description>
    <link>https://dev.to/cristian_barragan_f2f519e</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3472029%2Fd9c69830-fa2f-4bb6-b7df-f37d4defd334.png</url>
      <title>DEV Community: Cristian Barragan</title>
      <link>https://dev.to/cristian_barragan_f2f519e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cristian_barragan_f2f519e"/>
    <language>en</language>
    <item>
      <title>We benchmarked an AI agent with vs. without a semantic execution boundary. It cut token load ~63% — and that's before you count the electricity.</title>
      <dc:creator>Cristian Barragan</dc:creator>
      <pubDate>Thu, 20 Aug 2026 01:11:33 +0000</pubDate>
      <link>https://dev.to/cristian_barragan_f2f519e/we-benchmarked-an-ai-agent-with-vs-without-a-semantic-execution-boundary-it-cut-token-load-63--118c</link>
      <guid>https://dev.to/cristian_barragan_f2f519e/we-benchmarked-an-ai-agent-with-vs-without-a-semantic-execution-boundary-it-cut-token-load-63--118c</guid>
      <description>&lt;p&gt;The question&lt;/p&gt;

&lt;p&gt;When you give an AI agent tools to complete a real business task, how much of what it does is the task, and how much is just the agent finding its footing — discovering the schema, pulling raw rows into context, re-reading them, hoping it didn't miss a field?&lt;/p&gt;

&lt;p&gt;We built a paired benchmark to measure that gap directly, using Foundgine, an open-source .NET semantic execution layer, against a conventional "give the agent raw application tools" flow. Same task, same data, same required final state. Only the execution boundary changes.&lt;/p&gt;

&lt;p&gt;The scenario&lt;br&gt;
A banking customer-review task, deliberately not trivial:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
  ├── 4 banking relationships&lt;br&gt;
  │     └── 12 contracts&lt;br&gt;
  │            └── 48 transactions&lt;br&gt;
  ├── calculate total exposure&lt;br&gt;
  ├── compare with a $48,000 threshold&lt;br&gt;
  ├── mark the customer as reviewed (one field mutation)&lt;br&gt;
  └── verify the final state&lt;/p&gt;

&lt;p&gt;Flow A — Conventional application/AI: the agent gets application tools for schema discovery, customer lookup, relationship lookup, contract lookup, transaction retrieval, mutation, and verification. It has to reconstruct the graph itself, in its own context, one tool call at a time.&lt;/p&gt;

&lt;p&gt;Flow B — Foundgine semantic flow: the agent gets a semantic capability. Foundgine resolves the graph, applies the application's authorization boundary, and executes behind that boundary. The agent asks for the outcome; it doesn't walk the schema to get there.&lt;/p&gt;

&lt;p&gt;Both flows are graded on one thing above everything else: did they land on the exact same final state? If not, nothing else on this page matters. Across 10 measured runs (3 warmups) for each flow, they did — 100% of the time.&lt;/p&gt;

&lt;p&gt;What actually changed&lt;br&gt;
Metric  Conventional    Foundgine   Change&lt;br&gt;
Tool calls  7   TO  4   (−42.9%)&lt;br&gt;
Est. token load / call (heuristic)  ~981  TO    ~364       −62.9%&lt;br&gt;
Same final state    true    true    pass&lt;/p&gt;

&lt;p&gt;The tool-call number is measured directly from the harness — no estimation involved. The token number needs one more step, because this benchmark runs in replay mode (no live model calls, so provider-reported token counts are correctly zero — that's the harness working as intended, not a gap). To fill that in, we applied the standard tokenizer approximation — tokens ≈ max(chars/4, words×1.3) — to every recorded tool input/output payload plus the fixed system prompt, which tracks real BPE tokenizers within roughly ±15% for payloads like these. It's directional, not a provider-reported measurement, and it doesn't include the model's own reasoning tokens (which a live run would add — to both flows).&lt;/p&gt;

&lt;p&gt;What that's worth in dollars&lt;br&gt;
Converting token load into cost needs one more inference: tool-output payloads get billed as input tokens on the agent's next turn, tool-input payloads (the args the model generated) get billed as output tokens. That's how a real tool-calling loop is billed — inferred here, not measured, but it's the standard convention.&lt;/p&gt;

&lt;p&gt;At current Claude API list pricing (Aug 2026):&lt;/p&gt;

&lt;p&gt;Model ($/MTok in/out)   Saved / call    100K calls/day&lt;br&gt;
Haiku 4.5 ($1/$5)   $0.000685   ~$2,055/mo · ~$25K/yr&lt;br&gt;
Sonnet 5, standard ($3/$15) $0.002055   ~$6,165/mo · ~$75K/yr&lt;br&gt;
Opus 5 ($5/$25) $0.003425   ~$10,275/mo · ~$125K/yr&lt;/p&gt;

&lt;p&gt;A single internal agent running 10K calls/day is a few hundred dollars a month. A platform-wide agent at 1M calls/day is six figures a month. Treat every one of these as an order of magnitude for planning, not a quote — it's a heuristic estimate at list price, reproducible with a small script (estimate_cost_savings.py, shipped in the repo) so you can re-run it with your own volume and pricing instead of trusting mine.&lt;/p&gt;

&lt;p&gt;The part that surprised us: Foundgine was slower, wall-clock&lt;br&gt;
This is the section a lot of benchmark posts would quietly drop. We didn't.&lt;/p&gt;

&lt;p&gt;In this replay, Foundgine's wall-clock time was higher, not lower — the conventional flow's 7 small round trips were individually cheap in application time; Foundgine's 4 calls do more resolution work behind the boundary before the agent ever sees a result. Fewer, smaller round trips for the agent traded against more work inside the application.&lt;/p&gt;

&lt;p&gt;Tokens, API time, and application load are three different measurements, and a flow can win on one while losing another. Optimizing for per-call API spend and context-window pressure favors the semantic boundary here. Optimizing for raw end-to-end latency does not automatically follow. We report both instead of netting them out into one number that flatters the result.&lt;/p&gt;

&lt;p&gt;Zooming out: what if this were the world's problem, not one benchmark?&lt;br&gt;
This part is explicitly a napkin calculation, not a claim. But it's worth doing once, in the open, so it can be argued with.&lt;/p&gt;

&lt;p&gt;The IEA's 2026 base case puts global data-center electricity at roughly 485 TWh (2025) heading toward ~950 TWh by 2030, with AI-optimized servers already at ~31% of 2026 data-center power draw (~175 TWh/year) and growing about 3x faster than conventional server load. Critically, the IEA specifically flags agentic and reasoning workloads as consuming hundreds to thousands of times more energy per query than a simple text prompt — this is exactly the workload class this benchmark is measuring.&lt;/p&gt;

&lt;p&gt;If we assume energy scales roughly with tokens processed (a simplification — attention cost is superlinear in context length, so this probably understates the real gap at longer contexts), and some slice of that ~175 TWh/year AI-server budget is agentic tool-calling traffic shaped like our "conventional" flow, applying the measured ~63% token-load cut:&lt;/p&gt;

&lt;p&gt;Share of AI-server power that's agentic tool-calling like this  ≈ energy  ≈ saved at 63% cut    @ ~$0.12/kWh&lt;br&gt;
1%  1.75 TWh/yr 1.1 TWh/yr  ~$132M/yr&lt;br&gt;
5%  8.75 TWh/yr 5.5 TWh/yr  ~$660M/yr&lt;br&gt;
10% 17.5 TWh/yr 11 TWh/yr   ~$1.3B/yr&lt;/p&gt;

&lt;p&gt;1.1 TWh/year is roughly the annual electricity draw of 100,000 average US homes. None of the percentages in the left column are measured — they're scenario inputs, and I'd genuinely like people to push back on them. The one number underneath all three rows that is measured is the 62.9% token-load reduction on this specific scenario. The rest is "if this generalizes, here's the shape of what it's worth" — in dollars, and, just as importantly, in kilowatt-hours and tonnes of CO₂e.&lt;/p&gt;

&lt;p&gt;The honest takeaway isn't the headline dollar or TWh figure. It's that a meaningful share of agentic AI's cost and energy footprint is going toward an agent re-discovering how to talk to an application, not toward the business logic itself. That's a fixable, boring, structural problem — not an inherent cost of using AI agents.&lt;/p&gt;

&lt;p&gt;Efficiency is not the same thing as safety — and shouldn't be sold as one&lt;br&gt;
This is the part I want to be most direct about, because "we made the agent cheaper" is a dangerous headline to leave unqualified.&lt;/p&gt;

&lt;p&gt;Cutting tool calls and token load does not, by itself, change what an agent is authorized to do. That has to be designed in, deliberately, independent of the efficiency win:&lt;/p&gt;

&lt;p&gt;The application stays the authority, not the model. Foundgine's semantic capability and mutation boundary are application-defined; the agent requests intent, it never gets raw SQL or physical schema access. A cheaper path can't quietly become a wider one.&lt;/p&gt;

&lt;p&gt;Mutations require explicit, narrow intent. In this benchmark, the only field either flow is allowed to mutate is Customer.FullName — because that's the one field the capability grants, not because the agent chose to be conservative.&lt;/p&gt;

&lt;p&gt;Verification happens regardless of token count. Both flows call a verify step after the mutation. Fewer tokens should never mean fewer checks.&lt;br&gt;
"Same final state" is the actual gate for every number on this page. An agent that's 63% cheaper and reaches the wrong state isn't a result — it's a regression that happens to look fast.&lt;/p&gt;

&lt;p&gt;The efficiency case and the safety case for a semantic execution boundary aren't competing goals. They're the same design decision, looked at from two angles. If you're building agent infrastructure and only optimizing for tokens, you're only doing half the job.&lt;/p&gt;

&lt;p&gt;Reproduce it yourself&lt;br&gt;
Full technical report, run-by-run trace, and every caveat: agent benchmark → technical report&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.toFoundgine%20an%20AI-Runtime%20platform"&gt;https://cristianbarragan.github.io/Foundgine/docs-site/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>performance</category>
    </item>
    <item>
      <title>Foundgine: Why Semantics Matter for LLMs and AI Agents</title>
      <dc:creator>Cristian Barragan</dc:creator>
      <pubDate>Wed, 12 Aug 2026 21:17:57 +0000</pubDate>
      <link>https://dev.to/cristian_barragan_f2f519e/why-semantics-matter-for-llms-and-ai-agents-ai0</link>
      <guid>https://dev.to/cristian_barragan_f2f519e/why-semantics-matter-for-llms-and-ai-agents-ai0</guid>
      <description>&lt;p&gt;An engineering example from building Foundgine&lt;/p&gt;

&lt;p&gt;Large language models are remarkably good at interpreting language.&lt;/p&gt;

&lt;p&gt;That has led to a natural architectural assumption:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 ↓&lt;br&gt;
LLM&lt;br&gt;
 ↓&lt;br&gt;
SQL / API / Tool call&lt;br&gt;
 ↓&lt;br&gt;
System&lt;/p&gt;

&lt;p&gt;For simple applications, this can work surprisingly well.&lt;/p&gt;

&lt;p&gt;But as soon as an agent has to operate a non-trivial system, a fundamental problem appears:&lt;/p&gt;

&lt;p&gt;The model has to infer the meaning of the system before it can reliably act on it.&lt;/p&gt;

&lt;p&gt;That distinction is easy to overlook.&lt;/p&gt;

&lt;p&gt;A database schema contains structure.&lt;/p&gt;

&lt;p&gt;An API contains contracts.&lt;/p&gt;

&lt;p&gt;A GraphQL schema contains types and fields.&lt;/p&gt;

&lt;p&gt;Documentation contains explanations.&lt;/p&gt;

&lt;p&gt;But none of these necessarily provide a complete, executable representation of the system's semantics.&lt;/p&gt;

&lt;p&gt;That is the problem Foundgine was designed to explore.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Syntax is not semantics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consider a simplified relational model:&lt;/p&gt;

&lt;h2&gt;
  
  
  Customer
&lt;/h2&gt;

&lt;p&gt;Id&lt;br&gt;
CustomerKey&lt;br&gt;
FirstName&lt;br&gt;
LastName&lt;/p&gt;

&lt;h2&gt;
  
  
  CustomerBankingRelationship
&lt;/h2&gt;

&lt;p&gt;Id&lt;br&gt;
CustomerId&lt;br&gt;
CustomerBankingRelationshipKey&lt;/p&gt;

&lt;h2&gt;
  
  
  Contract
&lt;/h2&gt;

&lt;p&gt;Id&lt;br&gt;
CustomerBankingRelationshipId&lt;br&gt;
ContractKey&lt;/p&gt;

&lt;h2&gt;
  
  
  Transaction
&lt;/h2&gt;

&lt;p&gt;Id&lt;br&gt;
ContractId&lt;br&gt;
TransactionKey&lt;br&gt;
Amount&lt;br&gt;
Balance&lt;/p&gt;

&lt;p&gt;An LLM can look at this and infer:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
   ↓ CustomerId&lt;br&gt;
CustomerBankingRelationship&lt;br&gt;
   ↓ CustomerBankingRelationshipId&lt;br&gt;
Contract&lt;br&gt;
   ↓ ContractId&lt;br&gt;
Transaction&lt;/p&gt;

&lt;p&gt;That inference may be correct.&lt;/p&gt;

&lt;p&gt;But it is still an inference.&lt;/p&gt;

&lt;p&gt;The model is reconstructing semantics from implementation details.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;A column called:&lt;/p&gt;

&lt;p&gt;CustomerId&lt;/p&gt;

&lt;p&gt;is not the same thing as an explicit semantic statement:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
    hasMany&lt;br&gt;
CustomerBankingRelationship&lt;/p&gt;

&lt;p&gt;The first is a database implementation detail.&lt;/p&gt;

&lt;p&gt;The second describes the domain relationship.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The problem gets worse when an agent acts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose an AI agent receives:&lt;/p&gt;

&lt;p&gt;Create a customer with a banking relationship, a contract and two transactions.&lt;/p&gt;

&lt;p&gt;The agent needs to understand more than the names of the tables.&lt;/p&gt;

&lt;p&gt;It needs to understand:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
  └── CustomerBankingRelationship&lt;br&gt;
        └── Contract&lt;br&gt;
              └── Transaction&lt;/p&gt;

&lt;p&gt;It also needs to understand identity.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Customer.CustomerKey&lt;br&gt;
CustomerBankingRelationship.CustomerBankingRelationshipKey&lt;br&gt;
Contract.ContractKey&lt;br&gt;
Transaction.TransactionKey&lt;/p&gt;

&lt;p&gt;And it needs to understand that the child records depend on values produced by their parents.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Create Customer&lt;br&gt;
      ↓&lt;br&gt;
obtain Customer identity&lt;br&gt;
      ↓&lt;br&gt;
Create CustomerBankingRelationship&lt;br&gt;
      ↓&lt;br&gt;
obtain relationship identity&lt;br&gt;
      ↓&lt;br&gt;
Create Contract&lt;br&gt;
      ↓&lt;br&gt;
obtain contract identity&lt;br&gt;
      ↓&lt;br&gt;
Create Transactions&lt;/p&gt;

&lt;p&gt;This isn't merely SQL generation.&lt;/p&gt;

&lt;p&gt;It is planning over a semantic graph.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Foundgine separates meaning from execution&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This became one of the central architectural ideas in Foundgine.&lt;/p&gt;

&lt;p&gt;Rather than immediately turning a request into SQL, the pipeline introduces semantic representations between the external request and the physical database:&lt;/p&gt;

&lt;p&gt;Domain&lt;br&gt;
   ↓&lt;br&gt;
Metadata&lt;br&gt;
   ↓&lt;br&gt;
Semantic Graph&lt;br&gt;
   ↓&lt;br&gt;
Planner&lt;br&gt;
   ↓&lt;br&gt;
Query Plan&lt;br&gt;
   ↓&lt;br&gt;
Execution&lt;br&gt;
   ↓&lt;br&gt;
Provider&lt;br&gt;
   ↓&lt;br&gt;
SQL&lt;/p&gt;

&lt;p&gt;This separation is important.&lt;/p&gt;

&lt;p&gt;The semantic layer can describe concepts such as:&lt;/p&gt;

&lt;p&gt;Node&lt;br&gt;
NodeIdentity&lt;br&gt;
Edge&lt;br&gt;
EdgeIdentity&lt;br&gt;
Traversal&lt;br&gt;
Path&lt;br&gt;
Predicate&lt;br&gt;
Projection&lt;br&gt;
Ordering&lt;br&gt;
Cardinality&lt;/p&gt;

&lt;p&gt;These aren't PostgreSQL concepts.&lt;/p&gt;

&lt;p&gt;They aren't GraphQL concepts either.&lt;/p&gt;

&lt;p&gt;They describe what the operation means.&lt;/p&gt;

&lt;p&gt;Only later does the system decide how that meaning should be implemented physically.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why an intermediate semantic representation matters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consider:&lt;/p&gt;

&lt;p&gt;customer(first: 50) {&lt;br&gt;
    id&lt;br&gt;
    firstName&lt;br&gt;
    customerBankingRelationship {&lt;br&gt;
        contract {&lt;br&gt;
            transaction {&lt;br&gt;
                amount&lt;br&gt;
                balance&lt;br&gt;
            }&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;A naïve architecture can think about this as:&lt;/p&gt;

&lt;p&gt;GraphQL&lt;br&gt;
   ↓&lt;br&gt;
SQL&lt;/p&gt;

&lt;p&gt;Foundgine instead treats it conceptually as:&lt;/p&gt;

&lt;p&gt;GraphQL intent&lt;br&gt;
      ↓&lt;br&gt;
semantic traversal&lt;br&gt;
      ↓&lt;br&gt;
graph plan&lt;br&gt;
      ↓&lt;br&gt;
physical query plan&lt;br&gt;
      ↓&lt;br&gt;
SQL&lt;/p&gt;

&lt;p&gt;The important difference is that the system can reason about:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
  → CustomerBankingRelationship&lt;br&gt;
      → Contract&lt;br&gt;
          → Transaction&lt;/p&gt;

&lt;p&gt;before deciding how that traversal should be executed.&lt;/p&gt;

&lt;p&gt;This gives the planner a stable vocabulary.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The semantic model is also useful without AI&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is perhaps the most important point.&lt;/p&gt;

&lt;p&gt;It would be easy to describe semantics as:&lt;/p&gt;

&lt;p&gt;“metadata for AI.”&lt;/p&gt;

&lt;p&gt;That undersells the idea.&lt;/p&gt;

&lt;p&gt;The semantic model is useful even if there is no LLM anywhere.&lt;/p&gt;

&lt;p&gt;It can drive:&lt;/p&gt;

&lt;p&gt;deterministic query planning&lt;br&gt;
relationship traversal&lt;br&gt;
authorization decisions&lt;br&gt;
validation&lt;br&gt;
execution planning&lt;br&gt;
optimization&lt;br&gt;
explainability&lt;/p&gt;

&lt;p&gt;AI becomes another consumer.&lt;/p&gt;

&lt;p&gt;That distinction is important because it avoids building an “AI layer” that is tightly coupled to a particular model.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where LLMs fit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The LLM is extremely good at one part of this pipeline:&lt;/p&gt;

&lt;p&gt;Natural language&lt;br&gt;
        ↓&lt;br&gt;
       intent&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;“Show me the first 50 customers and their transactions.”&lt;/p&gt;

&lt;p&gt;An LLM can interpret the request.&lt;/p&gt;

&lt;p&gt;But it shouldn't necessarily be responsible for deciding:&lt;/p&gt;

&lt;p&gt;Does Customer have this relationship?&lt;/p&gt;

&lt;p&gt;What is the identity of the entity?&lt;/p&gt;

&lt;p&gt;Is this relationship one-to-one or one-to-many?&lt;/p&gt;

&lt;p&gt;Can this traversal happen?&lt;/p&gt;

&lt;p&gt;Which fields are authoritative?&lt;/p&gt;

&lt;p&gt;What dependencies exist between mutations?&lt;/p&gt;

&lt;p&gt;How should the operation be executed?&lt;/p&gt;

&lt;p&gt;Those are properties of the system.&lt;/p&gt;

&lt;p&gt;The system should expose them.&lt;/p&gt;

&lt;p&gt;The LLM interprets intent.&lt;/p&gt;

&lt;p&gt;The semantic layer provides meaning.&lt;/p&gt;

&lt;p&gt;The planner determines execution.&lt;/p&gt;

&lt;p&gt;That gives us:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
 ↓&lt;br&gt;
Intent&lt;br&gt;
 ↓&lt;br&gt;
Semantic Model&lt;br&gt;
 ↓&lt;br&gt;
Deterministic Planner&lt;br&gt;
 ↓&lt;br&gt;
Execution&lt;/p&gt;

&lt;p&gt;rather than:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
 ↓&lt;br&gt;
"probably correct" SQL&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A concrete mutation example&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where the distinction becomes particularly interesting.&lt;/p&gt;

&lt;p&gt;Imagine the mutation:&lt;/p&gt;

&lt;p&gt;Create Customer&lt;br&gt;
Create Banking Relationship&lt;br&gt;
Create Contract&lt;br&gt;
Create two Transactions&lt;/p&gt;

&lt;p&gt;The transaction records cannot be created independently.&lt;/p&gt;

&lt;p&gt;They depend on the contract.&lt;/p&gt;

&lt;p&gt;The contract depends on the banking relationship.&lt;/p&gt;

&lt;p&gt;The banking relationship depends on the customer.&lt;/p&gt;

&lt;p&gt;So the operation has a dependency graph:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
   │&lt;br&gt;
   ▼&lt;br&gt;
Banking Relationship&lt;br&gt;
   │&lt;br&gt;
   ▼&lt;br&gt;
Contract&lt;br&gt;
   │&lt;br&gt;
   ├──► Transaction&lt;br&gt;
   └──► Transaction&lt;/p&gt;

&lt;p&gt;The semantic representation exposes that dependency.&lt;/p&gt;

&lt;p&gt;The planner can then construct an executable plan.&lt;/p&gt;

&lt;p&gt;The provider can ultimately turn that plan into database operations.&lt;/p&gt;

&lt;p&gt;The LLM doesn't need to invent the dependency chain.&lt;/p&gt;

&lt;p&gt;It only needs to express the intended operation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This is where semantics become especially important for agents&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An AI agent has two fundamentally different problems:&lt;/p&gt;

&lt;p&gt;Problem 1 — What does the user want?&lt;/p&gt;

&lt;p&gt;This is where an LLM shines.&lt;/p&gt;

&lt;p&gt;Problem 2 — What does the system allow and mean?&lt;/p&gt;

&lt;p&gt;This should not be left entirely to the LLM.&lt;/p&gt;

&lt;p&gt;That second problem belongs to the application's semantic model.&lt;/p&gt;

&lt;p&gt;This gives us a useful division of responsibility:&lt;/p&gt;

&lt;p&gt;Responsibility  Best handled by&lt;br&gt;
Interpret natural language  LLM&lt;br&gt;
Determine system meaning    Semantic model&lt;br&gt;
Validate relationships  Semantic model&lt;br&gt;
Determine dependencies  Planner&lt;br&gt;
Select physical execution   Planner/provider&lt;br&gt;
Execute operation   Runtime&lt;br&gt;
Generate final explanation  LLM&lt;/p&gt;

&lt;p&gt;The LLM remains powerful.&lt;/p&gt;

&lt;p&gt;But it is no longer expected to reconstruct the entire system from scratch.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why this is different from RAG&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RAG is useful because it gives an LLM additional context.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
 ↓&lt;br&gt;
Retrieve documentation&lt;br&gt;
 ↓&lt;br&gt;
Reason&lt;/p&gt;

&lt;p&gt;But documentation is still information the model has to interpret.&lt;/p&gt;

&lt;p&gt;A semantic model is different.&lt;/p&gt;

&lt;p&gt;It can be structured and executable.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;"CustomerBankingRelationship is a relationship between..."&lt;/p&gt;

&lt;p&gt;the system can represent:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
    relationship:&lt;br&gt;
        CustomerBankingRelationship&lt;br&gt;
    cardinality:&lt;br&gt;
        many&lt;br&gt;
    identity:&lt;br&gt;
        CustomerBankingRelationshipKey&lt;/p&gt;

&lt;p&gt;The difference is subtle but important.&lt;/p&gt;

&lt;p&gt;RAG gives the model information about the system.&lt;/p&gt;

&lt;p&gt;A semantic model gives the software a structured representation of the system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The bigger architectural consequence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once semantics become first-class, the architecture becomes much more interesting:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              ┌─────────────┐
              │     LLM     │
              └──────┬──────┘
                     │
                   Intent
                     │
                     ▼
            ┌─────────────────┐
            │ Semantic Model  │
            └────────┬────────┘
                     │
          ┌──────────┴──────────┐
          │                     │
     Validation            Authorization
          │                     │
          └──────────┬──────────┘
                     │
                   Planner
                     │
                     ▼
               Query Plan
                     │
                     ▼
                 Provider
                     │
                     ▼
                    SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The LLM is no longer the architecture.&lt;/p&gt;

&lt;p&gt;It is one component inside the architecture.&lt;/p&gt;

&lt;p&gt;That's an important distinction for agentic systems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What Foundgine actually demonstrates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The repository doesn't prove that:&lt;/p&gt;

&lt;p&gt;“LLMs are solved.”&lt;/p&gt;

&lt;p&gt;It doesn't prove that:&lt;/p&gt;

&lt;p&gt;“A semantic layer makes every AI agent reliable.”&lt;/p&gt;

&lt;p&gt;Those would be much larger claims.&lt;/p&gt;

&lt;p&gt;What the repository does demonstrate is something narrower and, arguably, more useful:&lt;/p&gt;

&lt;p&gt;A software system can make its domain semantics explicit and use those semantics to deterministically plan operations instead of reconstructing system meaning from the physical database representation at every request.&lt;/p&gt;

&lt;p&gt;That is already valuable.&lt;/p&gt;

&lt;p&gt;And it creates an interesting foundation for AI agents.&lt;/p&gt;

&lt;p&gt;Because once a system has an explicit semantic model, an agent no longer has to discover everything through:&lt;/p&gt;

&lt;p&gt;documentation&lt;br&gt;
+&lt;br&gt;
database schema&lt;br&gt;
+&lt;br&gt;
API exploration&lt;br&gt;
+&lt;br&gt;
guesswork&lt;/p&gt;

&lt;p&gt;It can potentially consume the same semantic representation the runtime itself uses.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lesson from Foundgine is not:&lt;/p&gt;

&lt;p&gt;“Use AI to generate better SQL.”&lt;/p&gt;

&lt;p&gt;It is closer to:&lt;/p&gt;

&lt;p&gt;Don't ask an AI to infer semantics that your software already knows.&lt;/p&gt;

&lt;p&gt;Let the model do what models are good at:&lt;/p&gt;

&lt;p&gt;language&lt;br&gt;
reasoning&lt;br&gt;
intent&lt;/p&gt;

&lt;p&gt;Let the system do what deterministic software is good at:&lt;/p&gt;

&lt;p&gt;meaning&lt;br&gt;
constraints&lt;br&gt;
relationships&lt;br&gt;
planning&lt;br&gt;
execution&lt;/p&gt;

&lt;p&gt;And connect the two through an explicit semantic layer.&lt;/p&gt;

&lt;p&gt;That may be one of the more important architectural patterns for the next generation of AI-powered software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.toFoundgine%20an%20AI-Runtime%20platform"&gt;https://cristianbarragan.github.io/Foundgine/docs-site/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>Foundgine: Why Another Data Framework?</title>
      <dc:creator>Cristian Barragan</dc:creator>
      <pubDate>Tue, 11 Aug 2026 06:44:53 +0000</pubDate>
      <link>https://dev.to/cristian_barragan_f2f519e/foundgine-why-another-data-framework-1jib</link>
      <guid>https://dev.to/cristian_barragan_f2f519e/foundgine-why-another-data-framework-1jib</guid>
      <description>&lt;p&gt;There is no shortage of frameworks for building data-driven applications.&lt;/p&gt;

&lt;p&gt;There are ORMs.&lt;/p&gt;

&lt;p&gt;There are GraphQL servers.&lt;/p&gt;

&lt;p&gt;There are repositories.&lt;/p&gt;

&lt;p&gt;There are query builders.&lt;/p&gt;

&lt;p&gt;There are API frameworks.&lt;/p&gt;

&lt;p&gt;There are database drivers.&lt;/p&gt;

&lt;p&gt;All of them solve real problems.&lt;/p&gt;

&lt;p&gt;So why would another system be necessary?&lt;/p&gt;

&lt;p&gt;The motivation behind Foundgine starts with a different problem:&lt;/p&gt;

&lt;p&gt;modern applications are very good at describing requests, but the meaning of those requests is often lost before execution.&lt;/p&gt;

&lt;p&gt;Start with a simple request&lt;/p&gt;

&lt;p&gt;Imagine an application with these relationships:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
   └── Accounts&lt;br&gt;
         └── Transactions&lt;/p&gt;

&lt;p&gt;A client asks:&lt;/p&gt;

&lt;p&gt;query {&lt;br&gt;
  customers {&lt;br&gt;
    name&lt;br&gt;
    accounts {&lt;br&gt;
      number&lt;br&gt;
      transactions {&lt;br&gt;
        amount&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;At the API level, this is simple.&lt;/p&gt;

&lt;p&gt;The client is saying:&lt;/p&gt;

&lt;p&gt;Give me customers, their accounts, and the transactions belonging to those accounts.&lt;/p&gt;

&lt;p&gt;The difficult part is everything that happens next.&lt;/p&gt;

&lt;p&gt;The application has to determine:&lt;/p&gt;

&lt;p&gt;which entities are involved&lt;br&gt;
how they are related&lt;br&gt;
which fields are valid&lt;br&gt;
which relationships can be traversed&lt;br&gt;
what authorization applies&lt;br&gt;
how filtering and ordering should work&lt;br&gt;
how the data should be fetched&lt;br&gt;
how many database operations are required&lt;br&gt;
how the result should be reconstructed&lt;/p&gt;

&lt;p&gt;This is where application architecture tends to become complicated.&lt;/p&gt;

&lt;p&gt;The traditional path&lt;/p&gt;

&lt;p&gt;A typical implementation might look like:&lt;/p&gt;

&lt;p&gt;GraphQL request&lt;br&gt;
      ↓&lt;br&gt;
Resolver&lt;br&gt;
      ↓&lt;br&gt;
Service&lt;br&gt;
      ↓&lt;br&gt;
Repository&lt;br&gt;
      ↓&lt;br&gt;
ORM&lt;br&gt;
      ↓&lt;br&gt;
SQL&lt;br&gt;
      ↓&lt;br&gt;
Database&lt;/p&gt;

&lt;p&gt;Each layer makes sense.&lt;/p&gt;

&lt;p&gt;But there is an important architectural consequence.&lt;/p&gt;

&lt;p&gt;The original request gets broken apart.&lt;/p&gt;

&lt;p&gt;The resolver knows part of it.&lt;/p&gt;

&lt;p&gt;The service knows another part.&lt;/p&gt;

&lt;p&gt;The repository knows how to query the data.&lt;/p&gt;

&lt;p&gt;The ORM knows how to translate objects into SQL.&lt;/p&gt;

&lt;p&gt;The database finally executes the result.&lt;/p&gt;

&lt;p&gt;There is often no single representation of:&lt;/p&gt;

&lt;p&gt;"This is what the application is asking for."&lt;/p&gt;

&lt;p&gt;That becomes increasingly important when requests become more complex.&lt;/p&gt;

&lt;p&gt;Relationships expose the problem&lt;/p&gt;

&lt;p&gt;Consider:&lt;/p&gt;

&lt;p&gt;customers {&lt;br&gt;
  accounts {&lt;br&gt;
    transactions {&lt;br&gt;
      amount&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;A naive implementation can easily turn into:&lt;/p&gt;

&lt;p&gt;Query customers&lt;br&gt;
   ↓&lt;br&gt;
For each customer:&lt;br&gt;
    Query accounts&lt;br&gt;
       ↓&lt;br&gt;
    For each account:&lt;br&gt;
        Query transactions&lt;/p&gt;

&lt;p&gt;The infamous N+1 problem appears.&lt;/p&gt;

&lt;p&gt;The solution is well known.&lt;/p&gt;

&lt;p&gt;Use batching.&lt;/p&gt;

&lt;p&gt;Use eager loading.&lt;/p&gt;

&lt;p&gt;Use joins.&lt;/p&gt;

&lt;p&gt;Use DataLoader.&lt;/p&gt;

&lt;p&gt;Use projections.&lt;/p&gt;

&lt;p&gt;Use custom SQL.&lt;/p&gt;

&lt;p&gt;Use ORM-specific optimizations.&lt;/p&gt;

&lt;p&gt;These are all valid solutions.&lt;/p&gt;

&lt;p&gt;But they are mostly execution-level solutions.&lt;/p&gt;

&lt;p&gt;The deeper question is:&lt;/p&gt;

&lt;p&gt;Where does the system represent the original intent?&lt;/p&gt;

&lt;p&gt;That is the question Foundgine explores.&lt;/p&gt;

&lt;p&gt;Foundgine starts one step earlier&lt;/p&gt;

&lt;p&gt;Instead of immediately converting a request into framework-specific execution code, Foundgine introduces an intermediate representation.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Request&lt;br&gt;
   ↓&lt;br&gt;
Intent&lt;br&gt;
   ↓&lt;br&gt;
Metadata&lt;br&gt;
   ↓&lt;br&gt;
Semantics&lt;br&gt;
   ↓&lt;br&gt;
Plan&lt;br&gt;
   ↓&lt;br&gt;
Execution&lt;/p&gt;

&lt;p&gt;The important part is the plan.&lt;/p&gt;

&lt;p&gt;The plan represents the requested operation before it becomes SQL.&lt;/p&gt;

&lt;p&gt;For the previous example, the system can reason about something like:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
 ├── Name&lt;br&gt;
 └── Accounts&lt;br&gt;
      ├── Number&lt;br&gt;
      └── Transactions&lt;br&gt;
           └── Amount&lt;/p&gt;

&lt;p&gt;That structure contains meaning.&lt;/p&gt;

&lt;p&gt;It says what data is required and how the data is related.&lt;/p&gt;

&lt;p&gt;It does not yet say:&lt;/p&gt;

&lt;p&gt;"Use this particular SQL query."&lt;/p&gt;

&lt;p&gt;That decision belongs later.&lt;/p&gt;

&lt;p&gt;Intent versus execution&lt;/p&gt;

&lt;p&gt;This distinction is the central idea.&lt;/p&gt;

&lt;p&gt;Consider a relational database.&lt;/p&gt;

&lt;p&gt;The final execution might be something like:&lt;/p&gt;

&lt;p&gt;SELECT&lt;br&gt;
    c.name,&lt;br&gt;
    a.number,&lt;br&gt;
    t.amount&lt;br&gt;
FROM customer c&lt;br&gt;
LEFT JOIN account a&lt;br&gt;
    ON a.customer_id = c.id&lt;br&gt;
LEFT JOIN transaction t&lt;br&gt;
    ON t.account_id = a.id;&lt;/p&gt;

&lt;p&gt;That SQL is useful.&lt;/p&gt;

&lt;p&gt;But it is not the original intent.&lt;/p&gt;

&lt;p&gt;It is one possible implementation of the intent.&lt;/p&gt;

&lt;p&gt;Foundgine attempts to preserve the distinction:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             INTENT
                │
                ▼
          Execution Plan
                │
      ┌─────────┴─────────┐
      ▼                   ▼
    SQL                 Other
   Provider            Provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is what makes the architecture different.&lt;/p&gt;

&lt;p&gt;The platform does not need to assume that the frontend is GraphQL or that the backend is SQL.&lt;/p&gt;

&lt;p&gt;So what exactly is Foundgine?&lt;/p&gt;

&lt;p&gt;Foundgine is a platform for turning application intent into executable plans.&lt;/p&gt;

&lt;p&gt;Its core concerns are:&lt;/p&gt;

&lt;p&gt;Metadata&lt;/p&gt;

&lt;p&gt;What entities, fields, and relationships exist?&lt;/p&gt;

&lt;p&gt;Intent&lt;/p&gt;

&lt;p&gt;What is the application asking for?&lt;/p&gt;

&lt;p&gt;Semantics&lt;/p&gt;

&lt;p&gt;Is that request valid and allowed?&lt;/p&gt;

&lt;p&gt;Planning&lt;/p&gt;

&lt;p&gt;What should execution look like?&lt;/p&gt;

&lt;p&gt;Execution&lt;/p&gt;

&lt;p&gt;How does a provider execute the resulting plan?&lt;/p&gt;

&lt;p&gt;This produces a separation like:&lt;/p&gt;

&lt;p&gt;What?&lt;br&gt;
 ↓&lt;br&gt;
Intent&lt;/p&gt;

&lt;p&gt;What does it mean?&lt;br&gt;
 ↓&lt;br&gt;
Semantics&lt;/p&gt;

&lt;p&gt;How should it run?&lt;br&gt;
 ↓&lt;br&gt;
Plan&lt;/p&gt;

&lt;p&gt;Run it&lt;br&gt;
 ↓&lt;br&gt;
Execution&lt;/p&gt;

&lt;p&gt;That separation is the foundation.&lt;/p&gt;

&lt;p&gt;What Foundgine is not&lt;/p&gt;

&lt;p&gt;It is equally important to define what Foundgine is not.&lt;/p&gt;

&lt;p&gt;It is not an ORM&lt;/p&gt;

&lt;p&gt;Foundgine does not attempt to replace Entity Framework or similar tools.&lt;/p&gt;

&lt;p&gt;An ORM maps application objects to database structures.&lt;/p&gt;

&lt;p&gt;Foundgine is concerned with a different boundary:&lt;/p&gt;

&lt;p&gt;Application intent&lt;br&gt;
        ↓&lt;br&gt;
Execution plan&lt;/p&gt;

&lt;p&gt;An ORM can potentially be part of the execution infrastructure.&lt;/p&gt;

&lt;p&gt;It is not a GraphQL server&lt;/p&gt;

&lt;p&gt;GraphQL can be an input mechanism.&lt;/p&gt;

&lt;p&gt;But Foundgine does not require GraphQL to define its core model.&lt;/p&gt;

&lt;p&gt;The architecture is intended to allow other forms of intent to enter the system.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;GraphQL&lt;br&gt;
REST&lt;br&gt;
Application API&lt;br&gt;
JSON Intent&lt;br&gt;
Generated code&lt;br&gt;
       │&lt;br&gt;
       ▼&lt;br&gt;
    Foundgine&lt;br&gt;
It is not a SQL replacement&lt;/p&gt;

&lt;p&gt;SQL remains extremely powerful.&lt;/p&gt;

&lt;p&gt;Foundgine does not try to hide SQL behind another query language.&lt;/p&gt;

&lt;p&gt;Instead, SQL can be the final execution representation produced from a higher-level plan.&lt;/p&gt;

&lt;p&gt;It is not a repository generator&lt;/p&gt;

&lt;p&gt;Repositories typically answer questions such as:&lt;/p&gt;

&lt;p&gt;GetCustomer()&lt;br&gt;
GetCustomers()&lt;br&gt;
GetCustomerAccounts()&lt;/p&gt;

&lt;p&gt;Foundgine is interested in a different model:&lt;/p&gt;

&lt;p&gt;What does this request require?&lt;/p&gt;

&lt;p&gt;The distinction becomes increasingly useful when requests are dynamic.&lt;/p&gt;

&lt;p&gt;Why introduce another abstraction?&lt;/p&gt;

&lt;p&gt;An abstraction is only useful when it solves a problem that otherwise becomes expensive.&lt;/p&gt;

&lt;p&gt;The argument for Foundgine is that planning is already happening in many applications.&lt;/p&gt;

&lt;p&gt;It is simply happening implicitly.&lt;/p&gt;

&lt;p&gt;Developers manually decide:&lt;/p&gt;

&lt;p&gt;which joins to use&lt;br&gt;
which queries to issue&lt;br&gt;
which fields to project&lt;br&gt;
how relationships are loaded&lt;br&gt;
how authorization affects the query&lt;br&gt;
how mutations depend on one another&lt;br&gt;
how results are reconstructed&lt;/p&gt;

&lt;p&gt;Foundgine attempts to make that planning explicit and reusable.&lt;/p&gt;

&lt;p&gt;Instead of every application repeatedly implementing:&lt;/p&gt;

&lt;p&gt;Request&lt;br&gt;
   ↓&lt;br&gt;
Interpretation&lt;br&gt;
   ↓&lt;br&gt;
Validation&lt;br&gt;
   ↓&lt;br&gt;
Query construction&lt;br&gt;
   ↓&lt;br&gt;
Optimization&lt;br&gt;
   ↓&lt;br&gt;
Execution&lt;/p&gt;

&lt;p&gt;the platform provides a place for those responsibilities to live.&lt;/p&gt;

&lt;p&gt;The evolution behind the idea&lt;/p&gt;

&lt;p&gt;The idea did not begin with a desire to build another framework.&lt;/p&gt;

&lt;p&gt;It emerged from a more practical observation:&lt;/p&gt;

&lt;p&gt;As applications become more data-driven, the boundary between API, business semantics, and data access becomes increasingly complicated.&lt;/p&gt;

&lt;p&gt;GraphQL makes this particularly visible.&lt;/p&gt;

&lt;p&gt;A GraphQL query can describe a surprisingly large amount of intent:&lt;/p&gt;

&lt;p&gt;customers {&lt;br&gt;
    name&lt;br&gt;
    accounts {&lt;br&gt;
        balance&lt;br&gt;
        transactions {&lt;br&gt;
            amount&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Trying to map that directly to resolvers and application code can result in a growing amount of framework-specific logic.&lt;/p&gt;

&lt;p&gt;The natural next step is to ask:&lt;/p&gt;

&lt;p&gt;What if the query became a plan instead?&lt;/p&gt;

&lt;p&gt;From that question comes the broader architecture:&lt;/p&gt;

&lt;p&gt;Frontend&lt;br&gt;
   ↓&lt;br&gt;
Intent&lt;br&gt;
   ↓&lt;br&gt;
Semantic model&lt;br&gt;
   ↓&lt;br&gt;
Planner&lt;br&gt;
   ↓&lt;br&gt;
Execution plan&lt;br&gt;
   ↓&lt;br&gt;
Provider&lt;/p&gt;

&lt;p&gt;GraphQL becomes one way of expressing intent rather than the foundation of the entire system.&lt;/p&gt;

&lt;p&gt;The interesting part is the boundary&lt;/p&gt;

&lt;p&gt;The value of Foundgine is therefore not primarily about writing less SQL.&lt;/p&gt;

&lt;p&gt;It is about creating a clean boundary between:&lt;/p&gt;

&lt;p&gt;what the application wants&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;how infrastructure makes it happen.&lt;/p&gt;

&lt;p&gt;That boundary can potentially provide capabilities such as:&lt;/p&gt;

&lt;p&gt;query planning&lt;br&gt;
relationship traversal&lt;br&gt;
authorization-aware planning&lt;br&gt;
mutation dependency planning&lt;br&gt;
provider-specific optimization&lt;br&gt;
predictable execution&lt;br&gt;
testable intermediate plans&lt;br&gt;
alternative execution providers&lt;/p&gt;

&lt;p&gt;The important word is potentially.&lt;/p&gt;

&lt;p&gt;Foundgine is deliberately a foundation rather than a claim that every problem has already been solved.&lt;/p&gt;

&lt;p&gt;A different way to think about data access&lt;/p&gt;

&lt;p&gt;The traditional mental model is:&lt;/p&gt;

&lt;p&gt;API → Code → Database&lt;/p&gt;

&lt;p&gt;Foundgine proposes:&lt;/p&gt;

&lt;p&gt;API&lt;br&gt;
 ↓&lt;br&gt;
Intent&lt;br&gt;
 ↓&lt;br&gt;
Meaning&lt;br&gt;
 ↓&lt;br&gt;
Plan&lt;br&gt;
 ↓&lt;br&gt;
Execution&lt;br&gt;
 ↓&lt;br&gt;
Database&lt;/p&gt;

&lt;p&gt;The database still matters.&lt;/p&gt;

&lt;p&gt;The API still matters.&lt;/p&gt;

&lt;p&gt;The application code still matters.&lt;/p&gt;

&lt;p&gt;The difference is that the system now has an explicit representation of the work between them.&lt;/p&gt;

&lt;p&gt;That is the core motivation behind Foundgine.&lt;/p&gt;

&lt;p&gt;Not another ORM.&lt;/p&gt;

&lt;p&gt;Not another GraphQL framework.&lt;/p&gt;

&lt;p&gt;Not another database abstraction.&lt;/p&gt;

&lt;p&gt;A foundation for making application intent explicit, turning that intent into an execution plan, and allowing infrastructure to determine how the plan should run.&lt;/p&gt;

&lt;p&gt;That is the problem Foundgine is designed to explore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.toFoundgine%20an%20AI-Runtime%20platform"&gt;https://cristianbarragan.github.io/Foundgine/docs-site/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>database</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Coffee Beanery a GraphQL C# library using Dapper fully customizable</title>
      <dc:creator>Cristian Barragan</dc:creator>
      <pubDate>Mon, 01 Sep 2025 02:07:08 +0000</pubDate>
      <link>https://dev.to/cristian_barragan_f2f519e/graphql-c-library-using-dapper-and-fully-customizable-4pb</link>
      <guid>https://dev.to/cristian_barragan_f2f519e/graphql-c-library-using-dapper-and-fully-customizable-4pb</guid>
      <description>&lt;p&gt;Coffee Beanery intention is to make GraphQL adoption much easier than other frameworks and libraries. Providing it as code rather than as a NuGet package to allow full customizations on a case-by-case basis without boiler plate overhead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/CristianBarragan/Coffee-Beanery" rel="noopener noreferrer"&gt;Coffee Beanery repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration-based and faster development&lt;/li&gt;
&lt;li&gt;No N+1 problem since the entire query/mutation is batched and materialized by the database engine&lt;/li&gt;
&lt;li&gt;Framework agnostic&lt;/li&gt;
&lt;li&gt;Allows business service logic within the GraphQL API project&lt;/li&gt;
&lt;li&gt;Allows custom mapping between Entity models and Data models&lt;/li&gt;
&lt;li&gt;Supports subgraph mutations and queries&lt;/li&gt;
&lt;li&gt;Data annotation-based configuration (Data models and Entity models)&lt;/li&gt;
&lt;li&gt;Leverage to a mapping framework the mapping between Data models and Entity models&lt;/li&gt;
&lt;li&gt;Leverage generics to generate the column names based on the data entities&lt;/li&gt;
&lt;li&gt;Supports any GraphQL framework or vanilla .NET API, since it is not tightly couple to a vendor&lt;/li&gt;
&lt;li&gt;Nodes (Left joins between entities)&lt;/li&gt;
&lt;li&gt;Edges (Joins between entities)&lt;/li&gt;
&lt;li&gt;Paging&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Customizable Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Granular access by table/columns based on token-claims&lt;/li&gt;
&lt;li&gt;Data and column validations&lt;/li&gt;
&lt;li&gt;Query cache can be customized in multiple layers&lt;/li&gt;
&lt;li&gt;Query result handling can be fully customized&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Queries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even though the query cannot be directly converted and translated during the tree processing, the library supports multiple caching techniques, since queries need to be processed as a single statement for the entire tree&lt;/p&gt;

&lt;p&gt;Support of multiple cache levels&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;key: main node string
Value: Calculated query&lt;/li&gt;
&lt;li&gt;Where and Pagination are decoupled from the query, allowing better cache plans&lt;/li&gt;
&lt;li&gt;Query Result data: based on the requirements, the returning data result can be upserted and saved into the cache
Mutations
Mutations are not cached as they are directly converted and translated during the tree processing, since the upserts do not need to be combined within a single statement. Also, mutations are tightly coupled with data, so there is not much gain in caching the queries with specific values&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F874wq11wif86fal4ylmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F874wq11wif86fal4ylmm.png" alt="Customer test, 4 Parallel Threads with 100 iterations" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44nuw8qt9od42h8hbhvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44nuw8qt9od42h8hbhvk.png" alt="Customer Banking Relationship test, 4 Parallel Threads with 100 iterations" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
