<?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: tercel</title>
    <description>The latest articles on DEV Community by tercel (@tercelyi).</description>
    <link>https://dev.to/tercelyi</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%2F3781875%2Fd782a4aa-43be-460e-bea4-e6afcf0a2607.png</url>
      <title>DEV Community: tercel</title>
      <link>https://dev.to/tercelyi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tercelyi"/>
    <language>en</language>
    <item>
      <title>Type-Safe Agents: Leveraging apcore-js in TypeScript</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Sat, 06 Jun 2026 12:32:25 +0000</pubDate>
      <link>https://dev.to/tercelyi/type-safe-agents-leveraging-apcore-js-in-typescript-2447</link>
      <guid>https://dev.to/tercelyi/type-safe-agents-leveraging-apcore-js-in-typescript-2447</guid>
      <description>&lt;p&gt;While Python dominates the AI research space, TypeScript is the engine of the modern full-stack web. From high-performance Node.js backends to complex React frontends, TypeScript provides the structure and safety that large-scale engineering teams demand.&lt;/p&gt;

&lt;p&gt;When we built the &lt;strong&gt;apcore-js&lt;/strong&gt; SDK, we didn't just want to "port" the Python logic. We wanted to create a first-class, type-safe experience that leverages the unique strengths of the JavaScript ecosystem. &lt;/p&gt;

&lt;p&gt;In this twentieth article of our series, we explore how to build AI-Perceivable modules in TypeScript using apcore and &lt;strong&gt;TypeBox&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Goal: Cross-Language Parity
&lt;/h2&gt;

&lt;p&gt;A core tenet of the apcore protocol is that a module’s behavior should be identical regardless of the implementation language. A module named &lt;code&gt;executor.user.get&lt;/code&gt; must accept the same JSON input and produce the same output in both Python and TypeScript.&lt;/p&gt;

&lt;p&gt;apcore-js achieves this by using &lt;strong&gt;TypeBox&lt;/strong&gt; as its core schema engine. TypeBox allows us to define JSON Schemas that double as TypeScript types, giving us compile-time safety and runtime validation in a single definition.&lt;/p&gt;




&lt;h2&gt;
  
  
  Defining Type-Safe Schemas
&lt;/h2&gt;

&lt;p&gt;In apcore-js, you define your module's contract using TypeBox's &lt;code&gt;Static&lt;/code&gt; and &lt;code&gt;Type&lt;/code&gt; primitives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Static&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="s1"&gt;@sinclair/typebox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;InputSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The unique UUID of the user.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;includePrivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Whether to include sensitive fields.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;InputSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By adding the &lt;code&gt;description&lt;/code&gt; field directly into the TypeBox definition, you are creating the "Cognitive Interface" for the AI while simultaneously providing type hints for your IDE.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the Module
&lt;/h2&gt;

&lt;p&gt;apcore-js supports both class-based and functional module definitions. The class-based approach is idiomatic for TypeScript developers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;ClassModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ModuleAnnotations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Context&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="s1"&gt;@apcore/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetUserModule&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ClassModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;executor.user.get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Retrieve detailed user profiles.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;inputSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;InputSchema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;annotations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ModuleAnnotations&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;readonly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;destructive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// inputs is fully typed!&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;};&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;h2&gt;
  
  
  Automated Discovery &amp;amp; Mapping
&lt;/h2&gt;

&lt;p&gt;Managing a registry in Node.js is just as easy as in Python. apcore-js includes a &lt;code&gt;FileSystemLoader&lt;/code&gt; that scans your directory structure.&lt;/p&gt;

&lt;p&gt;One of the cleverest parts of the SDK is its &lt;strong&gt;Automatic ID Normalization&lt;/strong&gt;. In TypeScript, it’s common to name your files using &lt;code&gt;camelCase&lt;/code&gt; (e.g., &lt;code&gt;sendEmail.ts&lt;/code&gt;). apcore-js automatically maps this to the canonical &lt;code&gt;snake_case&lt;/code&gt; (e.g., &lt;code&gt;send_email&lt;/code&gt;) required by the protocol. This ensures that an AI Agent sees a consistent naming convention even in a polyglot environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Trace Propagation in the Node Mesh
&lt;/h2&gt;

&lt;p&gt;AI Agents in the Node ecosystem often live inside microservices. apcore-js is built for distributed environments. It automatically propagates the &lt;code&gt;trace_id&lt;/code&gt; through &lt;code&gt;Promise&lt;/code&gt; chains and can integrate with existing tracing headers (like Zipkin or Jaeger) via custom middleware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;callAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;executor.user.get&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="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion: Reliability at Compile Time
&lt;/h2&gt;

&lt;p&gt;By combining the rigor of the apcore protocol with the safety of TypeScript and TypeBox, &lt;strong&gt;apcore-js&lt;/strong&gt; allows you to build AI-Perceivable systems that are as reliable as they are intelligent. You get the best of both worlds: high-velocity development and rock-solid architectural constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now that we’ve mastered the two most popular languages for AI, it’s time to look at the performance tier. In our next article, we dive into Zero-Cost Abstraction: Building High-Performance AI Modules in Rust.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #20 of the **Building the AI-Perceivable World&lt;/em&gt;* series. Type safety is the first step to AI safety.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore-typescript" rel="noopener noreferrer"&gt;aiperceivable/apcore-typescript&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Pythonic AI: Mastering the apcore-python SDK</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Wed, 03 Jun 2026 12:36:55 +0000</pubDate>
      <link>https://dev.to/tercelyi/pythonic-ai-mastering-the-apcore-python-sdk-5da8</link>
      <guid>https://dev.to/tercelyi/pythonic-ai-mastering-the-apcore-python-sdk-5da8</guid>
      <description>&lt;p&gt;Python is the undisputed language of the AI era. It’s the language of research, the language of LLM orchestration (LangChain, CrewAI), and for many, the language of the enterprise backend. &lt;/p&gt;

&lt;p&gt;When we designed the &lt;strong&gt;apcore-python&lt;/strong&gt; SDK, our goal was simple: &lt;strong&gt;High Perceptibility, Low Intrusion.&lt;/strong&gt; We wanted to give Python developers a way to make their code "AI-ready" without forcing them to rewrite their entire architecture.&lt;/p&gt;

&lt;p&gt;In this nineteenth article of our series, we move from the engine room to the keyboard, showing you how to master the Python SDK to build professional, AI-Perceivable modules.&lt;/p&gt;




&lt;h2&gt;
  
  
  Defining Modules: The Two Styles
&lt;/h2&gt;

&lt;p&gt;Every developer has a different preference. Some love the structure of classes; others prefer the simplicity of decorators. apcore supports both.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Decorator Style (Fast &amp;amp; Functional)
&lt;/h3&gt;

&lt;p&gt;If you have an existing utility function and you want to turn it into an AI "Skill" in 30 seconds, use the &lt;code&gt;@module&lt;/code&gt; decorator.&lt;br&gt;
&lt;/p&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;apcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt;

&lt;span class="nd"&gt;@module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text.summarize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize text for Agentic planning.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Your logic here...
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&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;...&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;h3&gt;
  
  
  2. The Class Style (Structured &amp;amp; Extensible)
&lt;/h3&gt;

&lt;p&gt;For modules that require complex state, custom initialization, or detailed behavioral annotations, the class-based approach is superior.&lt;br&gt;
&lt;/p&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;apcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ModuleAnnotations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendEmailInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendEmailModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;input_schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SendEmailInput&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Send secure internal emails.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;annotations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ModuleAnnotations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destructive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requires_approval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&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;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Business logic...
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&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;sent&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;h2&gt;
  
  
  Pydantic Integration: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;The "Killer Feature" of apcore-python is its deep integration with &lt;strong&gt;Pydantic V2&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In the AI world, your schema's &lt;code&gt;description&lt;/code&gt; fields are just as important as the types. apcore-python extracts these descriptions directly from your Pydantic models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SearchInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The search term. Use keywords, not sentences.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Max results to return.&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;When you register this module, apcore automatically generates a JSON Schema Draft 2020-12 that includes these descriptions. This ensures that the AI Agent knows exactly &lt;em&gt;how&lt;/em&gt; to use each parameter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Initializing the Core
&lt;/h2&gt;

&lt;p&gt;Starting with &lt;strong&gt;v0.18.0&lt;/strong&gt;, we’ve simplified the &lt;code&gt;APCore&lt;/code&gt; constructor to focus on a unified configuration model. You no longer pass multiple paths to the constructor; instead, you load a &lt;code&gt;Config&lt;/code&gt; object.&lt;br&gt;
&lt;/p&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;apcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;APCore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;

&lt;span class="c1"&gt;# Load config from apcore.yaml and initialize
&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apcore.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;APCore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that your security policies, pipeline steps, and registry settings are always in sync across your entire application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Execution &amp;amp; Async Support
&lt;/h2&gt;

&lt;p&gt;AI Agents are often used in asynchronous environments (web servers, background tasks). The apcore-python SDK is built for this. You can call modules synchronously or asynchronously with full trace propagation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Async execution with identity propagation
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text.summarize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&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;text&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;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; 
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion: Built for Developers, Ready for AI
&lt;/h2&gt;

&lt;p&gt;apcore-python isn't just a library; it’s a design pattern. It allows you to build software that is idiomatic for Python developers and perfectly perceivable by AI Agents. By combining the power of Pydantic with the rigor of the apcore protocol, you are building the foundation for a reliable Agentic workforce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now that we’ve mastered Python, it’s time to look at the other side of the stack. In our next article, we dive into Type-Safe Agents: Leveraging apcore-js in TypeScript.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #19 of the **Building the AI-Perceivable World&lt;/em&gt;* series. Idiomatic code is the bridge to better AI.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore-python" rel="noopener noreferrer"&gt;aiperceivable/apcore-python&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>apcore-toolkit: The Utility Backbone for Module Developers</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Mon, 01 Jun 2026 14:31:11 +0000</pubDate>
      <link>https://dev.to/tercelyi/apcore-toolkit-the-utility-backbone-for-module-developers-1fp2</link>
      <guid>https://dev.to/tercelyi/apcore-toolkit-the-utility-backbone-for-module-developers-1fp2</guid>
      <description>&lt;p&gt;In our previous articles, we’ve looked at the massive ecosystem of adapters (MCP, A2A, CLI) and the rigorous 11-step execution engine. But as an ecosystem grows, a new problem emerges: &lt;strong&gt;Maintenance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every web framework—Django, Flask, FastAPI, NestJS—needs its own apcore adapter. If each of these adapters were built from scratch, the ecosystem would quickly become a fragmented mess of duplicated logic and inconsistent behavior.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;apcore&lt;/strong&gt;, we solve this with the &lt;strong&gt;apcore-toolkit&lt;/strong&gt;. It is the shared DNA that powers every scanner and writer in our universe. In this eighteenth article, we look at the utility backbone that makes building for apcore a seamless experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Don't Reinvent the Scanner
&lt;/h2&gt;

&lt;p&gt;The core challenge of an apcore adapter is "Perception"—how do you scan an existing codebase and extract its metadata?&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;apcore-toolkit&lt;/code&gt; provides a framework-agnostic &lt;strong&gt;BaseScanner&lt;/strong&gt;. This class handles the "dirty work" of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Filtering &amp;amp; Deduplication&lt;/strong&gt;: Ensuring you don't register the same module twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path Resolution&lt;/strong&gt;: Mapping complex file structures to Canonical IDs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema Extraction&lt;/strong&gt;: Merging OpenAPI query, path, and request body parameters into a single, unified JSON Schema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using the toolkit, building a new framework adapter moves from a "one-month task" to a "one-day task."&lt;/p&gt;




&lt;h2&gt;
  
  
  Convention Module Discovery (§5.14)
&lt;/h2&gt;

&lt;p&gt;One of the "magic" features of the toolkit is the &lt;strong&gt;ConventionScanner&lt;/strong&gt;. This is what powers the "Zero Import" way to build modules.&lt;/p&gt;

&lt;p&gt;It scans a directory of plain Python files and uses &lt;strong&gt;PEP 484 Type Hints&lt;/strong&gt; to infer the AI-Perceivable contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A function &lt;code&gt;def deploy(env: str)&lt;/code&gt; automatically generates a schema with an &lt;code&gt;env&lt;/code&gt; string property.&lt;/li&gt;
&lt;li&gt;The function's docstring is extracted as the module's &lt;code&gt;description&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Module-level constants like &lt;code&gt;CLI_GROUP&lt;/code&gt; or &lt;code&gt;TAGS&lt;/code&gt; are used to populate surface-specific metadata.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that developers can focus on business logic while the toolkit handles the "Perceptibility" layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Display Overlay System (§5.13)
&lt;/h2&gt;

&lt;p&gt;How do you change the "Alias" of a module for the MCP surface without changing your source code? You use the &lt;strong&gt;DisplayResolver&lt;/strong&gt; provided by the toolkit.&lt;/p&gt;

&lt;p&gt;The toolkit implements a sparse "Display Overlay" logic. It can read a &lt;code&gt;.binding.yaml&lt;/code&gt; file and merge its display fields into your scanned modules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It handles the &lt;strong&gt;Sanitization&lt;/strong&gt; of names (e.g., ensuring MCP tool names are valid).&lt;/li&gt;
&lt;li&gt;It follows a strict &lt;strong&gt;Resolution Chain&lt;/strong&gt;: Surface-specific override &amp;gt; Display default &amp;gt; Binding default &amp;gt; Scanner value.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  AIEnhancer: The Lazy Developer’s Best Friend
&lt;/h2&gt;

&lt;p&gt;Perhaps the most forward-looking component of the toolkit is the &lt;strong&gt;AIEnhancer&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We know that legacy code is often poorly documented. Parameters are named &lt;code&gt;data&lt;/code&gt; or &lt;code&gt;arg1&lt;/code&gt;, and descriptions are missing. The AIEnhancer uses Small Language Models (SLMs) to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read your source code.&lt;/li&gt;
&lt;li&gt;Infer the &lt;em&gt;intent&lt;/em&gt; of the parameters.&lt;/li&gt;
&lt;li&gt;Generate high-quality, AI-ready descriptions and examples.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It transforms "Silent Code" into "AI-Perceivable Skills" automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Velocity Through Standardization
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;apcore-toolkit&lt;/code&gt; is the silent engine that powers the ecosystem's velocity. By standardizing the "how" of scanning and writing, it ensures that every implementation—whether it’s for a Python CLI or a Rust microservice—behaves with identical rigor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now that we’ve seen the toolkit, it’s time to get hands-on. In our next article, we dive into Pythonic AI: Mastering the apcore-python SDK.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #18 of the **Building the AI-Perceivable World&lt;/em&gt;* series. Join us in building the infrastructure for the next decade.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore-toolkit" rel="noopener noreferrer"&gt;aiperceivable/apcore-toolkit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>showdev</category>
      <category>softwareengineering</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Observability 2.0: Tracing AI "Thought Chains" with OpenTelemetry</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Sun, 31 May 2026 02:43:33 +0000</pubDate>
      <link>https://dev.to/tercelyi/observability-20-tracing-ai-thought-chains-with-opentelemetry-3dn4</link>
      <guid>https://dev.to/tercelyi/observability-20-tracing-ai-thought-chains-with-opentelemetry-3dn4</guid>
      <description>&lt;p&gt;"Why did the Agent do that?" &lt;/p&gt;

&lt;p&gt;If you are building Agentic systems today, this is the question that keeps you up at night. AI Agents are inherently non-deterministic. They loop, they reason, and they call multiple tools in sequences that are hard to predict. When a multi-step task fails, a traditional stack trace is useless. You don't just need to know &lt;em&gt;where&lt;/em&gt; the code crashed; you need to know &lt;em&gt;what&lt;/em&gt; the AI was thinking.&lt;/p&gt;

&lt;p&gt;In this seventeenth article, and the conclusion of our &lt;strong&gt;Engine&lt;/strong&gt; volume, we explore how &lt;strong&gt;apcore&lt;/strong&gt; integrates with &lt;strong&gt;OpenTelemetry (OTel)&lt;/strong&gt; to turn the "Black Box" of AI reasoning into a transparent, traceable "Glass Box."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Concept of the "Thought Span"
&lt;/h2&gt;

&lt;p&gt;In traditional distributed tracing, a "Span" represents a single unit of work—like an HTTP request or a database query. In apcore, we introduce the &lt;strong&gt;Thought Span&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every time the &lt;code&gt;Executor.call()&lt;/code&gt; method is triggered, apcore automatically wraps the execution in an OpenTelemetry span. This span isn't just a timer; it’s a rich container of AI-specific metadata:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input/Output Data&lt;/strong&gt;: What did the AI send, and what did the module return? (Sensitive data is automatically redacted).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACL Decisions&lt;/strong&gt;: Which rule allowed or denied this call?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approval Events&lt;/strong&gt;: Did a human intervene? How long did the Agent wait?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Guidance&lt;/strong&gt;: If an error occurred, what self-healing instructions were sent back to the model?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Distributed Tracing: From LLM to DB
&lt;/h2&gt;

&lt;p&gt;One of the most powerful features of apcore is its ability to propagate the &lt;code&gt;trace_id&lt;/code&gt; across network boundaries.&lt;/p&gt;

&lt;p&gt;Imagine a user makes a request to your web frontend. That request enters a &lt;code&gt;fastapi-apcore&lt;/code&gt; adapter, triggers an Orchestrator Agent, which then calls a tool module, which finally queries a PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Because apcore is &lt;strong&gt;W3C Trace-Context compatible&lt;/strong&gt;, the same &lt;code&gt;trace_id&lt;/code&gt; is carried through the entire journey. When you open a tool like &lt;strong&gt;Jaeger&lt;/strong&gt;, &lt;strong&gt;Grafana Tempo&lt;/strong&gt;, or &lt;strong&gt;Honeycomb&lt;/strong&gt;, you don't just see system logs. You see the entire "Thought Chain" of the AI connected to the actual system performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Metrics for the Agentic Era
&lt;/h2&gt;

&lt;p&gt;Tracing tells you the &lt;em&gt;Why&lt;/em&gt;; Metrics tell you the &lt;em&gt;How Much&lt;/em&gt;. apcore exposes Prometheus-ready metrics that give you a bird's-eye view of your Agentic workforce:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Execution Count&lt;/strong&gt;: Which tools are the AI's "favorites"? (Useful for optimizing frequently used paths).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Latency by Module&lt;/strong&gt;: Is the AI's reasoning being slowed down by a specific legacy API?&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hallucination Rate (Error Rate)&lt;/strong&gt;: How often does the AI send malformed inputs to a specific module? A high schema validation error rate is a signal that your module's &lt;code&gt;description&lt;/code&gt; or &lt;code&gt;documentation&lt;/code&gt; needs improvement.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Implementation: One-Line Observability
&lt;/h2&gt;

&lt;p&gt;Enabling this deep insight doesn't require complex boilerplate. In most apcore SDKs, it’s a matter of registering the &lt;code&gt;TracingMiddleware&lt;/code&gt;:&lt;br&gt;
&lt;/p&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;apcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Executor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apcore.observability.tracing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TracingMiddleware&lt;/span&gt;

&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TracingMiddleware&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;# Now everything is traceable
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By standardizing observability at the protocol level, we ensure that every implementation—whether in Python, Rust, or TS—contributes to the same global visibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Engineering Transparency
&lt;/h2&gt;

&lt;p&gt;Reliability in the Agentic Era is impossible without transparency. &lt;strong&gt;apcore Observability 2.0&lt;/strong&gt; bridges the gap between software engineering and AI reasoning. It gives SREs and Developers the tools they need to monitor, debug, and optimize autonomous systems with professional precision.&lt;/p&gt;




&lt;h3&gt;
  
  
  Summary of Volume II: The Engine
&lt;/h3&gt;

&lt;p&gt;We have now deconstructed the core of apcore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We looked at the &lt;strong&gt;Discovery Algorithm&lt;/strong&gt; (Directory-as-ID).&lt;/li&gt;
&lt;li&gt;We traced the &lt;strong&gt;11-step Execution Pipeline&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We explored &lt;strong&gt;Strict Schemas&lt;/strong&gt; and &lt;strong&gt;Behavioral Annotations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We secured the system with &lt;strong&gt;Pattern-Based ACL&lt;/strong&gt; and &lt;strong&gt;Approval Gates&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;And finally, we made it all visible with &lt;strong&gt;OpenTelemetry&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Now that you understand the Engine, it’s time to build. In Volume III, we’ll move to Practical Implementation, starting with the &lt;code&gt;apcore-toolkit&lt;/code&gt;: the Swiss Army Knife for module developers.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #17 of the **Building the AI-Perceivable World&lt;/em&gt;* series. Transparency is the bedrock of Trust.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Human-in-the-Loop: The Runtime Enforcement of requires_approval</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Sat, 16 May 2026 07:08:03 +0000</pubDate>
      <link>https://dev.to/tercelyi/human-in-the-loop-the-runtime-enforcement-of-requiresapproval-3m20</link>
      <guid>https://dev.to/tercelyi/human-in-the-loop-the-runtime-enforcement-of-requiresapproval-3m20</guid>
      <description>&lt;p&gt;As AI Agents gain more autonomy, a fundamental fear has taken hold in the enterprise: &lt;em&gt;"What if the Agent does something it shouldn't?"&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;We’ve all seen the warnings in system prompts: &lt;em&gt;"Please be careful when deleting data."&lt;/em&gt; But as every seasoned engineer knows, &lt;strong&gt;a prompt is not a security policy.&lt;/strong&gt; If you want to prevent an AI from accidentally triggering a production deployment or wiping a database, you need a hard, runtime "Kill Switch."&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;apcore&lt;/strong&gt; protocol, we call this the &lt;strong&gt;Approval Gate&lt;/strong&gt;. In this sixteenth article, we explore how the &lt;code&gt;requires_approval&lt;/code&gt; annotation brings "Human-in-the-Loop" (HITL) directly into the heart of the execution pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Autonomy Needs a Brake Pedal
&lt;/h2&gt;

&lt;p&gt;Autonomous Agents are designed to loop: they plan, execute, observe, and repeat. The problem arises during the "Execute" phase. If an Agent decides that the best way to "optimize disk space" is to delete your &lt;code&gt;var/log&lt;/code&gt; directory, it will try to do so instantly.&lt;/p&gt;

&lt;p&gt;Traditional systems try to solve this with prompt engineering or post-execution auditing. &lt;strong&gt;Both are too slow.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;apcore&lt;/strong&gt;, we implement HITL at &lt;strong&gt;Step 5&lt;/strong&gt; of our 11-step pipeline. Before the validation runs, and long before your code is executed, the &lt;code&gt;Executor&lt;/code&gt; checks for the "Approval" flag.&lt;/p&gt;




&lt;h2&gt;
  
  
  The &lt;code&gt;requires_approval&lt;/code&gt; Annotation
&lt;/h2&gt;

&lt;p&gt;Marking a module as "High Stakes" is a single-line operation in apcore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ops.deploy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy to production.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@annotations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requires_approval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destructive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Logic...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this module is invoked, the apcore Executor doesn't run the code. Instead, it halts and triggers an &lt;strong&gt;ApprovalHandler&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pluggable Approval Handlers
&lt;/h2&gt;

&lt;p&gt;The beauty of apcore is that the "Human" doesn't have to be in any specific UI. Because apcore is a protocol, the approval request is projected onto whichever &lt;strong&gt;Surface&lt;/strong&gt; the caller is using:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The CLI Surface
&lt;/h3&gt;

&lt;p&gt;If you are running a module via &lt;code&gt;apcore-cli&lt;/code&gt;, the terminal will pause and ask:&lt;br&gt;
&lt;code&gt;Module 'ops.deploy' requires approval. Proceed? [y/N]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The MCP Surface
&lt;/h3&gt;

&lt;p&gt;If Claude is calling your tool via MCP, apcore-mcp uses the protocol's &lt;strong&gt;Elicitation&lt;/strong&gt; feature. A confirmation dialog appears directly in the Claude or Cursor interface, allowing the user to click "Approve" before the AI continues.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Agent-to-Agent (A2A) Surface
&lt;/h3&gt;

&lt;p&gt;In an A2A workflow, the "Provider Agent" sends an &lt;code&gt;input-required&lt;/code&gt; status back to the "Consumer Agent." The Consumer Agent then knows it must pause its task and ask its own human user for permission.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bypassing Approval: The Trusted Context
&lt;/h2&gt;

&lt;p&gt;There are scenarios where you &lt;em&gt;want&lt;/em&gt; to bypass the gate—for example, during automated CI/CD runs or when a highly trusted system administrator is using the CLI.&lt;/p&gt;

&lt;p&gt;apcore allows this via the &lt;strong&gt;Trusted Context&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt;: The &lt;code&gt;-y&lt;/code&gt; or &lt;code&gt;--yes&lt;/code&gt; flag tells the handler to auto-approve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt;: You can configure your registry to auto-approve calls from specific &lt;code&gt;identity.types&lt;/code&gt; (e.g., &lt;code&gt;"system"&lt;/code&gt;) while requiring them for &lt;code&gt;"user"&lt;/code&gt; or &lt;code&gt;"agent"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: Bridging Fear and Autonomy
&lt;/h2&gt;

&lt;p&gt;The path to production AI is not about making models "smarter"—it's about making our infrastructure &lt;strong&gt;safer&lt;/strong&gt;. By enforcing "Human-in-the-Loop" at the protocol level, &lt;strong&gt;apcore&lt;/strong&gt; gives enterprises the confidence to deploy autonomous Agents, knowing that the "Brake Pedal" is always under human control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we wrap up Volume II with "Observability 2.0: Tracing AI 'Thought Chains' with OpenTelemetry."&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #16 of the **Building the AI-Perceivable World&lt;/em&gt;* series. Join us in building secure and governed AI architectures.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>security</category>
    </item>
    <item>
      <title>Pattern-Based ACL: Securing the Boundaries of Agentic Autonomy</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Mon, 11 May 2026 12:29:55 +0000</pubDate>
      <link>https://dev.to/tercelyi/pattern-based-acl-securing-the-boundaries-of-agentic-autonomy-3j25</link>
      <guid>https://dev.to/tercelyi/pattern-based-acl-securing-the-boundaries-of-agentic-autonomy-3j25</guid>
      <description>&lt;p&gt;As we move toward a world of autonomous AI Agents, the "Access Control" problem undergoes a fundamental shift. In the traditional web, we worry about a human user accessing another user's data. In the Agentic era, we have a new nightmare: &lt;strong&gt;Agent Hallucinations.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine an Agent that, while trying to solve a complex task, "hallucinates" a call to your &lt;code&gt;executor.database.wipe&lt;/code&gt; module because it sounded like a good way to "clear the state." Without a robust security layer, the Agent might actually have the permission to do it.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;apcore&lt;/strong&gt;, we believe that security must be part of the protocol, not a secondary prompt. In this fifteenth article, we explore the &lt;strong&gt;Pattern-Based ACL&lt;/strong&gt; system that secures the boundaries of AI autonomy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Failure of Endpoint-Based Security
&lt;/h2&gt;

&lt;p&gt;Traditional API security often relies on a flat list of allowed endpoints for a specific API key. This approach breaks down when you have hundreds of "Skills" (modules) that Agents need to discover and invoke dynamically. Managing a static list for every possible Agent role becomes an administrative nightmare.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;apcore&lt;/strong&gt; takes a different path: &lt;strong&gt;Pattern-Based Access Control.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  High-Performance Pattern Matching
&lt;/h2&gt;

&lt;p&gt;The apcore ACL (Access Control List) uses a first-match-wins evaluation logic based on caller and target patterns. This allows you to define broad, high-level security policies that scale automatically as you add new modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of Namespaces
&lt;/h3&gt;

&lt;p&gt;Because apcore uses &lt;strong&gt;Directory-as-ID&lt;/strong&gt;, your modules are naturally organized into namespaces. You can write rules like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;allow callers=["api.*"] targets=["orchestrator.*"]&lt;/code&gt;: Front-facing APIs can only talk to the reasoning layer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow callers=["orchestrator.*"] targets=["executor.*"]&lt;/code&gt;: The brain can trigger execution.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;deny callers=["*"] targets=["admin.sensitive.*"]&lt;/code&gt;: Nobody calls admin tools unless explicitly allowed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Special Identifiers: @external and &lt;a class="mentioned-user" href="https://dev.to/system"&gt;@system&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;To make security management easier, the apcore protocol defines two "Magic Callers":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;@external&lt;/code&gt;&lt;/strong&gt;: Represents any call coming from outside the registry (e.g., a CLI tool, a Web request, or an MCP client).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;@system&lt;/code&gt;&lt;/strong&gt;: Represents internal framework tasks, such as periodic health checks or background cleanup.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By separating these, you can implement a &lt;strong&gt;Zero-Trust AI Policy&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Only allow external callers to see 'common' tools&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;callers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@external"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;common.*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;allow&lt;/span&gt;

&lt;span class="c1"&gt;# Only internal orchestrators can touch the 'executor' namespace&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;callers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orchestrator.*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;executor.*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;allow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conditional Rules: Identity &amp;amp; Depth
&lt;/h2&gt;

&lt;p&gt;Sometimes, a simple "Allow/Deny" based on the module ID isn't enough. apcore supports &lt;strong&gt;Conditional ACL Rules&lt;/strong&gt; that look at the current &lt;code&gt;Context&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role-Based&lt;/strong&gt;: Match based on the caller's &lt;code&gt;identity.roles&lt;/code&gt; (e.g., &lt;code&gt;"finance_admin"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity Type&lt;/strong&gt;: Differentiate between a &lt;code&gt;user&lt;/code&gt;, an &lt;code&gt;agent&lt;/code&gt;, and a &lt;code&gt;system&lt;/code&gt; caller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Call Depth&lt;/strong&gt;: Prevent recursive hallucination attacks by stopping any execution chain that exceeds a certain depth (e.g., &lt;code&gt;max_call_depth: 5&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Audit Trails: Prove Your Autonomy
&lt;/h2&gt;

&lt;p&gt;Security without auditability is useless in an enterprise. Every time the apcore ACL system makes a decision, it generates a structured &lt;strong&gt;AuditEntry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This entry includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/strong&gt;: Exactly when the check happened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;decision&lt;/code&gt;&lt;/strong&gt;: Allow or Deny.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;matched_rule&lt;/code&gt;&lt;/strong&gt;: Which specific line in your YAML policy triggered the decision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;trace_id&lt;/code&gt;&lt;/strong&gt;: Links the security decision to the specific AI "Thought Chain."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that if an Agent is denied access to a tool, your security team can see exactly &lt;em&gt;why&lt;/em&gt; and &lt;em&gt;who&lt;/em&gt; was calling.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: A Secure Sandbox for Agents
&lt;/h2&gt;

&lt;p&gt;Pattern-Based ACL turns apcore into more than just a library—it turns it into a &lt;strong&gt;Secure Runtime&lt;/strong&gt; for AI. By enforcing boundaries at the protocol level, we allow Agents to be autonomous without being dangerous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll look at the "Ultimate Safety Valve": Human-in-the-Loop and the runtime enforcement of &lt;code&gt;requires_approval&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #15 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Join us in building secure AI architectures.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>Context Object: State Management and Trace Propagation</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Tue, 05 May 2026 02:55:41 +0000</pubDate>
      <link>https://dev.to/tercelyi/context-object-state-management-and-trace-propagation-1dhb</link>
      <guid>https://dev.to/tercelyi/context-object-state-management-and-trace-propagation-1dhb</guid>
      <description>&lt;p&gt;In our previous articles, we explored the 11-step execution pipeline that secures every AI call. At the center of that pipeline sits a silent but essential hero: the &lt;strong&gt;Context Object&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the pipeline is the "Heart" of apcore, the Context is its &lt;strong&gt;"Nervous System."&lt;/strong&gt; It is the object that carries state, identity, and tracing information from the first entry point down to the deepest nested module call. In this fourteenth article, we go deep into how apcore manages the "Short-Term Memory" of an Agentic system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge of Statelessness
&lt;/h2&gt;

&lt;p&gt;AI Agents often perform complex, multi-step tasks. An Agent might first call a &lt;code&gt;search&lt;/code&gt; module, then a &lt;code&gt;summarize&lt;/code&gt; module, and finally a &lt;code&gt;file.write&lt;/code&gt; module. &lt;/p&gt;

&lt;p&gt;In a traditional stateless architecture, these calls are isolated. The &lt;code&gt;file.write&lt;/code&gt; module doesn't know that it was triggered by a specific search result or that it’s part of a high-priority audit task. This lack of context makes debugging impossible and security fragile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;apcore&lt;/strong&gt; solves this by injecting a reference-shared &lt;code&gt;Context&lt;/code&gt; object into every execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Anatomy of the apcore Context
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Context&lt;/code&gt; class (defined in &lt;code&gt;apcore.context&lt;/code&gt;) is a rich container that provides four critical capabilities:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. W3C-Compatible Tracing (&lt;code&gt;trace_id&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Every call chain in apcore is assigned a unique &lt;code&gt;trace_id&lt;/code&gt; (a UUID v4 by default). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;W3C Compatibility&lt;/strong&gt;: apcore can ingest &lt;code&gt;TraceParent&lt;/code&gt; headers from external systems (like a web gateway), ensuring that your AI's "Thought Chain" is connected to the original user request in your distributed logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trace Propagation&lt;/strong&gt;: When Module A calls Module B, the &lt;code&gt;trace_id&lt;/code&gt; is automatically carried forward.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The Audit Trail (&lt;code&gt;call_chain&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The Context maintains a &lt;code&gt;call_chain&lt;/code&gt; list that grows as the execution moves deeper.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example&lt;/em&gt;: &lt;code&gt;["api.v1.user", "orchestrator.order", "executor.payment"]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;This provides a real-time "Stack Trace" for AI Agents, allowing the system to detect circular calls and enforce recursion limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Identity &amp;amp; Permissions (&lt;code&gt;identity&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;identity&lt;/code&gt; property carries the authenticated caller’s details, including their &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt; (user/agent/system), and &lt;code&gt;roles&lt;/code&gt;. This is the data that the &lt;strong&gt;ACL system&lt;/strong&gt; uses to decide if a call should be allowed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Shared Memory (&lt;code&gt;data&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Perhaps the most powerful feature is &lt;code&gt;context.data&lt;/code&gt;—a dictionary that is &lt;strong&gt;reference-shared&lt;/strong&gt; across the entire call chain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unlike module inputs (which are local), &lt;code&gt;context.data&lt;/code&gt; allows modules to pass artifacts "sideways." &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Real-world use case&lt;/em&gt;: A middleware can calculate a session token once and store it in &lt;code&gt;context.data&lt;/code&gt;, making it available to all subsequent modules in that chain without cluttering their input parameters.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Implementation: The Child Context Pattern
&lt;/h2&gt;

&lt;p&gt;How does apcore ensure that the context stays accurate during nested calls? It uses the &lt;strong&gt;Child Context Pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you call another module via &lt;code&gt;context.executor.call()&lt;/code&gt;, the system doesn't just pass the parent context. It creates a &lt;code&gt;.child()&lt;/code&gt; context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Inside Module A
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputs&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="c1"&gt;# This creates a child context with:
&lt;/span&gt;    &lt;span class="c1"&gt;# 1. Same trace_id
&lt;/span&gt;    &lt;span class="c1"&gt;# 2. Updated caller_id (now Module A)
&lt;/span&gt;    &lt;span class="c1"&gt;# 3. Appended call_chain
&lt;/span&gt;    &lt;span class="c1"&gt;# 4. SHARED data dictionary
&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;module_b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputs&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that the &lt;code&gt;caller_id&lt;/code&gt; always points to the immediate parent, while the &lt;code&gt;trace_id&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; remain consistent across the entire journey.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Turning Isolation into Collaboration
&lt;/h2&gt;

&lt;p&gt;By standardizing state management through the &lt;strong&gt;Context Object&lt;/strong&gt;, apcore turns a collection of isolated functions into a coherent, intelligent workforce. It provides the "Short-Term Memory" that AI Agents need to perform complex, traceable, and secure operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll see how this identity data is used to enforce security in "Pattern-Based ACL: Securing the Boundaries of Agentic Autonomy."&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #14 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Identity and State are the foundation of Trust.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Behavioral Annotations: Why readonly and destructive guide LLM Planning</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Mon, 04 May 2026 01:07:46 +0000</pubDate>
      <link>https://dev.to/tercelyi/behavioral-annotations-why-readonly-and-destructive-guide-llm-planning-37nk</link>
      <guid>https://dev.to/tercelyi/behavioral-annotations-why-readonly-and-destructive-guide-llm-planning-37nk</guid>
      <description>&lt;p&gt;In our previous article, we discussed how &lt;strong&gt;Schemas&lt;/strong&gt; act as the "Postman" of the apcore ecosystem—ensuring that data is delivered in the correct format. But knowing &lt;em&gt;how&lt;/em&gt; to deliver a message isn't enough for an autonomous Agent. The Agent also needs to know the &lt;strong&gt;Impact&lt;/strong&gt; of the delivery.&lt;/p&gt;

&lt;p&gt;Imagine an Agent tasked with "fixing a data inconsistency." It finds two modules: &lt;code&gt;common.user.sync&lt;/code&gt; and &lt;code&gt;executor.user.reset&lt;/code&gt;. Without behavioral context, the Agent might pick the &lt;code&gt;reset&lt;/code&gt; module because it sounds more "thorough," not realizing it will delete the entire user profile.&lt;/p&gt;

&lt;p&gt;This is why &lt;strong&gt;Behavioral Annotations&lt;/strong&gt; are a core technical pillar of the apcore protocol. In this thirteenth article, we explore how these simple boolean flags act as "Cognitive Stop Signs" for AI planners.&lt;/p&gt;




&lt;h2&gt;
  
  
  Syntax vs. Semantics
&lt;/h2&gt;

&lt;p&gt;A schema handles the &lt;strong&gt;Syntax&lt;/strong&gt; (Is it a string? Is it required?). Annotations handle the &lt;strong&gt;Semantics&lt;/strong&gt; (Is it safe? Is it permanent?).&lt;/p&gt;

&lt;p&gt;By providing this semantic layer, we move from "Code-Calling" to "Skill-Perceiving." The AI Agent no longer treats your modules as black boxes; it perceives their personality.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 12 apcore Behavioral Annotations
&lt;/h2&gt;

&lt;p&gt;The apcore protocol defines a set of standardized annotations that provide the semantic "Personality" for your code. These are grouped into &lt;strong&gt;Safety&lt;/strong&gt;, &lt;strong&gt;Execution&lt;/strong&gt;, and &lt;strong&gt;Governance&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  Safety &amp;amp; Impact
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;readonly&lt;/code&gt;&lt;/strong&gt;: No side effects. Safe for discovery and infinite retries.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;destructive&lt;/code&gt;&lt;/strong&gt;: Data will be permanently modified or deleted.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;idempotent&lt;/code&gt;&lt;/strong&gt;: Multiple calls with same input have same effect as one.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;pure&lt;/code&gt;&lt;/strong&gt;: Output depends only on input; no external state dependency.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Execution &amp;amp; Performance
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;streaming&lt;/code&gt;&lt;/strong&gt;: The module returns a stream of events/chunks rather than a single block.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;cacheable&lt;/code&gt;&lt;/strong&gt;: Results can be stored for future use.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;cache_ttl&lt;/code&gt;&lt;/strong&gt;: How long (in seconds) the result remains valid.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;paginated&lt;/code&gt;&lt;/strong&gt;: The result is part of a series; requires a cursor/token to continue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Governance &amp;amp; Security
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;requires_approval&lt;/code&gt;&lt;/strong&gt;: Pauses execution for a human "Yes" (HITL).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;open_world&lt;/code&gt;&lt;/strong&gt;: Interacts with non-deterministic external systems (e.g., Web, Email).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal&lt;/code&gt;&lt;/strong&gt;: Hidden from standard discovery; used for system-to-system calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;extra&lt;/code&gt;&lt;/strong&gt;: A catch-all map for surface-specific or custom behavioral hints.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Guiding the Agent's Brain
&lt;/h2&gt;

&lt;p&gt;How does an LLM actually use these flags? It’s all about the &lt;strong&gt;Planning Phase&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a sophisticated Agent (like those powered by Claude 3.5 or GPT-4o) receives a list of tools, it builds a "Plan of Action." &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it sees a module marked as &lt;code&gt;destructive: true&lt;/code&gt;, the model's internal safety alignment often triggers a "Caution" state. &lt;/li&gt;
&lt;li&gt;It might decide to check for a "Dry Run" flag first.&lt;/li&gt;
&lt;li&gt;Or, it might generate a response to the user: &lt;em&gt;"I have found a way to fix this, but it requires a destructive database operation. Do you want me to proceed?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without these annotations, the Agent is "blind." It executes the plan first and discovers the consequences later—which is usually too late.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Case: &lt;code&gt;apexe&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The power of automated annotations is a highlight of &lt;strong&gt;apexe&lt;/strong&gt;, our tool for wrapping existing CLIs. When you run &lt;code&gt;apexe scan git&lt;/code&gt;, it doesn't just extract the parameters. It uses pattern matching to classify the commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git status&lt;/code&gt; and &lt;code&gt;git log&lt;/code&gt; are automatically marked as &lt;code&gt;readonly: true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push --force&lt;/code&gt; and &lt;code&gt;git reset --hard&lt;/code&gt; are marked as &lt;code&gt;destructive: true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By simply scanning your help text, apexe creates a "Safe Workspace" where an AI Agent can browse your repository without accidentally blowing up your production branch.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Professional Skills, Not Just Functions
&lt;/h2&gt;

&lt;p&gt;Engineering for AI means engineering for &lt;strong&gt;Cognitive Safety&lt;/strong&gt;. By using &lt;strong&gt;apcore Behavioral Annotations&lt;/strong&gt;, you turn your raw functions into "Professional Skills." You give the AI the wisdom it needs to plan responsibly, reducing token waste and preventing Agentic disasters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll dive into the AI’s "Short-Term Memory": The Context Object and how it manages traces and state across complex module chains.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #13 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Safety is a protocol-level primitive.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>Strict Schema Enforcement: The Bedrock of AI Reliability</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Fri, 01 May 2026 11:21:24 +0000</pubDate>
      <link>https://dev.to/tercelyi/strict-schema-enforcement-the-bedrock-of-ai-reliability-1kdb</link>
      <guid>https://dev.to/tercelyi/strict-schema-enforcement-the-bedrock-of-ai-reliability-1kdb</guid>
      <description>&lt;p&gt;In the early days of AI tool-calling, we relied on a wing and a prayer. We gave an LLM a docstring and hoped it would guess the right types. If the Agent sent a string instead of a UUID, or a float instead of an integer, the system would crash, returning a generic 500 error that left the Agent stuck in an infinite retry loop.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Parameter Hallucination&lt;/strong&gt;, and it is the single biggest obstacle to building production-grade AI systems.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;apcore&lt;/strong&gt;, we solve this by making &lt;strong&gt;Strict Schema Enforcement&lt;/strong&gt; a protocol-level requirement. In this twelfth article of our series, we dive into why data contracts are the only way to build a reliable Cognitive Interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why JSON Schema Draft 2020-12?
&lt;/h2&gt;

&lt;p&gt;When we designed apcore, we didn't want to invent a new schema language. We chose &lt;strong&gt;JSON Schema Draft 2020-12&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why? Because it is the "Universal Vocabulary" of the modern web. It is language-agnostic, widely supported, and incredibly expressive. By standardizing on this draft, we ensure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Cross-Language Consistency&lt;/strong&gt;: A schema defined in your Python backend is validated with the exact same logic in your Rust microservice.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Rich Polymorphism&lt;/strong&gt;: We can use &lt;code&gt;oneOf&lt;/code&gt; and &lt;code&gt;anyOf&lt;/code&gt; to define complex inputs that an LLM can actually reason about.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Self-Contained Definitions&lt;/strong&gt;: With &lt;code&gt;$ref&lt;/code&gt; resolution, apcore ensures that the LLM always receives a single, dereferenced schema, removing the need for the model to "fetch" external definitions.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Mandatory Perception
&lt;/h2&gt;

&lt;p&gt;In apcore, a module &lt;strong&gt;cannot&lt;/strong&gt; exist without an &lt;code&gt;input_schema&lt;/code&gt;. This isn't a suggestion; it’s an enforcement in the &lt;code&gt;Registry&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;By forcing developers to define the input contract upfront, we create a &lt;strong&gt;Safe Zone&lt;/strong&gt; for the AI Agent. The Agent no longer has to "guess" if a field is required or what its regex pattern is. It "perceives" the contract directly from the module metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Strict" Mode
&lt;/h3&gt;

&lt;p&gt;apcore encourages the use of &lt;code&gt;additionalProperties: false&lt;/code&gt;. This tells the LLM: &lt;em&gt;"Do not hallucinate extra parameters. Only send exactly what is defined here."&lt;/em&gt; This small architectural choice significantly reduces token noise and increases the success rate of complex tool calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Execution Pipeline: Step 6
&lt;/h2&gt;

&lt;p&gt;The power of strict schemas is best seen in &lt;strong&gt;Step 6&lt;/strong&gt; of the apcore Execution Pipeline: &lt;strong&gt;Input Validation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before your business logic ever touches the data, the apcore Executor runs a full schema validation. If the LLM makes a mistake—sending a string instead of a number—the Executor halts execution immediately.&lt;/p&gt;

&lt;p&gt;But here is the clever part: instead of a stack trace, it returns a &lt;strong&gt;Structured Validation Error&lt;/strong&gt;.&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SCHEMA_VALIDATION_ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Input validation failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"details"&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="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not a valid UUID"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ai_guidance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The user_id must be a UUID format. Please re-check the user record and try again."&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;p&gt;This error informs the Agent &lt;em&gt;exactly&lt;/em&gt; what went wrong, allowing it to self-correct and retry without human intervention.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Engineering the Contract
&lt;/h2&gt;

&lt;p&gt;If you want reliable AI Agents, you must stop "Prompting" your tools and start &lt;strong&gt;Engineering your Contracts&lt;/strong&gt;. Strict schema enforcement is not about adding friction; it’s about providing the semantic clarity that AI needs to act autonomously and safely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll move from syntax to semantics: Behavioral Annotations. We’ll look at how 'readonly' and 'destructive' guide the LLM's planning process.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #12 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Reliability is a design choice.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
    </item>
    <item>
      <title>The 11-Step Execution Pipeline: A Secured Journey for Every Call</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 30 Apr 2026 08:28:08 +0000</pubDate>
      <link>https://dev.to/tercelyi/the-11-step-execution-pipeline-a-secured-journey-for-every-call-2k25</link>
      <guid>https://dev.to/tercelyi/the-11-step-execution-pipeline-a-secured-journey-for-every-call-2k25</guid>
      <description>&lt;p&gt;When an AI Agent calls a tool, we often think of it as a simple "request-response" event. But in the &lt;strong&gt;apcore&lt;/strong&gt; world, every call is a mission-critical journey. Whether you are invoking a Python module or a Rust microservice, that call passes through a rigorous, &lt;strong&gt;11-step Execution Pipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This pipeline is the "Heart" of the apcore engine. It ensures that every interaction is validated, authorized, and perfectly traceable. In this eleventh article, we’re going to open the hood and see exactly how apcore ensures reliability at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  The apcore Execution Pipeline
&lt;/h2&gt;

&lt;p&gt;Every call through the &lt;code&gt;Executor.call()&lt;/code&gt; method follows this deterministic path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Context Processing&lt;/strong&gt;: Create or update the &lt;code&gt;Context&lt;/code&gt;. Generate a &lt;code&gt;trace_id&lt;/code&gt; (if one doesn't exist) and update the &lt;code&gt;caller_id&lt;/code&gt; and &lt;code&gt;call_chain&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Safety Checks&lt;/strong&gt;: Verify the maximum call depth (default 8) to prevent circular calls from crashing the system.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Module Lookup&lt;/strong&gt;: Find the target module in the &lt;strong&gt;Registry&lt;/strong&gt; using its Canonical ID.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;ACL Check&lt;/strong&gt;: Perform the first-match-wins &lt;strong&gt;Access Control List&lt;/strong&gt; check. Does the caller have permission to invoke the target?&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Approval Gate&lt;/strong&gt;: Check if the module is marked as &lt;code&gt;requires_approval&lt;/code&gt;. If so, pause execution and wait for a human or automated response.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Input Validation&lt;/strong&gt;: Validate the incoming &lt;code&gt;dict&lt;/code&gt; against the module's &lt;code&gt;input_schema&lt;/code&gt; (JSON Schema Draft 2020-12).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Middleware: &lt;code&gt;before()&lt;/code&gt;&lt;/strong&gt;: Execute all registered middleware's &lt;code&gt;before()&lt;/code&gt; hooks in sequence (e.g., logging, metrics, caching).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Module Execution&lt;/strong&gt;: The actual &lt;code&gt;module.execute(inputs, context)&lt;/code&gt; call. This is where your business logic runs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Output Validation&lt;/strong&gt;: Validate the returned result against the &lt;code&gt;output_schema&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware: &lt;code&gt;after()&lt;/code&gt;&lt;/strong&gt;: Execute all middleware's &lt;code&gt;after()&lt;/code&gt; hooks in reverse order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return Result&lt;/strong&gt;: Hand the validated and enriched result back to the caller.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why 11 Steps? (The Real-World Case of &lt;code&gt;apflow&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;You might wonder: "Isn't 11 steps overkill?"&lt;/p&gt;

&lt;p&gt;The answer lies in products like &lt;strong&gt;apflow&lt;/strong&gt;, our distributed task orchestration framework. In a cluster environment, where tasks are moving between nodes, you cannot afford "fuzzy" execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traceability at Scale
&lt;/h3&gt;

&lt;p&gt;By enforcing &lt;strong&gt;Step 1 (Context Processing)&lt;/strong&gt;, apflow ensures that a task triggered by a user's web request keeps the same &lt;code&gt;trace_id&lt;/code&gt; even as it moves from the Leader node to a remote Worker node. This is the only way to debug a "hallucinating" Agent in a distributed environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Governance in Autonomy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 5 (Approval Gate)&lt;/strong&gt; is critical for apflow's A2A (Agent-to-Agent) support. If an "Analyst Agent" wants to call a "Payment Agent," apflow uses this step to pause the workflow and wait for a human "Manager" to click "Approve" in the dashboard. Without this step, the system would lack a "Safety Valve."&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Without Borders
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 4 (ACL Check)&lt;/strong&gt; allows apflow to enforce "Role-Based" security. A &lt;code&gt;RestExecutor&lt;/code&gt; node might only be allowed to call &lt;code&gt;common.*&lt;/code&gt; modules, while a &lt;code&gt;SystemInfoExecutor&lt;/code&gt; node might have broader access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Rigor: Middleware &amp;amp; Error Guidance
&lt;/h2&gt;

&lt;p&gt;The pipeline isn't just a set of checks; it’s an extension point. In &lt;strong&gt;Step 7 and 10&lt;/strong&gt;, you can inject custom logic via Middleware. &lt;/p&gt;

&lt;p&gt;And if any step fails? apcore doesn't just throw a traceback. It provides &lt;strong&gt;Self-Healing Guidance&lt;/strong&gt;. If validation fails at &lt;strong&gt;Step 6&lt;/strong&gt;, the pipeline returns an error with &lt;code&gt;ai_guidance&lt;/code&gt;, telling the Agent exactly how to fix the input and retry.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: The Backbone of Trust
&lt;/h2&gt;

&lt;p&gt;Reliability in AI systems is not an accident; it is a structural property of the execution pipeline. By enforcing an 11-step journey, &lt;strong&gt;apcore&lt;/strong&gt; ensures that every AI call is as secure and predictable as a high-performance database transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll dive into the technical details of Article #12: Strict Schema Enforcement: The Bedrock of AI Reliability.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #11 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Join us as we build the engine of the Agentic era.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>The Execution Pipeline: A Secured Journey for Every Call</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 23 Apr 2026 23:42:40 +0000</pubDate>
      <link>https://dev.to/tercelyi/the-11-step-execution-pipeline-a-secured-journey-for-every-call-50lp</link>
      <guid>https://dev.to/tercelyi/the-11-step-execution-pipeline-a-secured-journey-for-every-call-50lp</guid>
      <description>&lt;p&gt;When an AI Agent calls a tool, we often think of it as a simple "request-response" event. But in the &lt;strong&gt;apcore&lt;/strong&gt; world, every call is a mission-critical journey. Whether you are invoking a Python module or a Rust microservice, that call passes through a rigorous, &lt;strong&gt;11-step Execution Pipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This pipeline is the "Heart" of the apcore engine. It ensures that every interaction is validated, authorized, and perfectly traceable. In this eleventh article, we’re going to open the hood and see exactly how apcore ensures reliability at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  The apcore Execution Pipeline
&lt;/h2&gt;

&lt;p&gt;Every call through the &lt;code&gt;Executor.call()&lt;/code&gt; method follows this deterministic path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Context Processing&lt;/strong&gt;: Create or update the &lt;code&gt;Context&lt;/code&gt;. Generate a &lt;code&gt;trace_id&lt;/code&gt; (if one doesn't exist) and update the &lt;code&gt;caller_id&lt;/code&gt; and &lt;code&gt;call_chain&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Safety Checks&lt;/strong&gt;: Verify the maximum call depth (default 8) to prevent circular calls from crashing the system.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Module Lookup&lt;/strong&gt;: Find the target module in the &lt;strong&gt;Registry&lt;/strong&gt; using its Canonical ID.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;ACL Check&lt;/strong&gt;: Perform the first-match-wins &lt;strong&gt;Access Control List&lt;/strong&gt; check. Does the caller have permission to invoke the target?&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Approval Gate&lt;/strong&gt;: Check if the module is marked as &lt;code&gt;requires_approval&lt;/code&gt;. If so, pause execution and wait for a human or automated response.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Input Validation&lt;/strong&gt;: Validate the incoming &lt;code&gt;dict&lt;/code&gt; against the module's &lt;code&gt;input_schema&lt;/code&gt; (JSON Schema Draft 2020-12).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Middleware: &lt;code&gt;before()&lt;/code&gt;&lt;/strong&gt;: Execute all registered middleware's &lt;code&gt;before()&lt;/code&gt; hooks in sequence (e.g., logging, metrics, caching).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Module Execution&lt;/strong&gt;: The actual &lt;code&gt;module.execute(inputs, context)&lt;/code&gt; call. This is where your business logic runs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Output Validation&lt;/strong&gt;: Validate the returned result against the &lt;code&gt;output_schema&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware: &lt;code&gt;after()&lt;/code&gt;&lt;/strong&gt;: Execute all middleware's &lt;code&gt;after()&lt;/code&gt; hooks in reverse order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return Result&lt;/strong&gt;: Hand the validated and enriched result back to the caller.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why 11 Steps? (The Real-World Case of &lt;code&gt;apflow&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;You might wonder: "Isn't 11 steps overkill?"&lt;/p&gt;

&lt;p&gt;The answer lies in products like &lt;strong&gt;apflow&lt;/strong&gt;, our distributed task orchestration framework. In a cluster environment, where tasks are moving between nodes, you cannot afford "fuzzy" execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traceability at Scale
&lt;/h3&gt;

&lt;p&gt;By enforcing &lt;strong&gt;Step 1 (Context Processing)&lt;/strong&gt;, apflow ensures that a task triggered by a user's web request keeps the same &lt;code&gt;trace_id&lt;/code&gt; even as it moves from the Leader node to a remote Worker node. This is the only way to debug a "hallucinating" Agent in a distributed environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Governance in Autonomy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 5 (Approval Gate)&lt;/strong&gt; is critical for apflow's A2A (Agent-to-Agent) support. If an "Analyst Agent" wants to call a "Payment Agent," apflow uses this step to pause the workflow and wait for a human "Manager" to click "Approve" in the dashboard. Without this step, the system would lack a "Safety Valve."&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Without Borders
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 4 (ACL Check)&lt;/strong&gt; allows apflow to enforce "Role-Based" security. A &lt;code&gt;RestExecutor&lt;/code&gt; node might only be allowed to call &lt;code&gt;common.*&lt;/code&gt; modules, while a &lt;code&gt;SystemInfoExecutor&lt;/code&gt; node might have broader access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Rigor: Middleware &amp;amp; Error Guidance
&lt;/h2&gt;

&lt;p&gt;The pipeline isn't just a set of checks; it’s an extension point. In &lt;strong&gt;Step 7 and 10&lt;/strong&gt;, you can inject custom logic via Middleware. &lt;/p&gt;

&lt;p&gt;And if any step fails? apcore doesn't just throw a traceback. It provides &lt;strong&gt;Self-Healing Guidance&lt;/strong&gt;. If validation fails at &lt;strong&gt;Step 6&lt;/strong&gt;, the pipeline returns an error with &lt;code&gt;ai_guidance&lt;/code&gt;, telling the Agent exactly how to fix the input and retry.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: The Backbone of Trust
&lt;/h2&gt;

&lt;p&gt;Reliability in AI systems is not an accident; it is a structural property of the execution pipeline. By enforcing an 11-step journey, &lt;strong&gt;apcore&lt;/strong&gt; ensures that every AI call is as secure and predictable as a high-performance database transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next, we’ll dive into the technical details of Article #12: Strict Schema Enforcement: The Bedrock of AI Reliability.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #11 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Join us as we build the engine of the Agentic era.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>Directory-as-ID: Scaling Module Discovery Without Configuration</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 23 Apr 2026 10:42:20 +0000</pubDate>
      <link>https://dev.to/tercelyi/directory-as-id-scaling-module-discovery-without-configuration-492p</link>
      <guid>https://dev.to/tercelyi/directory-as-id-scaling-module-discovery-without-configuration-492p</guid>
      <description>&lt;p&gt;In the previous volume, we explored the vision of an "AI-Perceivable" world. Now, it’s time to go under the hood. The first technical pillar of the &lt;strong&gt;apcore&lt;/strong&gt; protocol is a deceptively simple idea: &lt;strong&gt;Directory-as-ID&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a traditional microservices or modular architecture, you often have a central registry, a massive YAML configuration file, or a complex dependency injection container. As your system grows from 10 modules to 1,000, this central "phonebook" becomes a bottleneck. It’s the source of merge conflicts, naming collisions, and "Scaling Rot."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;apcore&lt;/strong&gt; solves this by making the file system the source of truth. In this tenth article, we’ll look at the algorithm behind Directory-as-ID and why it’s essential for scaling AI-ready systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Algorithm: From Path to Canonical ID
&lt;/h2&gt;

&lt;p&gt;The principle is straightforward: &lt;strong&gt;The relative path of a module file is its unique identity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have a module root directory (e.g., &lt;code&gt;extensions/&lt;/code&gt;), apcore scans the files and applies a deterministic mapping:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Remove the Root&lt;/strong&gt;: &lt;code&gt;extensions/executor/email/send.py&lt;/code&gt; -&amp;gt; &lt;code&gt;executor/email/send.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Remove Extension&lt;/strong&gt;: &lt;code&gt;executor/email/send.py&lt;/code&gt; -&amp;gt; &lt;code&gt;executor/email/send&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Normalize Separators&lt;/strong&gt;: &lt;code&gt;executor/email/send&lt;/code&gt; -&amp;gt; &lt;code&gt;executor.email.send&lt;/code&gt; (The Canonical ID)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why this matters for AI:
&lt;/h3&gt;

&lt;p&gt;AI Agents are highly sensitive to names. By using a hierarchical, directory-based naming convention, you naturally create &lt;strong&gt;Namespaces&lt;/strong&gt;. An Agent can quickly differentiate between &lt;code&gt;executor.user.delete&lt;/code&gt; and &lt;code&gt;admin.user.delete&lt;/code&gt; because the hierarchy provides the context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Case Study: Zero-Config in &lt;code&gt;apexe&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The power of Directory-as-ID is best seen in real-world products like &lt;strong&gt;apexe&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  apexe: AI-fying the CLI Universe
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;apexe&lt;/strong&gt; is a tool that scans existing CLIs (like &lt;code&gt;git&lt;/code&gt; or &lt;code&gt;docker&lt;/code&gt;) and wraps them into apcore modules. When you run &lt;code&gt;apexe scan git&lt;/code&gt;, it generates a hierarchy of modules under your &lt;code&gt;~/.apexe/modules/&lt;/code&gt; directory. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git commit&lt;/code&gt; becomes &lt;code&gt;cli.git.commit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push&lt;/code&gt; becomes &lt;code&gt;cli.git.push&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of Directory-as-ID, apexe doesn't need to manage a database of IDs. It simply writes the files to the right folders, and the apcore Registry "perceives" the entire CLI command tree instantly. This enables &lt;strong&gt;Dynamic Skill Discovery&lt;/strong&gt;: if you install a new CLI tool and scan it, your Agent can perceive it immediately without a single server restart.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Rigor: Handling Multi-Language Drift
&lt;/h2&gt;

&lt;p&gt;A core challenge of a language-agnostic standard is that different languages have different naming conventions. Python likes &lt;code&gt;snake_case&lt;/code&gt;, while TypeScript prefers &lt;code&gt;camelCase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The apcore protocol defines strict &lt;strong&gt;ID Normalization Rules&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normalization&lt;/strong&gt;: All IDs are converted to a "Canonical" form (lowercase, snake_case) for the Registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language Mapping&lt;/strong&gt;: Each SDK (Python, TS, Rust) handles the translation between the Canonical ID and the local file name (e.g., &lt;code&gt;SendEmail.ts&lt;/code&gt; maps to &lt;code&gt;send_email&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that even in a polyglot enterprise, the AI Agent sees a single, consistent address space.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Scale is a Design Constraint
&lt;/h2&gt;

&lt;p&gt;Directory-as-ID is more than a convenience; it’s a design constraint for the Agentic Era. It enables &lt;strong&gt;Zero-Config Discovery&lt;/strong&gt;, eliminates registry bottlenecks, and provides a natural namespace for AI perception.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the next article, we’ll dive into the heart of the engine: The 11-Step Execution Pipeline.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Article #10 of the **apcore: Building the AI-Perceivable World&lt;/em&gt;* series. Join us as we go deep into the protocol.*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/aiperceivable/apcore" rel="noopener noreferrer"&gt;aiperceivable/apcore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>softwareengineering</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
