<?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: Le Anh Phi</title>
    <description>The latest articles on DEV Community by Le Anh Phi (@muonroi).</description>
    <link>https://dev.to/muonroi</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%2F3870742%2F99418a18-756e-4eec-b691-8768c410fef6.jpeg</url>
      <title>DEV Community: Le Anh Phi</title>
      <link>https://dev.to/muonroi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muonroi"/>
    <language>en</language>
    <item>
      <title>Muonroi Building Block: an open-core .NET foundation for rule engines, decision tables, and multi-tenancy</title>
      <dc:creator>Le Anh Phi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 11:16:47 +0000</pubDate>
      <link>https://dev.to/muonroi/muonroi-building-block-an-open-core-net-foundation-for-rule-engines-decision-tables-and-1ndc</link>
      <guid>https://dev.to/muonroi/muonroi-building-block-an-open-core-net-foundation-for-rule-engines-decision-tables-and-1ndc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/muonroi/muonroi-building-block" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Status:&lt;/strong&gt; public repo, &lt;strong&gt;open-core&lt;/strong&gt; (Apache-2.0 OSS packages + commercial-licensed packages).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Target audience:&lt;/strong&gt; &lt;strong&gt;unknown&lt;/strong&gt; (repo docs suggest teams building .NET services that need rule orchestration, decision tables, multi-tenancy, and governance primitives).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Version:&lt;/strong&gt; &lt;code&gt;1.0.0-alpha.9&lt;/code&gt; (repo-wide versioning is configured via &lt;code&gt;Directory.Build.props&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Executive summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Muonroi Building Block&lt;/strong&gt; is the .NET foundation of the Muonroi ecosystem. It bundles a &lt;em&gt;rule engine stack&lt;/em&gt; (strongly typed rules + orchestration + tracing), &lt;strong&gt;decision tables&lt;/strong&gt; (with common hit policies), and supporting infrastructure like governance/licensing concepts and multi-tenancy helpers. The repository is &lt;strong&gt;open-core&lt;/strong&gt;: OSS packages are Apache 2.0, while commercial packages are distributed under a separate commercial license and are expected to be gated at runtime.&lt;/p&gt;

&lt;p&gt;A key differentiator is its developer experience around rule authoring: write rule logic in normal C#, mark it with an attribute, then let &lt;strong&gt;source generators and CLI tools&lt;/strong&gt; generate rule classes and DI registration glue. This reduces handmade boilerplate and allows verification steps (e.g., dependency checks) before runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key features and use cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key features (as described by repo README + deep map)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strongly typed rule abstraction&lt;/strong&gt; (&lt;code&gt;IRule&amp;lt;TContext&amp;gt;&lt;/code&gt;) and shared state via a &lt;strong&gt;FactBag&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule orchestration&lt;/strong&gt; with execution hooks, ordering, and dependency constraints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision table engine&lt;/strong&gt; with widely used hit policies (Unique, Any, First, All, Collect, RuleOrder).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source generators + analyzers&lt;/strong&gt; to extract rules from code and generate DI registration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI toolchain&lt;/strong&gt; (RuleGen) for extract/verify/register/watch flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenancy&lt;/strong&gt; packages for resolving tenant context and linking per-tenant resources.&lt;/li&gt;
&lt;li&gt;Explicit &lt;strong&gt;OSS/commercial boundary enforcement&lt;/strong&gt; via scripts (modular boundary checks).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practical use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy/risk/fraud scoring&lt;/strong&gt; where rules evolve faster than deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision tables&lt;/strong&gt; for business-friendly rule maintenance with deterministic evaluation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenant SaaS&lt;/strong&gt; foundations: consistent tenant resolution + quota enforcement primitives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preproduction verification&lt;/strong&gt;: catch rule dependency errors (and other analyzer-driven issues) before runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture and main components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Big-picture: rule execution pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
  Input[Input context + facts] --&amp;gt; Orchestrator[IMRuleOrchestrator.ExecuteAsync]
  Orchestrator --&amp;gt; FactBag[FactBag shared state]
  FactBag --&amp;gt; Rules[Compiled rules / FEEL / decision tables / flow graph]
  Rules --&amp;gt; Result[OrchestratorResult + updated facts]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Big-picture: code-first rule authoring + generation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  Dev[Developer writes C# method] --&amp;gt; Attr[[MExtractAsRule]]
  Attr --&amp;gt; CLI[muonroi-rule extract/register/verify]
  CLI --&amp;gt; Gen[Generated rule classes + DI registration]
  Gen --&amp;gt; DI[services.AddRuleEngine&amp;lt;T&amp;gt;() + AddGeneratedRules()]
  DI --&amp;gt; Runtime[Runtime executes rules via orchestrator]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monorepo layout (high level)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;muonroi-building-block/
  src/
    Muonroi.RuleEngine.Abstractions/
    Muonroi.RuleEngine.Core/
    Muonroi.RuleEngine.DecisionTable/
    Muonroi.RuleEngine.SourceGenerators/
    Muonroi.Tenancy.*
    Muonroi.Governance.*
    Muonroi.Observability
    (...more packages...)
  tools/
    Muonroi.RuleGen/                  # CLI for rule extraction/registration/verification
    Muonroi.DecisionTableGen/         # decision table tooling (per deep map)
    Muonroi.RuleGen.VisualStudio/     # VS extension (per deep map)
    Muonroi.RuleGen/vscode-extension/ # VS Code extension (per deep map)
  samples/
    Quickstart.RuleEngine/
    Quickstart.DecisionTable/
    FraudDetection/
    LoanApproval/
    MultiTenantSaaS/
    RuleSourceGen/
  REPO_DEEP_MAP.md
  OSS-BOUNDARY.md
  LICENSE-APACHE / LICENSE-COMMERCIAL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want the “map of everything,” the repo provides it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/REPO_DEEP_MAP.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/REPO_DEEP_MAP.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation and quickstart
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install the core rule engine packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Muonroi.RuleEngine.Core
dotnet add package Muonroi.RuleEngine.SourceGenerators
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Exact versions are &lt;strong&gt;unknown&lt;/strong&gt; here; prefer pinning versions explicitly for production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Quick example: write a rule in plain C
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MExtractAsRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HIGH_VALUE_ORDER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DependsOn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"CREDIT_SCORE"&lt;/span&gt; &lt;span class="p"&gt;})]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;RuleResult&lt;/span&gt; &lt;span class="nf"&gt;HighValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FactBag&lt;/span&gt; &lt;span class="n"&gt;facts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;1000m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RuleResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Below threshold."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;facts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"requiresReview"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RuleResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generate the glue code and wire up DI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;muonroi-rule extract &lt;span class="nt"&gt;--source&lt;/span&gt; src/Rules &lt;span class="nt"&gt;--output&lt;/span&gt; Generated/Rules
muonroi-rule register &lt;span class="nt"&gt;--rules&lt;/span&gt; Generated/Rules &lt;span class="nt"&gt;--output&lt;/span&gt; Generated/RuleEngineRegistrationExtensions.g.cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Muonroi.RuleEngine.Generated&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRuleEngine&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddGeneratedRules&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run a sample (Rule Engine quickstart)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;workspace-root&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;\muonroi-building-block\samples\Quickstart.RuleEngine\src\Quickstart.RuleEngine.Api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-X&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http://localhost:5000/api/orders/evaluate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{\"&lt;/span&gt;&lt;span class="nx"&gt;amount\&lt;/span&gt;&lt;span class="s2"&gt;":1200,\"&lt;/span&gt;&lt;span class="nx"&gt;customerType\&lt;/span&gt;&lt;span class="s2"&gt;":\"&lt;/span&gt;&lt;span class="nx"&gt;premium\&lt;/span&gt;&lt;span class="s2"&gt;",\"&lt;/span&gt;&lt;span class="nx"&gt;countryCode\&lt;/span&gt;&lt;span class="s2"&gt;":\"&lt;/span&gt;&lt;span class="nx"&gt;US\&lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run a sample (Decision Table quickstart)
&lt;/h3&gt;

&lt;p&gt;Start Postgres locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;muonroi-sample-postgres&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;muonroi_decision_tables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5432:5432&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;postgres:16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the API sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;workspace-root&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;\muonroi-building-block\samples\Quickstart.DecisionTable\src\Quickstart.DecisionTable.Api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create and execute a table via REST APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:5000/api/v1/decision-tables"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-ContentType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-InFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".\assets\discount-table.json"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"inputs":{"amount":1200,"customerType":"premium","country":"US"}}'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:5000/api/v1/decision-tables/discount-rules/execute"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-ContentType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contribution guide and license
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Contributing
&lt;/h3&gt;

&lt;p&gt;The contribution guide emphasizes “boundary-safe” work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default working branch: &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prereqs: .NET SDK 8+, PowerShell 7+; Postgres/Redis only if your change needs them&lt;/li&gt;
&lt;li&gt;Run tests + the &lt;strong&gt;modular boundary check&lt;/strong&gt; before opening a PR:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pwsh ./scripts/check-modular-boundaries.ps1 &lt;span class="nt"&gt;-RepoRoot&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
dotnet &lt;span class="nb"&gt;test &lt;/span&gt;Muonroi.BuildingBlock.sln &lt;span class="nt"&gt;-c&lt;/span&gt; Debug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contributing guide:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/CONTRIBUTING.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  License (open-core)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OSS packages: Apache 2.0 (&lt;code&gt;LICENSE-APACHE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Commercial packages: Muonroi commercial license (&lt;code&gt;LICENSE-COMMERCIAL&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The repo documents an &lt;strong&gt;OSS/commercial boundary rule&lt;/strong&gt; and checks it via a script:

&lt;ul&gt;
&lt;li&gt;OSS packages MUST NOT depend on commercial packages.&lt;/li&gt;
&lt;li&gt;Commercial packages MAY depend on OSS packages.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Key boundary doc:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/OSS-BOUNDARY.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/OSS-BOUNDARY.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;License files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/LICENSE-APACHE" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/LICENSE-APACHE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/LICENSE-COMMERCIAL" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/LICENSE-COMMERCIAL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison to similar projects (brief)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Microsoft RulesEngine&lt;/strong&gt;: JSON-defined workflows and dynamic expression evaluation; Muonroi Building Block offers a more “code-first + source-generated” workflow (plus decision tables, tenancy/governance packages).&lt;br&gt;&lt;br&gt;
References:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://microsoft.github.io/RulesEngine/" rel="noopener noreferrer"&gt;https://microsoft.github.io/RulesEngine/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/RulesEngine" rel="noopener noreferrer"&gt;https://github.com/microsoft/RulesEngine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;NRules&lt;/strong&gt;: Rete-based .NET rules engine with an internal DSL in C#. Muonroi’s approach leans more toward orchestration + multiple rule types (compiled rules, decision tables, FEEL, flow graphs) and a CLI/source-generator pipeline.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Reference: &lt;a href="https://github.com/NRules/NRules" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://github.com/NRules/NRules" rel="noopener noreferrer"&gt;https://github.com/NRules/NRules&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Drools / DMN decision tables&lt;/strong&gt;: DMN decision tables and FEEL are widely used in decision modeling; Muonroi explicitly implements decision tables and FEEL-related pieces in its runtime/tooling.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Reference: &lt;a href="https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html" rel="noopener noreferrer"&gt;https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Suggested tags and social blurb
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Suggested dev.to tags
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;dotnet&lt;/code&gt;, &lt;code&gt;csharp&lt;/code&gt;, &lt;code&gt;rulesengine&lt;/code&gt;, &lt;code&gt;decisiontable&lt;/code&gt;, &lt;code&gt;opensource&lt;/code&gt;, &lt;code&gt;multitenant&lt;/code&gt;, &lt;code&gt;architecture&lt;/code&gt;, &lt;code&gt;sourcegenerators&lt;/code&gt;, &lt;code&gt;cli&lt;/code&gt;, &lt;code&gt;observability&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Social blurb (3–5 lines)
&lt;/h3&gt;

&lt;p&gt;Muonroi Building Block is an open-core .NET foundation for rule engines, decision tables, and multi-tenant services.&lt;br&gt;&lt;br&gt;
It supports code-first rules + source-generated registration, decision table evaluation, and runtime orchestration with shared FactBag state.&lt;br&gt;&lt;br&gt;
If you’re building policy-heavy systems (risk/fraud/pricing) and want strong DX around rule authoring, it’s worth a deep look.&lt;br&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/muonroi/muonroi-building-block" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repo deep map: &lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/REPO_DEEP_MAP.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/REPO_DEEP_MAP.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OSS boundary doc: &lt;a href="https://github.com/muonroi/muonroi-building-block/blob/main/OSS-BOUNDARY.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-building-block/blob/main/OSS-BOUNDARY.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft RulesEngine: &lt;a href="https://github.com/microsoft/RulesEngine" rel="noopener noreferrer"&gt;https://github.com/microsoft/RulesEngine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NRules: &lt;a href="https://github.com/NRules/NRules" rel="noopener noreferrer"&gt;https://github.com/NRules/NRules&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Drools DMN + decision tables: &lt;a href="https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html" rel="noopener noreferrer"&gt;https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>rulesengine</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Muonroi UI Engine: a manifest-driven UI runtime + rule-authoring web components (open-core)</title>
      <dc:creator>Le Anh Phi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 11:16:02 +0000</pubDate>
      <link>https://dev.to/muonroi/muonroi-ui-engine-a-manifest-driven-ui-runtime-rule-authoring-web-components-open-core-k9f</link>
      <guid>https://dev.to/muonroi/muonroi-ui-engine-a-manifest-driven-ui-runtime-rule-authoring-web-components-open-core-k9f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/muonroi/muonroi-ui-engine" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Status:&lt;/strong&gt; public repo, &lt;strong&gt;open-core&lt;/strong&gt; (some packages are Apache-2.0 OSS, some are commercial-licensed).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Target audience:&lt;/strong&gt; &lt;strong&gt;unknown&lt;/strong&gt; (repo docs suggest teams building backend-driven UI + rule-authoring UIs).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Version:&lt;/strong&gt; workspace &lt;code&gt;0.1.22&lt;/code&gt; (from &lt;code&gt;package.json&lt;/code&gt;); MVC package &lt;code&gt;0.1.0&lt;/code&gt; (from &lt;code&gt;.csproj&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Executive summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Muonroi UI Engine&lt;/strong&gt; is the frontend / host-integration layer of the Muonroi ecosystem. Its core idea is &lt;strong&gt;backend-driven UI&lt;/strong&gt;: a host app fetches a &lt;em&gt;manifest&lt;/em&gt; that describes navigation, screens, components, actions, and the component registry, then a runtime turns it into a render plan for your framework (React / Angular / PrimeNG).&lt;/p&gt;

&lt;p&gt;The repo also contains &lt;strong&gt;open-core rule-authoring UI surfaces&lt;/strong&gt; built as Web Components (Lit): decision tables, rule flow designer, FEEL playground, tracing, etc. These appear to require a commercial license / “activation proof” at runtime, while the base runtime + adapters stay usable without commercial dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key features and use cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key features (from repo structure and deep map)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manifest schema (v1/v2)&lt;/strong&gt; that models navigation groups, screens, components, actions, data sources, registry, auth profile, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Core runtime&lt;/strong&gt; that resolves screens by route and checks what can render/execute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework adapters&lt;/strong&gt; for:

&lt;ul&gt;
&lt;li&gt;React (&lt;code&gt;@muonroi/ui-engine-react&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Angular (&lt;code&gt;@muonroi/ui-engine-angular&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;PrimeNG (&lt;code&gt;@muonroi/ui-engine-primeng&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Web Components (Lit)&lt;/strong&gt; rule-authoring widgets (commercial modules), exposed via tags like:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;mu-decision-table&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;mu-rule-flow-designer&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;mu-feel-playground&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;mu-rule-trace-viewer&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;ASP.NET MVC bridge&lt;/strong&gt; (&lt;code&gt;Muonroi.Ui.Engine.Mvc&lt;/code&gt;) for server-rendered hosts: manifest models + helper extensions.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practical use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend-driven admin portals&lt;/strong&gt; where navigation + screen composition are shipped from a server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable UIs across multiple frontend stacks&lt;/strong&gt;: reuse the same manifest across React and Angular apps via adapters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded rule-authoring experiences&lt;/strong&gt; (decision tables / flow designer) inside an internal control plane.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-rendered hosts&lt;/strong&gt; that need to load a manifest and drive “what to show” in MVC views.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture and main components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Big-picture (how the UI engine flows)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  Host[Host app (React / Angular / MVC)] --&amp;gt;|fetch JSON manifest| Manifest[MUiEngineManifest]
  Manifest --&amp;gt; Runtime[MUiEngineRuntime]
  Runtime --&amp;gt; Plan[Render plan / layout plan]
  Plan --&amp;gt; Adapter[Framework adapter&amp;lt;br/&amp;gt;(React/Angular/PrimeNG)]
  Adapter --&amp;gt; UI[Actual UI components&amp;lt;br/&amp;gt;+ custom elements]
  UI --&amp;gt;|calls| APIs[Backend endpoints]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monorepo layout (high level)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;muonroi-ui-engine/
  packages/
    m-ui-engine-core/                 # OSS runtime + schema contracts
    m-ui-engine-react/                # OSS React wrappers
    m-ui-engine-angular/              # OSS Angular mappers
    m-ui-engine-primeng/              # OSS PrimeNG adapter
    m-ui-engine-rule-components/      # Commercial: decision tables, flow designer, FEEL, trace...
    m-ui-engine-rule-components-primeng  # Commercial: PrimeNG adapter for rule components
    m-ui-engine-signalr/              # Commercial: schema watcher via SignalR
    m-ui-engine-sync/                 # Commercial: CLI sync tooling
  src/
    Muonroi.Ui.Engine.Mvc/            # OSS .NET MVC bridge package
  tests/
    Muonroi.Ui.Engine.Mvc.Tests/      # tests mostly concentrated here (per repo README)
  REPO_DEEP_MAP.md                    # file-level map of the monorepo
  LICENSE / LICENSE-APACHE / LICENSE-COMMERCIAL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core runtime package: what’s inside
&lt;/h3&gt;

&lt;p&gt;The file-level map highlights core “building blocks” such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;contracts.ts&lt;/code&gt;: the manifest schema (&lt;code&gt;MUiEngineManifest&lt;/code&gt;, &lt;code&gt;MUiEngineScreen&lt;/code&gt;, &lt;code&gt;MUiEngineAction&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;runtime.ts&lt;/code&gt;: &lt;code&gt;MUiEngineRuntime&lt;/code&gt; (screen resolution, permission checks).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bootstrap.ts&lt;/code&gt;: bootstrapper, manifest provider, schema watcher, telemetry.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;adapters.ts&lt;/code&gt;: render adapters + render-plan builders.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;license/MLicenseVerifier.ts&lt;/code&gt;: license verification used to gate commercial modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only read one file before diving deeper, start here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/REPO_DEEP_MAP.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/REPO_DEEP_MAP.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optional commercial rule-authoring surface
&lt;/h3&gt;

&lt;p&gt;The deep map lists many UI widgets shipped as &lt;strong&gt;custom elements&lt;/strong&gt; (Lit). A typical flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
  App[Host app] --&amp;gt;|bootstraps custom elements| Loader[MLoadRuleEngineCustomElements]
  Loader --&amp;gt; Gate[Commercial license check]
  Gate --&amp;gt;|license ok| Widgets[Decision table / Flow designer / FEEL / Trace widgets]
  Gate --&amp;gt;|not licensed| Prompt[Upgrade prompt / restricted UI]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installation and quickstart
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Build the monorepo locally (TypeScript workspace)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install
&lt;/span&gt;pnpm build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The root &lt;code&gt;package.json&lt;/code&gt; indicates a workspace layout with &lt;code&gt;packages/*&lt;/code&gt; and scripts that run workspace builds/tests.&lt;/li&gt;
&lt;li&gt;Tooling includes TypeScript and Vitest (for tests), and the repo references Vite configs for certain bundles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install the ASP.NET MVC host bridge
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Muonroi.Ui.Engine.Mvc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Compatibility warning:&lt;/strong&gt; the &lt;code&gt;.csproj&lt;/code&gt; targets &lt;code&gt;net9.0&lt;/code&gt; (check your runtime/SDK availability).&lt;/p&gt;

&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Bootstrapping rule-authoring custom elements from React
&lt;/h3&gt;

&lt;p&gt;The README shows a React setup that loads custom elements and renders the flow designer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;MLoadRuleEngineCustomElements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;MuRuleFlowDesignerReact&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@muonroi/ui-engine-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;MLoadRuleEngineCustomElements&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;activationProof&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MuRuleFlowDesignerReact&lt;/span&gt;
  &lt;span class="na"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;workflowName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wf.orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/api/v1"&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What’s unknown:&lt;/strong&gt; how &lt;code&gt;activationProof&lt;/code&gt; is obtained and what exact fields it contains (it’s part of the commercial story).&lt;/p&gt;

&lt;h3&gt;
  
  
  2) A minimal (illustrative) manifest snippet
&lt;/h3&gt;

&lt;p&gt;Based on the TypeScript contracts, a manifest is shaped roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schemaVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mui.engine.v2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generatedAtUtc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-14T00:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tenantId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tenant-a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"navigationGroups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"screens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dataSources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"componentRegistry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"components"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3) MVC host: working with manifest models
&lt;/h3&gt;

&lt;p&gt;The MVC package includes manifest models like &lt;code&gt;MUiEngineManifest&lt;/code&gt;, &lt;code&gt;MUiEngineNavigationGroup&lt;/code&gt;, &lt;code&gt;MUiEngineScreen&lt;/code&gt;, etc. You can also use extension helpers like &lt;code&gt;MVisibleItems()&lt;/code&gt; for view-level rendering logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@using&lt;/span&gt; &lt;span class="n"&gt;Muonroi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mvc&lt;/span&gt;
&lt;span class="n"&gt;@using&lt;/span&gt; &lt;span class="n"&gt;Muonroi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mvc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Models&lt;/span&gt;
&lt;span class="n"&gt;@model&lt;/span&gt; &lt;span class="n"&gt;MUiEngineManifest&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;@foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NavigationGroups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GroupDisplayName&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nf"&gt;@foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MVisibleItems&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contribution guide and license
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Contributing
&lt;/h3&gt;

&lt;p&gt;The repo’s contributing guide highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default branch: &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prereqs: Node.js 20+, &lt;code&gt;pnpm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Usual workflow: &lt;code&gt;pnpm install&lt;/code&gt;, &lt;code&gt;pnpm test&lt;/code&gt;, &lt;code&gt;pnpm build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Keep the OSS/commercial boundary intact; add docs/tests when behavior changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contributing guide:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/CONTRIBUTING.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  License (open-core / dual license)
&lt;/h3&gt;

&lt;p&gt;The root license file describes a &lt;strong&gt;dual-license&lt;/strong&gt; structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OSS core + adapters: Apache 2.0 (&lt;code&gt;LICENSE-APACHE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Commercial modules: Muonroi commercial license (&lt;code&gt;LICENSE-COMMERCIAL&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;License files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE-APACHE" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE-APACHE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE-COMMERCIAL" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/LICENSE-COMMERCIAL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison to similar approaches (brief)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compared to microfrontend orchestrators (e.g., single-spa):&lt;/strong&gt; Muonroi UI Engine is centered on a &lt;em&gt;backend-driven manifest + runtime + component registry&lt;/em&gt;, not only on “mount multiple frontends into one shell.”&lt;br&gt;&lt;br&gt;
Reference (microfrontends concept): &lt;a href="https://single-spa.js.org/docs/microfrontends-concept/" rel="noopener noreferrer"&gt;https://single-spa.js.org/docs/microfrontends-concept/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compared to low-code/internal tool builders (e.g., Appsmith):&lt;/strong&gt; Appsmith focuses on a visual app builder with drag-and-drop widgets + integrations, while Muonroi UI Engine looks like a programmable runtime + adapters with optional embedded rule-authoring widgets.&lt;br&gt;&lt;br&gt;
Reference: &lt;a href="https://www.appsmith.com/" rel="noopener noreferrer"&gt;https://www.appsmith.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compared to form builders (e.g., Form.io):&lt;/strong&gt; Form.io’s open source core is strongly focused on form rendering/builder, whereas Muonroi UI Engine’s scope includes navigation/screen composition plus rule-authoring widgets (decision tables/flows).&lt;br&gt;&lt;br&gt;
Reference: &lt;a href="https://form.io/open-source/" rel="noopener noreferrer"&gt;https://form.io/open-source/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Suggested tags and social blurb
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Suggested dev.to tags
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;muonroi&lt;/code&gt;, &lt;code&gt;typescript&lt;/code&gt;, &lt;code&gt;webcomponents&lt;/code&gt;, &lt;code&gt;react&lt;/code&gt;, &lt;code&gt;angular&lt;/code&gt;, &lt;code&gt;dotnet&lt;/code&gt;, &lt;code&gt;lit&lt;/code&gt;, &lt;code&gt;backenddrivenui&lt;/code&gt;, &lt;code&gt;monorepo&lt;/code&gt;, &lt;code&gt;opensource&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Social blurb (3–5 lines)
&lt;/h3&gt;

&lt;p&gt;Muonroi UI Engine is a manifest-driven UI runtime (open-core) that lets your backend describe navigation/screens/components—and renders them through React/Angular/PrimeNG adapters.&lt;br&gt;&lt;br&gt;
It also ships optional Lit-based rule-authoring widgets (decision tables, flow designer, FEEL playground, tracing).&lt;br&gt;&lt;br&gt;
If you’re exploring backend-driven UI + embeddable rule tooling, this monorepo is worth a look.&lt;br&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/muonroi/muonroi-ui-engine" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repo deep map: &lt;a href="https://github.com/muonroi/muonroi-ui-engine/blob/main/REPO_DEEP_MAP.md" rel="noopener noreferrer"&gt;https://github.com/muonroi/muonroi-ui-engine/blob/main/REPO_DEEP_MAP.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;single-spa microfrontends concept: &lt;a href="https://single-spa.js.org/docs/microfrontends-concept/" rel="noopener noreferrer"&gt;https://single-spa.js.org/docs/microfrontends-concept/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Appsmith: &lt;a href="https://www.appsmith.com/" rel="noopener noreferrer"&gt;https://www.appsmith.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Form.io open source: &lt;a href="https://form.io/open-source/" rel="noopener noreferrer"&gt;https://form.io/open-source/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webcomponents</category>
      <category>react</category>
      <category>angular</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Quick Codex: a lightweight workflow layer for Codex CLI</title>
      <dc:creator>Le Anh Phi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 09:50:02 +0000</pubDate>
      <link>https://dev.to/muonroi/quick-codex-a-lightweight-workflow-layer-for-codex-cli-2p1f</link>
      <guid>https://dev.to/muonroi/quick-codex-a-lightweight-workflow-layer-for-codex-cli-2p1f</guid>
      <description>&lt;p&gt;Codex is very good at focused execution.&lt;/p&gt;

&lt;p&gt;But once a task gets a little bigger, a familiar problem shows up: the work starts living in chat memory.&lt;/p&gt;

&lt;p&gt;You clarify the task in one turn, research a few gaps in the next, begin implementation, then come back later and wonder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What exactly was the agreed scope?&lt;/li&gt;
&lt;li&gt;Which part is done?&lt;/li&gt;
&lt;li&gt;What is the next safe step?&lt;/li&gt;
&lt;li&gt;Can I trust the current state, or am I already drifting?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That pain point is why I built &lt;strong&gt;&lt;a href="https://github.com/muonroi/quick-codex" rel="noopener noreferrer"&gt;Quick Codex&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is an open-source, lightweight workflow layer for Codex CLI. The goal is simple: make medium-sized work more &lt;strong&gt;resumable, auditable, and harder to derail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not bigger. Not more complex. Just more durable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem is not coding, it is continuity
&lt;/h2&gt;

&lt;p&gt;In my experience, raw Codex is strongest when the task is already clear and the execution window is short.&lt;/p&gt;

&lt;p&gt;The trouble starts when a task spans multiple turns and the workflow stays implicit.&lt;/p&gt;

&lt;p&gt;Something like this happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You explain the problem
&lt;/li&gt;
&lt;li&gt;Codex explores a few files
&lt;/li&gt;
&lt;li&gt;A plan starts to form
&lt;/li&gt;
&lt;li&gt;Implementation begins
&lt;/li&gt;
&lt;li&gt;Context gets fuzzy
&lt;/li&gt;
&lt;li&gt;The next step is no longer obvious
&lt;/li&gt;
&lt;li&gt;Drift starts
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At that point, you are not fighting code generation anymore. You are fighting &lt;strong&gt;state loss&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is the gap Quick Codex is trying to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Quick Codex actually does
&lt;/h2&gt;

&lt;p&gt;Quick Codex adds a small local workflow surface around Codex CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;qc-flow&lt;/code&gt; → front-half work&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;qc-lock&lt;/code&gt; → strict execution&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CLI utilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;status&lt;/li&gt;
&lt;li&gt;resume&lt;/li&gt;
&lt;li&gt;doctor-run&lt;/li&gt;
&lt;li&gt;repair-run&lt;/li&gt;
&lt;li&gt;lock-check&lt;/li&gt;
&lt;li&gt;verify-wave&lt;/li&gt;
&lt;li&gt;close-wave&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; workflow state should live in files, not only in chat memory.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Two modes, two different jobs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  qc-flow
&lt;/h3&gt;

&lt;p&gt;Use when the task is still unclear.&lt;/p&gt;

&lt;h3&gt;
  
  
  qc-lock
&lt;/h3&gt;

&lt;p&gt;Use when the scope is already defined and needs strict control.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx quick-codex &lt;span class="nb"&gt;install
&lt;/span&gt;node bin/quick-codex.js status &lt;span class="nt"&gt;--dir&lt;/span&gt; /path/to/project
node bin/quick-codex.js resume &lt;span class="nt"&gt;--dir&lt;/span&gt; /path/to/project
node bin/quick-codex.js doctor-run &lt;span class="nt"&gt;--dir&lt;/span&gt; /path/to/project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/muonroi/quick-codex" rel="noopener noreferrer"&gt;https://github.com/muonroi/quick-codex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/quick-codex" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/quick-codex&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>cli</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Experience Engine: AI Memory That Shrinks As Your Agent Learns</title>
      <dc:creator>Le Anh Phi</dc:creator>
      <pubDate>Fri, 10 Apr 2026 01:44:43 +0000</pubDate>
      <link>https://dev.to/muonroi/experience-engine-ai-memory-that-shrinks-as-your-agent-learns-2jee</link>
      <guid>https://dev.to/muonroi/experience-engine-ai-memory-that-shrinks-as-your-agent-learns-2jee</guid>
      <description>&lt;p&gt;Every AI coding session, my agent made the same mistakes.&lt;/p&gt;

&lt;p&gt;DbContext as singleton — state corruption, 15 minutes debugging. &lt;strong&gt;Again.&lt;/strong&gt; ILogger instead of IMLog — lost tenant context. &lt;strong&gt;Again.&lt;/strong&gt; Wrong project reference path — build fails. &lt;strong&gt;Again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had 500 memory notes. My agent was still a junior with a bigger notebook.&lt;/p&gt;

&lt;p&gt;So I built something different.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With AI Memory
&lt;/h2&gt;

&lt;p&gt;Every AI memory tool — Mem0, Letta, Zep — stores &lt;strong&gt;facts&lt;/strong&gt;. More sessions = more entries = more tokens = more cost. They're giving your agent a bigger notebook.&lt;/p&gt;

&lt;p&gt;But here's the thing: &lt;strong&gt;a notebook doesn't make you experienced.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A junior developer with 500 notes is still a junior. A mid-level developer with 15 principles understands &lt;em&gt;why&lt;/em&gt; things work. The difference isn't how much you remember — it's whether you can &lt;strong&gt;generalize&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Junior (500 notes):
  "DbContext singleton caused bug"
  "HttpClient singleton caused leak"  
  "SmtpClient singleton caused corruption"
  → Encounters RedisConnection singleton → NO MATCH → makes the mistake

Mid-level (1 principle):
  "Stateful objects must be scoped, never singleton"
  → Encounters RedisConnection singleton → MATCHES → avoids the mistake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's what Experience Engine does. It doesn't store more facts. It &lt;strong&gt;evolves facts into principles&lt;/strong&gt;, then deletes the facts.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;When you code with any AI agent (Claude Code, Gemini CLI, Codex CLI), Experience Engine runs silently in the background:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before every Edit/Write/Bash:&lt;/strong&gt;&lt;br&gt;
A hook queries the experience store: "Have I seen this mistake before?" If yes, it injects a warning directly into the agent's context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⚠️ [Experience - High Confidence (0.85)]: Stateful objects must be 
scoped, never singleton. Last time SingleInstance caused state 
corruption in DbContext.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent reads this warning and avoids the mistake. No human intervention needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After every session:&lt;/strong&gt;&lt;br&gt;
An extractor scans the session transcript for mistake patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry loops (same tool call 3+ times)&lt;/li&gt;
&lt;li&gt;User corrections ("no, not that", "wrong", "undo")&lt;/li&gt;
&lt;li&gt;Test fail → fix cycles&lt;/li&gt;
&lt;li&gt;Git reverts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each detected mistake gets extracted into a structured Q&amp;amp;A entry and stored in a vector database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weekly (automatic):&lt;/strong&gt;&lt;br&gt;
The evolution engine runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Promote&lt;/strong&gt;: entries confirmed 3+ times move from cache → behavioral rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstract&lt;/strong&gt;: clusters of 3+ similar entries → one general principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demote&lt;/strong&gt;: entries ignored 3+ times get deprioritized&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive&lt;/strong&gt;: entries unused for 90 days get cleaned up&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result: &lt;strong&gt;memory shrinks as capability grows.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The 4-Tier Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T0 Principles  (~400 tokens)  — generalized rules, always loaded
    "Stateful objects must be scoped, never singleton"

T1 Behavioral  (~600 tokens)  — specific reflexes, always loaded
    "WHEN DbContext + DI → MUST check lifetime FIRST"

T2 QA Cache    (semantic)     — detailed Q&amp;amp;A, retrieved on match
    Q: "Why not singleton?" → A: "State corruption across requests"

T3 Raw         (staging)      — unprocessed mistakes, TTL 30 days

Lifecycle: T3 → extract → T2 → promote (3x confirmed) → T1 
           → generalize (cluster 3+) → T0
           Memory SHRINKS as capability GROWS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  What Makes This Different
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Mem0&lt;/th&gt;
&lt;th&gt;Letta&lt;/th&gt;
&lt;th&gt;Zep&lt;/th&gt;
&lt;th&gt;Experience Engine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Over time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Entries grow forever&lt;/td&gt;
&lt;td&gt;Entries grow forever&lt;/td&gt;
&lt;td&gt;Entries grow forever&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Entries shrink into principles&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Novel cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only exact matches&lt;/td&gt;
&lt;td&gt;Only exact matches&lt;/td&gt;
&lt;td&gt;Only exact matches&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Principles generalize&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mistake learning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 detection patterns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python + SDK&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Zero (Node.js built-in)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Local-first&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cloud vendor&lt;/td&gt;
&lt;td&gt;SaaS terms&lt;/td&gt;
&lt;td&gt;Cloud vendor&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;You own everything&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Experience Graph
&lt;/h2&gt;

&lt;p&gt;Experiences aren't isolated entries — they're linked with typed edges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DbContext singleton ──generalizes──→ "Stateful objects: always scoped"
                    ──relates-to───→ HttpClient singleton  
                    ──supersedes───→ [old] "Use transient for DbContext"
                    ──contradicts──→ [demoted] "Singleton is fine for DbContext"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When one experience matches your current action, the engine follows edges to surface related experiences too. This is how it catches RedisConnection singleton — not because it's seen Redis before, but because it's &lt;strong&gt;connected&lt;/strong&gt; to the principle about stateful objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Temporal Reasoning
&lt;/h2&gt;

&lt;p&gt;Knowledge evolves. What was true in January might be wrong in March:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;January:  "Use singleton for HttpClient" (confirmed 5x)
March:    "Use IHttpClientFactory instead" (contradicts January)
          → January entry superseded, not deleted
          → March entry ranks higher (recent confirmation)
          → GET /api/timeline?topic=httpclient shows the evolution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine tracks &lt;code&gt;confirmedAt[]&lt;/code&gt; arrays — not just "what was learned" but "when it was last confirmed." Stale knowledge gets penalized. Recent confirmations get boosted.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST API
&lt;/h2&gt;

&lt;p&gt;Everything is accessible via HTTP — not just CLI hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the server&lt;/span&gt;
node server.js
&lt;span class="c"&gt;# Experience Engine API running on http://localhost:8082&lt;/span&gt;

&lt;span class="c"&gt;# Check health&lt;/span&gt;
curl localhost:8082/health

&lt;span class="c"&gt;# Query experience before a tool call&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST localhost:8082/api/intercept &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"toolName":"Write","toolInput":{"file_path":"src/Startup.cs"}}'&lt;/span&gt;

&lt;span class="c"&gt;# Response:&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"suggestions"&lt;/span&gt;: &lt;span class="s2"&gt;"⚠️ [High Confidence (0.85)]: Stateful objects must be scoped"&lt;/span&gt;,
  &lt;span class="s2"&gt;"hasSuggestions"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Trigger evolution&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST localhost:8082/api/evolve
&lt;span class="c"&gt;# {"promoted":2,"abstracted":1,"demoted":0,"archived":3,"success":true}&lt;/span&gt;

&lt;span class="c"&gt;# View stats&lt;/span&gt;
curl localhost:8082/api/stats?since&lt;span class="o"&gt;=&lt;/span&gt;30d

&lt;span class="c"&gt;# Knowledge timeline&lt;/span&gt;
curl &lt;span class="s2"&gt;"localhost:8082/api/timeline?topic=dependency+injection"&lt;/span&gt;

&lt;span class="c"&gt;# Experience graph&lt;/span&gt;
curl &lt;span class="s2"&gt;"localhost:8082/api/graph?id=abc-123"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10 endpoints total. Zero dependencies — uses Node.js built-in &lt;code&gt;http&lt;/code&gt; module. CORS enabled for browser extensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python SDK
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;muonroi_experience&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8082&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Query experience
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file_path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hasSuggestions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;suggestions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Extract lessons
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent tried singleton for DbContext, caused corruption...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Trigger evolution  
&lt;/span&gt;&lt;span class="n"&gt;evolution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Promoted: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;evolution&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;promoted&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Abstracted: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;evolution&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;abstracted&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Check stats
&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mistakes avoided: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;suggestions&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# View knowledge timeline
&lt;/span&gt;&lt;span class="n"&gt;timeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dependency injection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[superseded]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;superseded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;solution&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero dependencies — uses Python stdlib &lt;code&gt;urllib&lt;/code&gt;. Python 3.8+.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-User Support
&lt;/h2&gt;

&lt;p&gt;Multiple developers on the same machine get isolated stores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;EXP_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;alice node server.js    &lt;span class="c"&gt;# Alice's experiences&lt;/span&gt;
&lt;span class="nv"&gt;EXP_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bob node server.js      &lt;span class="c"&gt;# Bob's (completely isolated)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Share principles without sharing personal data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Alice shares a principle she evolved&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST localhost:8082/api/principles/share &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"principleId": "abc-123"}'&lt;/span&gt;
&lt;span class="c"&gt;# Returns portable JSON — no personal data included&lt;/span&gt;

&lt;span class="c"&gt;# Bob imports it&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST localhost:8082/api/principles/import &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"principle":"Stateful objects must be scoped","solution":"...","confidence":0.85}'&lt;/span&gt;
&lt;span class="c"&gt;# Bob's evolution engine manages it independently from here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start (5 minutes)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/muonroi/experience-engine.git
&lt;span class="nb"&gt;cd &lt;/span&gt;experience-engine
bash .experience/setup.sh &lt;span class="nt"&gt;--local&lt;/span&gt;   &lt;span class="c"&gt;# Docker Qdrant + Ollama (100% free)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup wizard handles everything. After setup, your agent starts learning automatically through hooks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported providers
&lt;/h3&gt;

&lt;p&gt;You're not locked to Ollama. The engine supports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embedding:&lt;/strong&gt; Ollama, OpenAI, Gemini, VoyageAI, SiliconFlow, or any OpenAI-compatible API&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brain (extraction):&lt;/strong&gt; Ollama, OpenAI, Gemini, Claude, DeepSeek, SiliconFlow, or any OpenAI-compatible API&lt;/p&gt;

&lt;p&gt;Mix and match — e.g., SiliconFlow for cheap embeddings + Ollama for free extraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anti-Noise Scoring
&lt;/h2&gt;

&lt;p&gt;Not all experiences are equal. Results are ranked by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hit frequency&lt;/strong&gt; — confirmed experiences rank higher&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recency&lt;/strong&gt; — recently confirmed &amp;gt; stale (60+ days penalty)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence aging&lt;/strong&gt; — new entries start lower, climb with confirmation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignore tracking&lt;/strong&gt; — suggestions ignored 3x get demoted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain match&lt;/strong&gt; — editing &lt;code&gt;.ts&lt;/code&gt; file → TypeScript experiences rank higher&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal boost&lt;/strong&gt; — confirmed in last 7 days → score boost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superseded penalty&lt;/strong&gt; — replaced knowledge ranks lower&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means your agent gets the &lt;strong&gt;most relevant, most trusted&lt;/strong&gt; experience for the current context — not just the most similar vector match.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophy
&lt;/h2&gt;

&lt;p&gt;Every AI memory company stores your data on their cloud and charges you to access it. Mem0 stores your memories. Letta stores your agent state. You pay monthly to access your own knowledge.&lt;/p&gt;

&lt;p&gt;Experience Engine is different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your data never leaves your machine&lt;/strong&gt; (unless you choose cloud sync)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero vendor lock-in&lt;/strong&gt; — standard formats, portable profiles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies&lt;/strong&gt; — Node.js built-in modules only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The engine is open source&lt;/strong&gt; — you pay for convenience, never for capability&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Enterprise AI replaces you. Personal AI empowers you. Same technology. Different owner."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The engine is live and working. I'm dogfooding it on my own projects right now. After 2 weeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;47 suggestions fired&lt;/li&gt;
&lt;li&gt;12 mistakes avoided&lt;/li&gt;
&lt;li&gt;5 principles evolved from ~50 raw entries&lt;/li&gt;
&lt;li&gt;Memory footprint &lt;strong&gt;decreased&lt;/strong&gt; (entries compressed into principles)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up: dashboard for visualizing the "Saves" feed (mistakes the agent &lt;em&gt;didn't&lt;/em&gt; make), and a browser extension that injects experience into ChatGPT/Claude/Gemini web interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/muonroi/experience-engine" rel="noopener noreferrer"&gt;github.com/muonroi/experience-engine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License&lt;/strong&gt;: MIT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt;: 49 passing (JS) + 20 passing (Python SDK)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies&lt;/strong&gt;: Zero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're running local LLMs with Ollama, I'd love to hear how the engine works with your setup. And if you have ideas for new mistake detection patterns — PRs welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Experience Engine is MIT licensed and free forever. The core engine will never be paywalled.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>ollama</category>
    </item>
  </channel>
</rss>
