<?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>Make Your Agent's Shell Governed: apexe in Practice</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Sat, 07 Nov 2026 01:40:58 +0000</pubDate>
      <link>https://dev.to/tercelyi/make-your-agents-shell-governed-apexe-in-practice-2k14</link>
      <guid>https://dev.to/tercelyi/make-your-agents-shell-governed-apexe-in-practice-2k14</guid>
      <description>&lt;p&gt;A previous post described how to give a coding agent a governed CLI workflow: initialize contracts, review policy, preview a call, then execute. That workflow works, and it has one weak joint.&lt;/p&gt;

&lt;p&gt;The workflow depends on the agent choosing to follow it. A Skill is a document. If the agent skips it, nothing in the system notices.&lt;/p&gt;

&lt;p&gt;apexe 0.10.0 closes that joint with three commands: apexe sh (and the installed apexe-sh launcher), apexe agent , and apexe hook claude. The integration now lives where the host actually decides what to run.&lt;/p&gt;

&lt;p&gt;This post takes one host from zero to verified, then shows how to widen coverage without pretending the boundary is bigger than it is.&lt;/p&gt;

&lt;p&gt;The gap, in one sentence&lt;br&gt;
Governance is only as good as the code path the command must pass through. For a terminal agent, that path is the host's shell invocation. So you either replace the shell, pre-tool every call, or leave enforcement to the model's goodwill.&lt;/p&gt;

&lt;p&gt;apexe now supports the first two.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install, initialize, review
Use a prebuilt binary or build from source; then prepare coverage:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;apexe init&lt;br&gt;
apexe list --verbose&lt;br&gt;
init acquires the configured rules source, matches installed commands and their variants, and writes bindings plus a starter ACL. Review ~/.apexe/acl.yaml before you go further: generated allow rules are suggestions, not your policy.&lt;/p&gt;

&lt;p&gt;Read the init report too. native_ready tells you which routes have reviewed native grammar. The reviewed pilot is small on purpose — BSD cat, head, and ls. If your installation reports nothing else there, that is expected, not a bug.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turn on the launcher, then read the report
apexe env --enable
source ~/.apexe/bin/apexe-activate.sh
apexe sh --check
env --enable installs the PATH shims, the activation helpers, the startup block for your shell, and the stable apexe-sh entry point. apexe-sh is what a host points at when it only accepts a shell path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;apexe sh --check is the part people skip and then regret. It reports:&lt;/p&gt;

&lt;p&gt;the real shell it will exec, and the entry point it found&lt;br&gt;
the shim manifest and ACL state — a missing ACL is a warning, because shim-routed commands would then run without access control&lt;br&gt;
the local environment policy and the dynamic-loader denylist (LD_PRELOAD, LD_LIBRARY_PATH, DYLD_*)&lt;br&gt;
verified routes and scanned routes, listed separately&lt;br&gt;
bindings that exist but were excluded from shims, each with its exclusion reason&lt;br&gt;
host snippets for OpenCode, pi, Codex, and Claude Code&lt;br&gt;
Two lines in that report decide your next step. If the ACL is missing, stop and load one. If a command you need appears under exclusions, the reason string tells you which reviewed fact is absent — coverage gaps are visible before you widen anything.&lt;/p&gt;

&lt;p&gt;For machine checks, apexe sh --check --format json gives you the same data in CI.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wire one host
Print first, write second:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;apexe agent opencode&lt;br&gt;
apexe agent --check opencode&lt;br&gt;
apexe agent opencode --write&lt;br&gt;
--write merges into existing JSON atomically, preserves other keys, and refuses a file that is not valid JSON. For OpenCode and pi it also refuses when apexe-sh is not installed. That refusal is the point: both hosts start every command through that path, so a missing launcher does not fall back to the system shell — the host simply fails to run anything, and you get an EACCES that names nothing useful.&lt;/p&gt;

&lt;p&gt;The four hosts are four different integrations. Do not assume one recipe:&lt;/p&gt;

&lt;p&gt;Host    What you configure  Thing to know&lt;br&gt;
OpenCode    shell = absolute apexe-sh path  Its shell tool invokes apexe-sh -c ""&lt;br&gt;
pi  shellPath = apexe-sh    Exports APEXE_SHELL_DEPTH=1 to nested shells&lt;br&gt;
Codex   Login-shell PATH activation Rejects apexe-sh as its shell; zsh activation now writes .zprofile too, so noninteractive login shells resolve shims&lt;br&gt;
Claude Code PreToolUse hook, or PATH at launch  Rejects apexe-sh as SHELL/CLAUDE_CODE_SHELL and falls back to /bin/zsh&lt;br&gt;
Codex deserves one extra note: apexe agent codex --write has no shell file to edit, so it runs apexe env --reload --shell zsh instead. Upgrade an existing installation the same way, then restart the host.&lt;/p&gt;

&lt;p&gt;Claude Code: hook instead of shell&lt;br&gt;
apexe hook claude&lt;br&gt;
Configure it as a PreToolUse hook matching Bash. A simple external command is rewritten to apexe sh -c '' through updatedInput; commands already routed through apexe are left alone, so the hook does not recurse.&lt;/p&gt;

&lt;p&gt;Builtins that change session state (cd, export, set, alias), pipelines, redirections, and compound commands are not rewritten — a one-shot apexe sh -c cannot preserve their semantics. Those keep relying on the installed PATH shims. If the shim manifest is missing, the hook denies the call and tells you to run apexe env --enable.&lt;/p&gt;

&lt;p&gt;apexe hook claude --persistent is the experimental answer to that limitation: it routes every Bash call through one detached governed session that preserves cwd, variables, functions, and aliases, scoped to the host session id and project directory, with an idle timeout and an explicit stop. Try it on a project you can afford to re-run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify from inside the agent
Ask the agent to run:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;command -v ls&lt;br&gt;
apexe exec -- ls -la&lt;br&gt;
command -v ls should print the shim path under ~/.apexe/bin/, and ~/.apexe/audit.jsonl should gain an execution record. If command -v still points at /bin/ls, the host is not using your launcher — check apexe agent --check  before touching anything else.&lt;/p&gt;

&lt;p&gt;This is also the honest test of "did I enforce anything": if the agent can still reach /bin/ls with PATH intact, you widened convenience, not a boundary.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Widen coverage on purpose
Your shims cover reviewed routes. Everything else has a binding but no reviewed grammar, which is most of a real machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;0.10.0 lets you admit those bindings explicitly:&lt;/p&gt;

&lt;p&gt;apexe env --enable --scanned readonly&lt;br&gt;
apexe sh --check&lt;br&gt;
A scanned route parses and validates the caller's argv against the scanned schema, then executes the original argv. It never rebuilds or reorders your command line. Every such execution is audited with tier: scanned.&lt;/p&gt;

&lt;p&gt;Three properties to keep straight:&lt;/p&gt;

&lt;p&gt;readonly admits only readonly, non-destructive, closed-world modules. all admits any current binding — use it after reading the bindings, not before.&lt;br&gt;
Schema inference is not a reviewed contract. Path-guard coverage for arguments the scanner did not type can be incomplete.&lt;br&gt;
--scanned lowers the grammar bar for declared routes; it cannot widen the set. A route an overlay left out stays out.&lt;br&gt;
Trust is now stamped per route (metadata.grammar), which changes what a partial overlay buys you. A mode: merge overlay that fully covers one route makes that route reviewed while its siblings stay closed. Before this release, a git-shaped tool needed a tool-wide authoritative overlay, which erased every subcommand — there was simply no usable path for git.&lt;/p&gt;

&lt;p&gt;Audit what your overlays left behind:&lt;/p&gt;

&lt;p&gt;apexe list --diagnostics&lt;br&gt;
You get the closed routes per overlay, and — when a policy is loaded — ACL grants that match no loaded module. The second list is usually a scan artefact, and it is the only place those dead permissions are visible without reading acl.yaml by hand.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Know exactly what you bought
Two trust decisions are baked into 0.10.0 and both are worth saying out loud.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Local execution now inherits your environment. apexe sh, PATH shims, and native apexe exec pass the caller's environment to the child so GH_TOKEN, AWS_PROFILE, KUBECONFIG, and SSH_AUTH_SOCK keep working. Only dynamic-loader variables (LD_PRELOAD, LD_LIBRARY_PATH, DYLD_*) are stripped. Captured execution — MCP, A2A, module JSON — still clears the environment and passes a small allowlist. So: a locally governed tool runs with your credentials. That is a deliberate trust decision, and it is not isolation.&lt;/p&gt;

&lt;p&gt;Approval is now answerable. A route marked requires_approval prompts on the controlling terminal and reads y/yes with a bounded wait. A non-interactive process is refused with a remedy instead of hanging. MCP keeps its client-based elicitation path; A2A approval stores remain a library integration.&lt;/p&gt;

&lt;p&gt;And the boundary itself:&lt;/p&gt;

&lt;p&gt;apexe sh --locked --allow-path /usr/bin -c 'ls'&lt;br&gt;
--locked restricts PATH to the shim directory plus explicit --allow-path entries. It reduces accidental discovery of ungoverned binaries. It is not a sandbox: absolute paths, builtins, functions, sudo, and interpreter-internal execution still work. APEXE_SHELL_LOCKED and APEXE_SHELL_ALLOW_PATH apply the same setting to apexe-sh, which forwards every argument to the real shell.&lt;/p&gt;

&lt;p&gt;apexe-sh changes command lookup order. Commands with a reviewed shim are governed; everything else is not. Pair it with the account, container, or VM boundary your workload needs, and read the threat model.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Three fixes you will feel on day one
git -v and git status -v no longer collide. The argv parser kept one flat flag-spelling map per module, so one spelling reused on both sides of a subcommand made every route of that tool fail before a single argument was read. Tool-level spellings now live in their own namespace and resolve by the side of the subcommand the token appears on. Git-shaped tools became usable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;x-apexe-exec is enforced on scanned routes. A scanned route replays the caller's argv, so a value like git -c core.pager= never reached the exec-parameter rejection and ran as a command. The check now runs on the parsed input both tiers produce — which matters precisely because the scanned tier exists.&lt;/p&gt;

&lt;p&gt;A refusal names the route you asked for. Routes are validated when selected, not before matching, so a sibling without reviewed grammar no longer fails your command, and the message says Route '' instead of blaming whichever module sorted first.&lt;/p&gt;

&lt;p&gt;There is one recovery path worth knowing if you deploy on shared machines: apexe env --enable --replace-unowned regenerates the reserved entry point and activation helpers when the ownership record is gone. Without it, a lost ~/.apexe-shims.json left the installation unrecoverable except by deleting files by hand. --reload and --disable also read that record first, so --disable now warns when a host still points at the entry point it just removed.&lt;/p&gt;

&lt;p&gt;Troubleshooting&lt;br&gt;
Symptom Likely cause&lt;br&gt;
Host cannot run any command, EACCES, nothing mentions apexe apexe-sh is not installed; run apexe env --enable, then apexe agent --check &lt;br&gt;
command -v ls shows /bin/ls Host is not using the launcher, or a login shell rebuilt PATH; use the managed startup block&lt;br&gt;
Codex runs ungoverned commands  zsh login shells read .zprofile; run apexe env --reload --shell zsh and restart&lt;br&gt;
Claude Code ignores the shell   It rejects apexe-sh as SHELL; use the hook or start it with the shim directory on PATH&lt;br&gt;
A command you need is not shimmed   apexe sh --check lists it with the exclusion reason; cover that route in an overlay or widen with --scanned readonly&lt;br&gt;
A 2.0 overlay does not validate Expected — commands[] and global_flags are a preview this build accepts; the published schema still pins 1.0/1.1&lt;br&gt;
Close&lt;br&gt;
The interesting shift is not that apexe gained three subcommands. It is that "the agent follows the policy" stopped being an assumption. Configure one host, run apexe sh --check, then try to make an ungoverned command slip through — that exercise tells you more about your setup than any feature list.&lt;/p&gt;

&lt;p&gt;apexe init&lt;br&gt;
apexe env --enable&lt;br&gt;
apexe sh --check&lt;br&gt;
apexe agent  --check&lt;br&gt;
apexe agent  --write&lt;br&gt;
Repository: github.com/aiperceivable/apexe · Apache-2.0 · Shell integration guide · Threat model&lt;/p&gt;

&lt;p&gt;Which host are you wiring up first — and which command did you decide to leave ungoverned on purpose?&lt;/p&gt;

</description>
      <category>cli</category>
      <category>agents</category>
      <category>governance</category>
    </item>
    <item>
      <title>Demystifying the MCP Protocol for Open Source AI</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Fri, 06 Nov 2026 01:44:56 +0000</pubDate>
      <link>https://dev.to/tercelyi/demystifying-the-mcp-protocol-for-open-source-ai-39da</link>
      <guid>https://dev.to/tercelyi/demystifying-the-mcp-protocol-for-open-source-ai-39da</guid>
      <description>&lt;p&gt;The MCP protocol is the connective tissue for many open source AI workflows—yet is often treated as a black box. Here’s a developer’s-eye primer on why MCP matters, how it relates to A2A and CLI adapters, and where runtimes like apcore step up to fill governance, audit, and multi-protocol gaps.&lt;/p&gt;

&lt;p&gt;MCP defines how an agent or model can discover, describe, and invoke remote tools. Classic “bare server” MCP implementations give you a surface, but they don’t enforce validation or traceability. Projects aiming for responsible agent development are increasingly layering governed runtimes that check schemas, approvals, and usage evidence before anything is exposed to MCP or A2A.&lt;/p&gt;

&lt;p&gt;For open source maintainers: are your agent-facing modules only protocol-compliant, or are they governable, testable, and ready for enterprise calls? With apcore’s multi-language SDKs and standard contract enforcement, you can bridge to MCP or A2A with confidence—and reduce your incident response exposure.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build a Python Workflow That AI Agents Can Discover with APFlow</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Mon, 26 Oct 2026 11:58:02 +0000</pubDate>
      <link>https://dev.to/tercelyi/build-a-python-workflow-that-ai-agents-can-discover-with-apflow-3583</link>
      <guid>https://dev.to/tercelyi/build-a-python-workflow-that-ai-agents-can-discover-with-apflow-3583</guid>
      <description>&lt;p&gt;Let's build a small workflow that reads two regional request counts and combines them into one report. Along the way, we'll see how APFlow separates workflow structure from execution order and registers Python functions as capabilities that can be exposed to agents.&lt;/p&gt;

&lt;p&gt;The example uses local sample data and SQLite. You can run it without a model provider or an API key.&lt;/p&gt;

&lt;p&gt;APFlow is an open-source Python orchestration engine. It embeds the apcore module standard, giving registered capabilities descriptions and schemas that adapters can expose through MCP, A2A, REST, and CLI.&lt;/p&gt;

&lt;p&gt;Use Python 3.11 or newer. Clone the repository and install APFlow in a virtual environment:&lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/aiperceivable/apflow.git" rel="noopener noreferrer"&gt;https://github.com/aiperceivable/apflow.git&lt;/a&gt;&lt;br&gt;
cd apflow&lt;br&gt;
python -m venv .venv&lt;br&gt;
source .venv/bin/activate&lt;br&gt;
python -m pip install -e .&lt;br&gt;
The activation command above is for a Unix-style shell.&lt;/p&gt;

&lt;p&gt;Define the two relationships&lt;br&gt;
All three tasks belong to one report:&lt;/p&gt;

&lt;p&gt;Structure tree:&lt;br&gt;
report&lt;br&gt;
  ├── north&lt;br&gt;
  └── south&lt;/p&gt;

&lt;p&gt;Execution dependencies:&lt;br&gt;
north ──┐&lt;br&gt;
        ├──&amp;gt; report&lt;br&gt;
south ──┘&lt;br&gt;
parent_id expresses membership in the report. dependencies makes the report wait for both regional results. A structural parent can therefore execute after its children when its dependencies require it.&lt;/p&gt;

&lt;p&gt;The two regional tasks have no dependency on one another, so the engine can schedule them concurrently.&lt;/p&gt;

&lt;p&gt;Register functions and run the graph&lt;br&gt;
Save the following as workflow_demo.py in the cloned repository. The Pydantic models describe the capability inputs and business outputs. Functions receive input dictionaries; the decorator uses the models for their schemas.&lt;/p&gt;

&lt;p&gt;import asyncio&lt;br&gt;
import logging&lt;br&gt;
from typing import Any&lt;/p&gt;

&lt;p&gt;from pydantic import BaseModel, Field&lt;/p&gt;

&lt;p&gt;from apflow.adapters.function_executor import function_executor&lt;br&gt;
from apflow.app import create_app&lt;/p&gt;

&lt;p&gt;class MetricInput(BaseModel):&lt;br&gt;
    region: str = Field(pattern="^(north|south)$")&lt;/p&gt;

&lt;p&gt;class MetricOutput(BaseModel):&lt;br&gt;
    requests: int&lt;/p&gt;

&lt;p&gt;class SummaryInput(BaseModel):&lt;br&gt;
    north: MetricOutput&lt;br&gt;
    south: MetricOutput&lt;/p&gt;

&lt;p&gt;class SummaryOutput(BaseModel):&lt;br&gt;
    total_requests: int&lt;/p&gt;

&lt;p&gt;@function_executor(&lt;br&gt;
    id="sample_metric",&lt;br&gt;
    description="Read a sample request count for one region",&lt;br&gt;
    input_model=MetricInput,&lt;br&gt;
    output_model=MetricOutput,&lt;br&gt;
)&lt;br&gt;
async def sample_metric(inputs: dict[str, Any]) -&amp;gt; dict[str, int]:&lt;br&gt;
    counts = {"north": 12, "south": 18}&lt;br&gt;
    return {"requests": counts[inputs["region"]]}&lt;/p&gt;

&lt;p&gt;@function_executor(&lt;br&gt;
    id="summarize_metrics",&lt;br&gt;
    description="Combine request counts from north and south",&lt;br&gt;
    input_model=SummaryInput,&lt;br&gt;
    output_model=SummaryOutput,&lt;br&gt;
)&lt;br&gt;
async def summarize_metrics(inputs: dict[str, Any]) -&amp;gt; dict[str, int]:&lt;br&gt;
    total = inputs["north"]["requests"] + inputs["south"]["requests"]&lt;br&gt;
    return {"total_requests": total}&lt;/p&gt;

&lt;p&gt;async def main() -&amp;gt; None:&lt;br&gt;
    app = create_app(connection_string="sqlite:///:memory:")&lt;br&gt;
    tasks: list[dict[str, Any]] = [&lt;br&gt;
        {&lt;br&gt;
            "id": "report",&lt;br&gt;
            "name": "Regional report",&lt;br&gt;
            "params": {"executor_id": "summarize_metrics"},&lt;br&gt;
            "dependencies": [{"id": "north"}, {"id": "south"}],&lt;br&gt;
        },&lt;br&gt;
        {&lt;br&gt;
            "id": "north",&lt;br&gt;
            "name": "North request count",&lt;br&gt;
            "parent_id": "report",&lt;br&gt;
            "params": {"executor_id": "sample_metric"},&lt;br&gt;
            "inputs": {"region": "north"},&lt;br&gt;
        },&lt;br&gt;
        {&lt;br&gt;
            "id": "south",&lt;br&gt;
            "name": "South request count",&lt;br&gt;
            "parent_id": "report",&lt;br&gt;
            "params": {"executor_id": "sample_metric"},&lt;br&gt;
            "inputs": {"region": "south"},&lt;br&gt;
        },&lt;br&gt;
    ]&lt;br&gt;
    try:&lt;br&gt;
        tree = await app.task_creator.create_task_tree_from_array(tasks)&lt;br&gt;
        await app.task_manager.distribute_task_tree(tree)&lt;br&gt;
        app.session.expire_all()&lt;br&gt;
        report = await app.task_repository.get_task_by_id("report")&lt;br&gt;
        assert report is not None&lt;br&gt;
        assert report.status == "completed"&lt;br&gt;
        assert report.result == {"total_requests": 30}&lt;br&gt;
        logging.info("Report completed: %s", report.result)&lt;br&gt;
    finally:&lt;br&gt;
        app.session.close()&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;":&lt;br&gt;
    logging.basicConfig(level=logging.INFO)&lt;br&gt;
    asyncio.run(main())&lt;br&gt;
Run it:&lt;/p&gt;

&lt;p&gt;python workflow_demo.py&lt;br&gt;
Among the execution logs, you should see:&lt;/p&gt;

&lt;p&gt;Report completed: {'total_requests': 30}&lt;br&gt;
The assertions also verify the persisted status and business result. The example uses an in-memory database, so its records last for this process.&lt;/p&gt;

&lt;p&gt;Follow the dependency data&lt;br&gt;
APFlow injects each dependency's stored business output under its task ID. Here, summarize_metrics receives inputs["north"] and inputs["south"].&lt;/p&gt;

&lt;p&gt;The function returns {"total_requests": 30} as business data. The function decorator handles the executor result envelope, and the task repository stores the business payload in task.result.&lt;/p&gt;

&lt;p&gt;This distinction becomes useful when an executor also reports usage or a structured execution error. Those values have their own execution metadata rather than becoming fields that every downstream business function must unpack.&lt;/p&gt;

&lt;p&gt;Inspect the capability contract&lt;br&gt;
Because the decorators run before create_app(), the app's registry discovers the custom executors. Inside main(), you can inspect one definition:&lt;/p&gt;

&lt;p&gt;definition = app.registry.get_definition("apflow.sample_metric")&lt;br&gt;
assert definition is not None&lt;br&gt;
logging.info("Input contract: %s", definition.input_schema)&lt;br&gt;
For a server deployment, import your executor module before building the application's registry. A separate apflow serve --all process needs its own executor loading configuration; it does not inherit functions from this completed script.&lt;/p&gt;

&lt;p&gt;You can explore APFlow's built-in HTTP interface independently:&lt;/p&gt;

&lt;p&gt;apflow serve --all&lt;br&gt;
In another terminal:&lt;/p&gt;

&lt;p&gt;curl &lt;a href="http://localhost:8000/modules" rel="noopener noreferrer"&gt;http://localhost:8000/modules&lt;/a&gt;&lt;br&gt;
The unified server also provides /docs, /a2a, and /mcp. Custom modules loaded into that server become available through its configured adapters and policies.&lt;/p&gt;

&lt;p&gt;Move from a local example to an operated workflow&lt;br&gt;
This script demonstrates local execution, dependency injection, and capability registration. Background execution uses the separate durable submission contract: create definitions with an idempotency key, submit the root, and inspect persisted status.&lt;/p&gt;

&lt;p&gt;REST and unified servers run a dispatcher. Standalone MCP, A2A, and CLI submission need one connected to the same database. For recovery, run.retry creates a new Run; submit its new root explicitly. Confirmed completed results can be reused while the original history remains available.&lt;/p&gt;

&lt;p&gt;For a personal project, replace the sample metrics with one useful integration and keep the graph small. For a team, use a representative reporting or document-processing workflow to evaluate identity, failure recovery, and consumption reporting. Shared token scopes require participating executors to declare and enforce consumption bounds.&lt;/p&gt;

&lt;p&gt;APFlow remains classified as Alpha. Start with a workflow whose outcomes you can verify, then add remote side effects and provider integrations deliberately.&lt;/p&gt;

&lt;p&gt;The APFlow repository has the source and examples. See the current durable submission guide for the next step. If you try this example, open an issue with the integration you want to build, and star the repository to follow its development.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>mcp</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Consolidating Governance Across MCP, HTTP, CLI, and A2A</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 22 Oct 2026 09:32:17 +0000</pubDate>
      <link>https://dev.to/tercelyi/consolidating-governance-across-mcp-http-cli-and-a2a-3a0a</link>
      <guid>https://dev.to/tercelyi/consolidating-governance-across-mcp-http-cli-and-a2a-3a0a</guid>
      <description>&lt;p&gt;Most teams already have multiple ways to reach the same operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST / HTTP APIs&lt;/li&gt;
&lt;li&gt;CLIs and scripts&lt;/li&gt;
&lt;li&gt;internal RPC or message‑bus flows&lt;/li&gt;
&lt;li&gt;a2a integrations via SaaS tools&lt;/li&gt;
&lt;li&gt;now: MCP or other agent tool protocols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each surface tends to evolve its own auth, ACL, and logging story.&lt;/p&gt;

&lt;p&gt;That’s painful even before you add AI agents. Once agents are involved, inconsistent governance becomes a hard blocker.&lt;/p&gt;

&lt;p&gt;A more durable architecture is to consolidate governance in a protocol‑neutral capability runtime, and let all surfaces become adapters.&lt;/p&gt;

&lt;p&gt;Define capabilities once&lt;/p&gt;

&lt;p&gt;Create a runtime‑owned catalog where each capability has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a stable ID&lt;/li&gt;
&lt;li&gt;an input/output schema&lt;/li&gt;
&lt;li&gt;an owner and risk classification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backends implement the behavior, but the runtime owns the contract.&lt;/p&gt;

&lt;p&gt;Attach governance at the capability layer&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;API gateway policies here&lt;/li&gt;
&lt;li&gt;service‑level ACLs there&lt;/li&gt;
&lt;li&gt;custom checks in CLIs&lt;/li&gt;
&lt;li&gt;broad API keys for agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…attach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identity + role rules&lt;/li&gt;
&lt;li&gt;approvals&lt;/li&gt;
&lt;li&gt;environment constraints&lt;/li&gt;
&lt;li&gt;additional guards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to the capability itself.&lt;/p&gt;

&lt;p&gt;The runtime enforces those rules for every call.&lt;/p&gt;

&lt;p&gt;Make protocols into adapters&lt;/p&gt;

&lt;p&gt;Adapters for HTTP, CLI, MCP, a2a, etc. should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authenticate in their own context&lt;/li&gt;
&lt;li&gt;map calls into capability invocations with identity + metadata&lt;/li&gt;
&lt;li&gt;send them through the runtime&lt;/li&gt;
&lt;li&gt;map results back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The actual governance (schemas, ACLs, approvals, audit) is shared.&lt;/p&gt;

&lt;p&gt;Standardize evidence&lt;/p&gt;

&lt;p&gt;Because the runtime sees all invocations, it can emit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured events (who did what, via which surface)&lt;/li&gt;
&lt;li&gt;consistent trace IDs and error shapes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes incident response and audits tractable even when agents are involved.&lt;/p&gt;

&lt;p&gt;Migrate incrementally&lt;/p&gt;

&lt;p&gt;You don’t have to flip everything at once.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start with a few high‑risk operations&lt;/li&gt;
&lt;li&gt;define them as capabilities&lt;/li&gt;
&lt;li&gt;run them through the runtime for one surface (e.g., CLI)&lt;/li&gt;
&lt;li&gt;gradually move agent tools and a2a flows over&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each step reduces the number of “islands” with their own policy logic.&lt;/p&gt;

&lt;p&gt;For agent use in particular, this consolidation is what lets you say, with a straight face, that agents follow the same rules and leave the same evidence trail as your other callers.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>architecture</category>
      <category>backend</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Give Your Coding Agent a Governed CLI Workflow with apexe</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Fri, 16 Oct 2026 12:14:58 +0000</pubDate>
      <link>https://dev.to/tercelyi/give-your-coding-agent-a-governed-cli-workflow-with-apexe-500j</link>
      <guid>https://dev.to/tercelyi/give-your-coding-agent-a-governed-cli-workflow-with-apexe-500j</guid>
      <description>&lt;p&gt;An agent task starts simply: list a directory, read a file, inspect a tool. As the task grows, those small calls become a workflow with real permissions and side effects.&lt;/p&gt;

&lt;p&gt;That is a useful place to introduce &lt;strong&gt;apexe&lt;/strong&gt;: a governed execution layer for CLI tools and HTTP APIs. It gives existing commands typed contracts and applies configured policy before execution, with records of executions and refusals.&lt;/p&gt;

&lt;p&gt;Here is how to start with a local CLI workflow, then connect it to the agent or protocol client you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prepare apexe and a trusted CLI
&lt;/h2&gt;

&lt;p&gt;Use a &lt;a href="https://github.com/aiperceivable/apexe/releases" rel="noopener noreferrer"&gt;prebuilt binary&lt;/a&gt;, or build from source with stable Rust and Cargo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aiperceivable/apexe.git
&lt;span class="nb"&gt;cd &lt;/span&gt;apexe
cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--path&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
apexe &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow below targets Unix CLI tools. macOS and Linux are the main starting points; native Windows CLI discovery is not supported. Git is needed to acquire the rules corpus, and the CLI binaries you want to use must already be installed.&lt;/p&gt;

&lt;p&gt;Initialize coverage and inspect the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe init
apexe list &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;init&lt;/code&gt; obtains the configured rules source, normally &lt;a href="https://github.com/aiperceivable/cli-permissions" rel="noopener noreferrer"&gt;cli-permissions&lt;/a&gt;, checks matching installed commands and variants, and writes bindings plus a starter ACL.&lt;/p&gt;

&lt;p&gt;Review &lt;code&gt;~/.apexe/acl.yaml&lt;/code&gt;. A new policy defaults to deny, with generated allow rules for local readonly operations. Existing manual rules and policy defaults are preserved. Treat generated classifications as material to review.&lt;/p&gt;

&lt;p&gt;Read the init report, including skipped tools, warnings, and &lt;code&gt;native_ready&lt;/code&gt; module IDs. This is where you learn which entry points your installation can actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Preview one native invocation
&lt;/h2&gt;

&lt;p&gt;Native execution accepts familiar argv:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this example, you need a matching reviewed native binding. The current native pilot covers &lt;strong&gt;BSD &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt;, and &lt;code&gt;ls&lt;/code&gt;&lt;/strong&gt;. A Linux installation may successfully scan GNU tools while lacking native grammar for this call; scanning coverage and native eligibility are separate.&lt;/p&gt;

&lt;p&gt;Inspect the preflight's validity, execution mode, module, ACL decision, approval requirement, and argument/path checks. Confirm that it describes the operation and policy you intended.&lt;/p&gt;

&lt;p&gt;Only after reading an admitted preflight, submit a separate execution call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Native stdout and stderr pass through, and apexe preserves the child's exit status. You do not need to activate a shell environment or run an MCP server.&lt;/p&gt;

&lt;p&gt;Keep preview and execution separate in an agent workflow: the point is to inspect the result before starting the child. Execution checks the request again; a preview does not reserve permission or grant human approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use module JSON when the binding has no native grammar
&lt;/h2&gt;

&lt;p&gt;Module JSON is another local interface. Start by inspecting the installed schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe list &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output's &lt;code&gt;modules&lt;/code&gt; array contains each module's &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;input_schema&lt;/code&gt;. Use the property names and shapes from your own binding.&lt;/p&gt;

&lt;p&gt;For example, &lt;strong&gt;if&lt;/strong&gt; your &lt;code&gt;cli.ls&lt;/code&gt; schema advertises a &lt;code&gt;file&lt;/code&gt; array, preview:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe &lt;span class="nb"&gt;exec &lt;/span&gt;cli.ls &lt;span class="nt"&gt;--input&lt;/span&gt; &lt;span class="s1"&gt;'{"file":["."]}'&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After inspecting an admitted result, execute separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe &lt;span class="nb"&gt;exec &lt;/span&gt;cli.ls &lt;span class="nt"&gt;--input&lt;/span&gt; &lt;span class="s1"&gt;'{"file":["."]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Module mode captures the result as JSON, including &lt;code&gt;stdout&lt;/code&gt;, &lt;code&gt;stderr&lt;/code&gt;, and &lt;code&gt;exit_code&lt;/code&gt;; it supplies null child stdin. Native mode preserves streams, with stdin inheritance only where reviewed capabilities permit it.&lt;/p&gt;

&lt;p&gt;Both routes apply their normal governance checks. A missing native grammar can justify selecting module JSON for the same operation. An ACL or path refusal calls for resolving the denied request with the operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Give your terminal agent the same workflow
&lt;/h2&gt;

&lt;p&gt;apexe includes one shared routing Skill for &lt;strong&gt;Claude Code, Codex, pi, and OpenCode&lt;/strong&gt;. From the source checkout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/install_agent_skill.py &lt;span class="nt"&gt;--project-dir&lt;/span&gt; /path/to/your-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace that destination with the project where the agent works. Follow the &lt;a href="https://github.com/aiperceivable/apexe/blob/main/docs/agent-skill.md" rel="noopener noreferrer"&gt;Agent Skill guide&lt;/a&gt; to declare the execution route and selected policy in the host's project instructions.&lt;/p&gt;

&lt;p&gt;The Skill guides the agent to resolve configuration before its first task command, route external CLI calls through explicit &lt;code&gt;exec&lt;/code&gt;, preview new or changed calls, and stop on governance refusals. Explicit exec works without shims or MCP.&lt;/p&gt;

&lt;p&gt;For a pipeline, the shell still owns the pipe. Each external stage needs its own governed invocation, and the Skill calls for preflighting stages sequentially before execution. Shell redirection happens outside apexe's typed-path checks.&lt;/p&gt;

&lt;p&gt;Installing the Skill alone does not enroll every project or intercept an unrestricted terminal. Compulsory routing requires host enforcement.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Add an interface when you need it
&lt;/h2&gt;

&lt;p&gt;For existing shell workflows, optional &lt;code&gt;env&lt;/code&gt; integration installs eligible external-command shims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;--enable&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.apexe/bin/apexe-activate.sh
apexe &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;--check&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this after bindings and policy are ready. Shims preserve familiar command names for covered tools. Builtins, aliases, absolute paths, and uncovered commands remain outside that route.&lt;/p&gt;

&lt;p&gt;For an MCP client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe serve &lt;span class="nt"&gt;--acl&lt;/span&gt; ~/.apexe/acl.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For A2A:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe a2a &lt;span class="nt"&gt;--acl&lt;/span&gt; ~/.apexe/acl.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Servers need the explicit ACL flag for access control. Local exec uses caller &lt;code&gt;local&lt;/code&gt; and loads the default ACL when present; if none is loaded, access control is inactive. MCP interactive approval is opt-in with &lt;code&gt;--enable-approval&lt;/code&gt; and a compatible client. Local execution has no interactive approval client, so calls that actually need that decision fail closed. A2A has no interactive approval transport; approval-store support requires library integration.&lt;/p&gt;

&lt;p&gt;Have an HTTP API too? &lt;code&gt;serve&lt;/code&gt; and &lt;code&gt;a2a&lt;/code&gt; can import supported operations from OpenAPI 3.0/3.1 documents alongside CLI modules. See the &lt;a href="https://github.com/aiperceivable/apexe/blob/main/docs/openapi.md" rel="noopener noreferrer"&gt;OpenAPI guide&lt;/a&gt; for the supported JSON proxy surface and credential setup. HTTP import is a server feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the contract current
&lt;/h2&gt;

&lt;p&gt;After a CLI changes, check its source contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apexe verify &lt;span class="nt"&gt;--report&lt;/span&gt; ./drift-report.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional explicit behavioral cases add evidence for the invocations tested. Recorded evidence is bound to binding, executable, and case digests, so changes can invalidate it. It does not certify every possible use of a CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know the execution boundary
&lt;/h2&gt;

&lt;p&gt;Governed CLI calls use structured inputs, configured ACLs, schema-typed path checks, environment scrubbing, timeouts, and auditing. apexe passes argv to the subprocess without evaluating a shell command string.&lt;/p&gt;

&lt;p&gt;An allowed process still has the host process's privileges. &lt;strong&gt;apexe is not an OS sandbox.&lt;/strong&gt; Pair it with the account and isolation boundary your workload needs, and read the &lt;a href="https://github.com/aiperceivable/apexe/blob/main/docs/threat-model.md" rel="noopener noreferrer"&gt;threat model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project is Rust-based and Apache-2.0 licensed. Start with one trusted CLI and one operation you can inspect from preflight through audit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aiperceivable/apexe" rel="noopener noreferrer"&gt;Explore apexe on GitHub&lt;/a&gt; · &lt;a href="https://github.com/aiperceivable/apexe/blob/main/docs/quickstart.md" rel="noopener noreferrer"&gt;Read the quick start&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which CLI would you like your agent to use through a reviewed execution contract?&lt;/p&gt;

</description>
      <category>agents</category>
      <category>cli</category>
      <category>mcp</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Distributed Orchestration vs Agent Reasoning</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 15 Oct 2026 02:47:51 +0000</pubDate>
      <link>https://dev.to/tercelyi/distributed-orchestration-vs-agent-reasoning-lj6</link>
      <guid>https://dev.to/tercelyi/distributed-orchestration-vs-agent-reasoning-lj6</guid>
      <description>&lt;p&gt;A lot of “AI agent orchestration” diagrams quietly merge two very different responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deciding what to do next (reasoning)&lt;/li&gt;
&lt;li&gt;actually running distributed work reliably (orchestration)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve ever operated a workflow engine, you know the second problem doesn’t go away just because a model is choosing the steps.&lt;/p&gt;

&lt;p&gt;Agents are planners, not workflow engines&lt;/p&gt;

&lt;p&gt;Agent frameworks are great at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;breaking down fuzzy tasks&lt;/li&gt;
&lt;li&gt;picking tools / capabilities&lt;/li&gt;
&lt;li&gt;adapting a plan based on intermediate outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re not good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;guaranteeing retries and idempotency&lt;/li&gt;
&lt;li&gt;managing long‑running state&lt;/li&gt;
&lt;li&gt;coordinating fan‑out and aggregation at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are classic workflow concerns.&lt;/p&gt;

&lt;p&gt;What orchestration is responsible for&lt;/p&gt;

&lt;p&gt;A real orchestration layer needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;persist workflow state&lt;/li&gt;
&lt;li&gt;handle node restarts and deploys without losing work&lt;/li&gt;
&lt;li&gt;retry failed steps with backoff&lt;/li&gt;
&lt;li&gt;apply idempotency / deduplication&lt;/li&gt;
&lt;li&gt;support compensation / rollbacks for multi‑step flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In an agentic system, that orchestration is often built on top of a governed capability runtime.&lt;/p&gt;

&lt;p&gt;Why pair a runtime with orchestration?&lt;/p&gt;

&lt;p&gt;A protocol‑neutral capability runtime gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;schema‑validated inputs/outputs for each operation&lt;/li&gt;
&lt;li&gt;identity / ACL / approval checks&lt;/li&gt;
&lt;li&gt;structured traces and events per invocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An orchestrator then uses those capabilities as building blocks, chaining them together under strong guarantees.&lt;/p&gt;

&lt;p&gt;The agent stays in the role of planner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it proposes which capabilities to call and with which parameters&lt;/li&gt;
&lt;li&gt;it can react to structured errors and adjust the plan&lt;/li&gt;
&lt;li&gt;it doesn’t try to be the persistence or retry layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation has practical benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Debuggability&lt;br&gt;
When a flow fails, you can see where: in planning, in runtime validation, or in orchestrated execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safety&lt;br&gt;
Every step is subject to the same ACLs, approvals, and audit behavior, regardless of whether it was triggered by an agent or a human.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evolution&lt;br&gt;
You can swap agent frameworks or tool protocols without rewriting the orchestration and governance layers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small, realistic first step&lt;/p&gt;

&lt;p&gt;If you’re starting from an agent demo that calls services directly, you don’t have to refactor everything at once.&lt;/p&gt;

&lt;p&gt;Try this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pick a single, non‑trivial flow (e.g., canary deploy, batch data fix)&lt;/li&gt;
&lt;li&gt;expose the underlying operations as governed capabilities with schemas&lt;/li&gt;
&lt;li&gt;route all calls through a runtime that adds identity, ACLs, approvals, and traces&lt;/li&gt;
&lt;li&gt;have a simple orchestrator (queue + worker, or a workflow engine you already use) own retries and long‑running state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once that path works, expand the set of capabilities and flows that use it.&lt;/p&gt;

&lt;p&gt;The key shift is mental: treat agents as planners on top of a governed, orchestrated system – not as replacements for the parts of your stack that already give you reliability guarantees.&lt;/p&gt;

</description>
      <category>distributedsystems</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Distributed Orchestration vs Agent Reasoning</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Wed, 14 Oct 2026 02:38:17 +0000</pubDate>
      <link>https://dev.to/tercelyi/distributed-orchestration-vs-agent-reasoning-2efm</link>
      <guid>https://dev.to/tercelyi/distributed-orchestration-vs-agent-reasoning-2efm</guid>
      <description>&lt;p&gt;A lot of “AI agent orchestration” diagrams quietly merge two very different responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deciding what to do next (reasoning)&lt;/li&gt;
&lt;li&gt;actually running distributed work reliably (orchestration)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve ever operated a workflow engine, you know the second problem doesn’t go away just because a model is choosing the steps.&lt;/p&gt;

&lt;p&gt;Agents are planners, not workflow engines&lt;/p&gt;

&lt;p&gt;Agent frameworks are great at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;breaking down fuzzy tasks&lt;/li&gt;
&lt;li&gt;picking tools / capabilities&lt;/li&gt;
&lt;li&gt;adapting a plan based on intermediate outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re not good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;guaranteeing retries and idempotency&lt;/li&gt;
&lt;li&gt;managing long‑running state&lt;/li&gt;
&lt;li&gt;coordinating fan‑out and aggregation at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are classic workflow concerns.&lt;/p&gt;

&lt;p&gt;What orchestration is responsible for&lt;/p&gt;

&lt;p&gt;A real orchestration layer needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;persist workflow state&lt;/li&gt;
&lt;li&gt;handle node restarts and deploys without losing work&lt;/li&gt;
&lt;li&gt;retry failed steps with backoff&lt;/li&gt;
&lt;li&gt;apply idempotency / deduplication&lt;/li&gt;
&lt;li&gt;support compensation / rollbacks for multi‑step flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In an agentic system, that orchestration is often built on top of a governed capability runtime.&lt;/p&gt;

&lt;p&gt;Why pair a runtime with orchestration?&lt;/p&gt;

&lt;p&gt;A protocol‑neutral capability runtime gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;schema‑validated inputs/outputs for each operation&lt;/li&gt;
&lt;li&gt;identity / ACL / approval checks&lt;/li&gt;
&lt;li&gt;structured traces and events per invocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An orchestrator then uses those capabilities as building blocks, chaining them together under strong guarantees.&lt;/p&gt;

&lt;p&gt;The agent stays in the role of planner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it proposes which capabilities to call and with which parameters&lt;/li&gt;
&lt;li&gt;it can react to structured errors and adjust the plan&lt;/li&gt;
&lt;li&gt;it doesn’t try to be the persistence or retry layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation has practical benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Debuggability&lt;br&gt;
When a flow fails, you can see where: in planning, in runtime validation, or in orchestrated execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safety&lt;br&gt;
Every step is subject to the same ACLs, approvals, and audit behavior, regardless of whether it was triggered by an agent or a human.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evolution&lt;br&gt;
You can swap agent frameworks or tool protocols without rewriting the orchestration and governance layers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small, realistic first step&lt;/p&gt;

&lt;p&gt;If you’re starting from an agent demo that calls services directly, you don’t have to refactor everything at once.&lt;/p&gt;

&lt;p&gt;Try this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pick a single, non‑trivial flow (e.g., canary deploy, batch data fix)&lt;/li&gt;
&lt;li&gt;expose the underlying operations as governed capabilities with schemas&lt;/li&gt;
&lt;li&gt;route all calls through a runtime that adds identity, ACLs, approvals, and traces&lt;/li&gt;
&lt;li&gt;have a simple orchestrator (queue + worker, or a workflow engine you already use) own retries and long‑running state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once that path works, expand the set of capabilities and flows that use it.&lt;/p&gt;

&lt;p&gt;The key shift is mental: treat agents as planners on top of a governed, orchestrated system – not as replacements for the parts of your stack that already give you reliability guarantees.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>distributedsystems</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Practical Patterns for AI Agent Governance in Production</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Wed, 07 Oct 2026 00:53:29 +0000</pubDate>
      <link>https://dev.to/tercelyi/practical-patterns-for-ai-agent-governance-in-production-3f84</link>
      <guid>https://dev.to/tercelyi/practical-patterns-for-ai-agent-governance-in-production-3f84</guid>
      <description>&lt;p&gt;When an AI agent starts calling real systems – deploy pipelines, billing, CRM, data workflows – “governance” stops being optional.&lt;/p&gt;

&lt;p&gt;Over the last year, a few practical patterns have emerged for teams that got agents into production without terrifying security and infra.&lt;/p&gt;

&lt;p&gt;Pattern 1: Treat capabilities as a catalog, not just functions&lt;/p&gt;

&lt;p&gt;Instead of wiring agents to ad‑hoc endpoints, define a capability catalog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stable capability IDs&lt;/li&gt;
&lt;li&gt;machine‑readable schemas for inputs and outputs&lt;/li&gt;
&lt;li&gt;metadata (owner, risk, environments)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same capabilities are callable by humans (CLI), services (HTTP/RPC), and agents. That shared catalog becomes your map of what the organization can actually do.&lt;/p&gt;

&lt;p&gt;Pattern 2: Build a centralized enforcement pipeline&lt;/p&gt;

&lt;p&gt;Sprinkling ACL checks and approvals across N services doesn’t scale.&lt;/p&gt;

&lt;p&gt;Introduce a runtime layer that every capability invocation passes through. It should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resolve identity and caller context&lt;/li&gt;
&lt;li&gt;enforce ACLs&lt;/li&gt;
&lt;li&gt;evaluate approval conditions&lt;/li&gt;
&lt;li&gt;run middleware for logging / metrics / policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Downstream services implement business logic; the runtime decides whether the call is allowed and how it should be wrapped.&lt;/p&gt;

&lt;p&gt;Pattern 3: Keep protocols as adapters on the edge&lt;/p&gt;

&lt;p&gt;MCP, HTTP, CLIs, internal RPC – all are just ways to reach the same capabilities.&lt;/p&gt;

&lt;p&gt;If each protocol carries its own governance semantics, you’ll get drift. Instead, let each protocol adapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;map protocol requests into capability calls&lt;/li&gt;
&lt;li&gt;inject identity and context&lt;/li&gt;
&lt;li&gt;route through the same enforcement pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That way, adopting a new tool protocol is mostly an adapter exercise, not a rewrite of core rules.&lt;/p&gt;

&lt;p&gt;Pattern 4: Evidence as a first‑class output&lt;/p&gt;

&lt;p&gt;When something breaks, teams want more than logs. They want evidence.&lt;/p&gt;

&lt;p&gt;Your runtime can emit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured “invocation” events (who, what, where)&lt;/li&gt;
&lt;li&gt;consistent error shapes with trace IDs&lt;/li&gt;
&lt;li&gt;hooks for usage / cost tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because this happens in one place, you don’t depend on every service getting logging exactly right.&lt;/p&gt;

&lt;p&gt;Pattern 5: Offload determinism to an orchestrator&lt;/p&gt;

&lt;p&gt;Agents are planners; they’re not great at guaranteeing that a fan‑out of 1,000 jobs completes exactly once.&lt;/p&gt;

&lt;p&gt;Pair agents with a workflow engine that handles determinism:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retries and idempotency&lt;/li&gt;
&lt;li&gt;timeouts and cancellation&lt;/li&gt;
&lt;li&gt;compensation logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent assembles a plan in terms of governed capabilities; the orchestrator executes that plan reliably.&lt;/p&gt;

&lt;p&gt;Pattern 6: Iterate on one end‑to‑end path&lt;/p&gt;

&lt;p&gt;A realistic path for many teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pick a non‑trivial, high‑value capability (e.g., canary deploy)&lt;/li&gt;
&lt;li&gt;give it a schema, policies, and full tracing&lt;/li&gt;
&lt;li&gt;expose it to a human interface and an agent&lt;/li&gt;
&lt;li&gt;run it in production with tight monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the friction you hit there to refine your runtime, then scale out to more capabilities.&lt;/p&gt;

&lt;p&gt;These patterns don’t depend on a specific framework. They do depend on drawing a clear line between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;capabilities (what can be done)&lt;/li&gt;
&lt;li&gt;the governed runtime (who can do it, under what rules)&lt;/li&gt;
&lt;li&gt;protocols and agents (how it’s requested)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once that separation exists, agent governance becomes a matter of evolving policy and runtime behavior – not rewriting every integration when a new agent pattern appears.&lt;/p&gt;

</description>
      <category>governance</category>
      <category>ai</category>
      <category>agents</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why Raw Shell Access Is the Wrong Agent Integration—and What apexe Does Instead</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 01 Oct 2026 13:21:06 +0000</pubDate>
      <link>https://dev.to/tercelyi/why-raw-shell-access-is-the-wrong-agent-integration-and-what-apexe-does-instead-15c7</link>
      <guid>https://dev.to/tercelyi/why-raw-shell-access-is-the-wrong-agent-integration-and-what-apexe-does-instead-15c7</guid>
      <description>&lt;p&gt;Your organisation probably already owns the capabilities its agents need. They live in git, kubectl, jq, curl, operational scripts, and internal Unix command-line tools.&lt;/p&gt;

&lt;p&gt;The usual choice is uncomfortable: give an agent shell access, or rebuild every useful command as an API or MCP server.&lt;/p&gt;

&lt;p&gt;apexe is built for the middle path. It scans an existing CLI, turns each command into a schema-driven apcore module, and serves those modules through MCP or A2A with execution-time controls.&lt;/p&gt;

&lt;p&gt;existing CLI → module contract + reviewed policy → governed Executor → many agent clients&lt;br&gt;
What is supported today?&lt;br&gt;
Precision matters in agent infrastructure. The current product boundary is:&lt;/p&gt;

&lt;p&gt;Item    apexe 0.8 status&lt;br&gt;
Unix CLI tools on PATH  Supported by apexe scan&lt;br&gt;
macOS/Linux system utilities (ls, cat, cp, sort, …)   Supported as CLI tools, including BSD-aware parsing&lt;br&gt;
Built-in parsers (Man, BSD Usage, GNU, Click, Cobra, Clap)  Supported scanner feature&lt;br&gt;
ACL for scanned CLI modules Supported when supplied with --acl&lt;br&gt;
MCP Supported by apexe serve (stdio, HTTP, Explorer)&lt;br&gt;
A2A Supported by apexe a2a&lt;br&gt;
OpenAPI input   Not supported by the apexe CLI today&lt;br&gt;
OpenAPI deserves a direct note. The apcore toolkit has OpenAPI-related functionality, but apexe does not call its OpenAPIScanner. apexe is currently a CLI-to-agent bridge, so we should not market OpenAPI support as shipped functionality.&lt;/p&gt;

&lt;p&gt;Start with a real CLI&lt;br&gt;
apexe scan git curl jq&lt;br&gt;
apexe list&lt;br&gt;
apexe serve --show-config claude-desktop --acl ~/.apexe/acl.yaml&lt;br&gt;
The scan is deterministic: help text, man pages, and shell completions—not an LLM. It creates one binding per command, such as cli.git.log or cli.curl, and each binding contains JSON Schema for flags and operands.&lt;/p&gt;

&lt;p&gt;An agent calls a JSON object rather than composing a command string:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "url": "&lt;a href="https://httpbin.org/get" rel="noopener noreferrer"&gt;https://httpbin.org/get&lt;/a&gt;",&lt;br&gt;
  "silent": true&lt;br&gt;
}&lt;br&gt;
apexe validates this object, builds argv, and launches the program directly. No shell parses the resulting arguments.&lt;/p&gt;

&lt;p&gt;One capability configuration, many agent clients&lt;br&gt;
The goal is not to create a separate tool definition and security policy for every agent product. Bindings and ACL are the source of truth:&lt;/p&gt;

&lt;p&gt;~/.apexe/bindings/ + ~/.apexe/acl.yaml → apexe → Claude / Codex / Pi / another MCP client&lt;br&gt;
This does not mean every client shares one configuration-file format. Each host still needs its own MCP connection entry. What stays shared is the command or HTTP endpoint, the scanned module bindings, and the reviewed ACL.&lt;/p&gt;

&lt;p&gt;apexe can generate connection snippets for Claude Desktop and Cursor:&lt;/p&gt;

&lt;p&gt;apexe serve --show-config claude-desktop --acl ~/.apexe/acl.yaml&lt;br&gt;
apexe serve --show-config cursor --acl ~/.apexe/acl.yaml&lt;br&gt;
Codex can register the same local stdio server:&lt;/p&gt;

&lt;p&gt;codex mcp add apexe -- apexe serve --acl ~/.apexe/acl.yaml&lt;br&gt;
Pi and other MCP-capable clients can connect through their own MCP configuration mechanism. apexe does not currently generate a Pi-specific file, so the client must support the transport you select. For a shared deployment, run one authenticated HTTP server and have compatible clients connect to that endpoint.&lt;/p&gt;

&lt;p&gt;Why the module contract matters&lt;br&gt;
The contract is what lets the same capability retain its meaning across delivery surfaces:&lt;/p&gt;

&lt;p&gt;apexe serve exposes it over MCP, using stdio by default or HTTP with a browser Explorer.&lt;br&gt;
apexe a2a exposes the same governed modules as agent skills.&lt;br&gt;
--prefix and --tags reduce the registered surface before a client can discover or invoke it.&lt;br&gt;
Policy does not need to be rewritten per protocol because MCP and A2A share the same Executor.&lt;/p&gt;

&lt;p&gt;Governance is a product feature, not a checkbox&lt;br&gt;
apexe scan writes a default-deny ACL. It is a starter policy, not an invisible decision: enforcement begins only when an operator serves with --acl.&lt;/p&gt;

&lt;p&gt;apexe serve --acl ~/.apexe/acl.yaml&lt;br&gt;
The ACL controls which capability may be called. An always-on path guard answers a different question: what filesystem location may this specific call touch? It checks path-typed inputs after resolving symlinks and traversal, protects system paths from writes, and protects credential locations from both reads and writes.&lt;/p&gt;

&lt;p&gt;apexe policy&lt;br&gt;
apexe policy --path /etc/nginx/conf.d --mode write&lt;br&gt;
Every child process is shell-free, runs with a scrubbed environment, has a timeout and output cap, and can produce a private audit record. These are meaningful safeguards, but they are not a sandbox. Run exposed tools inside the container, VM, account, and network boundary your risk model requires.&lt;/p&gt;

&lt;p&gt;Why 0.7 and 0.8 matter&lt;br&gt;
The current releases make the boundary more useful in practice: path protection, argument-sensitive approvals, refusal of verified command-executing parameters, binary availability checks, an explicit default-deny tier for network-reaching tools, and externally maintained verified CLI overlays.&lt;/p&gt;

&lt;p&gt;Bindings now live by default under ~/.apexe/bindings and record which apexe version produced them. Existing users should rescan after upgrading:&lt;/p&gt;

&lt;p&gt;apexe scan git curl jq --no-cache&lt;br&gt;
apexe list --available-only&lt;br&gt;
What comes next: local execution, then native terminal workflows&lt;br&gt;
The next proposed feature is F8 local execution. It is deliberately split into two stages rather than treating a shell wrapper as a shortcut.&lt;/p&gt;

&lt;p&gt;Stage 1, apexe run, is a structured local entry point for one scanned module at a time:&lt;/p&gt;

&lt;p&gt;apexe run cli.ls --input '{"long": true, "paths": ["/tmp"]}' --acl ~/.apexe/acl.yaml&lt;br&gt;
It will reuse the same Executor that MCP and A2A use, produce captured output, and make preflight decisions inspectable from the terminal. It is not native shell syntax and does not provide streaming stdin or pipelines.&lt;/p&gt;

&lt;p&gt;Stage 2, apexe env with PATH shims, is the intended end-user terminal experience. Eligible external commands retain their normal names and argv syntax, so an existing pipeline such as ls -l /tmp | grep ERROR | head -20 can remain unchanged. Each stage is independently resolved to a scanned module and receives schema validation, verified cli-permissions facts, ACL, path guard, timeout, output limit, and audit logging—without using sh -c.&lt;/p&gt;

&lt;p&gt;This is not available yet. Its safety depends on contracts that are still being settled: passthrough I/O, an explicit human-reviewed allowlist for modules that may read streaming stdin, PATH isolation, and measurements of refusal rate and shim latency. It also cannot intercept shell builtins, aliases/functions, or absolute-path calls. Read the F8 design for the exact boundary.&lt;/p&gt;

&lt;p&gt;Join the design conversation&lt;br&gt;
The interesting question is not “can an agent run a command?” It can. The question is which existing capability sources should share a contract, governance layer, and protocol delivery model.&lt;/p&gt;

&lt;p&gt;We would love your comments:&lt;/p&gt;

&lt;p&gt;Which CLI or internal tool would you expose first?&lt;br&gt;
Which agent hosts—Claude, Codex, Pi, or another MCP client—need the same governed tool surface?&lt;br&gt;
Which existing scripts or pipelines should a governed PATH-shim mode support first?&lt;br&gt;
Would OpenAPI ingestion be valuable in the same workflow?&lt;br&gt;
What must an operator review before an agent can use a newly discovered capability?&lt;br&gt;
Project: aiperceivable/apexe&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>cli</category>
      <category>seurity</category>
    </item>
    <item>
      <title>Designing Schema-First Capabilities for AI Agents</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 01 Oct 2026 05:49:02 +0000</pubDate>
      <link>https://dev.to/tercelyi/designing-schema-first-capabilities-for-ai-agents-fpn</link>
      <guid>https://dev.to/tercelyi/designing-schema-first-capabilities-for-ai-agents-fpn</guid>
      <description>&lt;p&gt;If your AI agent can call production systems, the contract between the agent and your capabilities is more important than the prompt.&lt;/p&gt;

&lt;p&gt;A schema‑first capability design puts that contract at the center of your architecture and lets everything else – CLIs, HTTP APIs, agent tools – project from it.&lt;/p&gt;

&lt;p&gt;What is a schema‑first capability?&lt;/p&gt;

&lt;p&gt;Take a real operation in your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create_invoice&lt;/li&gt;
&lt;li&gt;deploy_service&lt;/li&gt;
&lt;li&gt;reset_user_password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of documenting this informally and wiring it directly into APIs, you define a machine‑readable schema that captures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input fields, types, and constraints&lt;/li&gt;
&lt;li&gt;output structure&lt;/li&gt;
&lt;li&gt;error variants and their shapes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This schema is authoritative across all callers: humans, microservices, and AI agents.&lt;/p&gt;

&lt;p&gt;Why do this for agents?&lt;/p&gt;

&lt;p&gt;LLMs are not type‑safe. They will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;omit required fields&lt;/li&gt;
&lt;li&gt;invent new ones&lt;/li&gt;
&lt;li&gt;send wrong types ("five" instead of 5)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you validate deep inside your application, you only discover problems after partial side effects. A schema‑aware runtime can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validate inputs before execution&lt;/li&gt;
&lt;li&gt;validate outputs before returning&lt;/li&gt;
&lt;li&gt;produce structured errors the agent can learn to handle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That alone dramatically reduces “mystery failures” in production.&lt;/p&gt;

&lt;p&gt;Schema as a governance anchor&lt;/p&gt;

&lt;p&gt;Once every capability has a stable ID and schema, you can attach policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which identities / roles may call it&lt;/li&gt;
&lt;li&gt;which calls need approval&lt;/li&gt;
&lt;li&gt;which environments it applies to&lt;/li&gt;
&lt;li&gt;what logging, tracing, and usage hooks must run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Crucially, this policy is attached to the capability itself, not to any single protocol.&lt;/p&gt;

&lt;p&gt;Multi‑language, one contract&lt;/p&gt;

&lt;p&gt;Most organizations run Python, TypeScript, and at least one systems language. A normative schema lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate / validate language‑specific SDKs&lt;/li&gt;
&lt;li&gt;write conformance tests once&lt;/li&gt;
&lt;li&gt;keep contracts synchronized across stacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents don’t care which language implements a capability; they care that the contract is consistent.&lt;/p&gt;

&lt;p&gt;A concrete pattern to start&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose an existing, non‑trivial operation.&lt;/li&gt;
&lt;li&gt;Write its real input/output contract and error cases.&lt;/li&gt;
&lt;li&gt;Encode that as a schema.&lt;/li&gt;
&lt;li&gt;Wrap the implementation in a small runtime layer that validates against the schema and emits structured events.&lt;/li&gt;
&lt;li&gt;Expose it through one additional surface (CLI, HTTP, or a tool protocol).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how often validation catches bad calls&lt;/li&gt;
&lt;li&gt;how much easier debugging becomes with structured traces&lt;/li&gt;
&lt;li&gt;how straightforward it is to add another surface once the capability exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, your catalog of schema‑first capabilities becomes the safe surface area your agents can operate in, with the same rules and evidence as the rest of your stack.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>What a Governed Agent Runtime Actually Does</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Tue, 29 Sep 2026 01:33:25 +0000</pubDate>
      <link>https://dev.to/tercelyi/what-a-governed-agent-runtime-actually-does-31aa</link>
      <guid>https://dev.to/tercelyi/what-a-governed-agent-runtime-actually-does-31aa</guid>
      <description>&lt;p&gt;Most AI agent prototypes fail not because the model is weak, but because the path from the model to real capabilities is essentially ungoverned.&lt;/p&gt;

&lt;p&gt;When an agent can deploy code, mutate data, or touch infrastructure, you need more than tool definitions. You need a governed runtime between the model and the capability.&lt;/p&gt;

&lt;p&gt;In this article I’ll outline what a governed, protocol‑neutral runtime does, why it matters for AI agents, and how it differs from agent frameworks and tool protocols.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start from capabilities, not protocols&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In many stacks, the starting point is the protocol surface: an HTTP API, a CLI, an MCP server, or a bespoke RPC layer. Governance ends up scattered across them.&lt;/p&gt;

&lt;p&gt;A governed runtime inverts this. The primitive is a capability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a function your system can perform&lt;/li&gt;
&lt;li&gt;with a strict input/output schema&lt;/li&gt;
&lt;li&gt;annotated with metadata and policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Protocols become adapters that project that same capability to different callers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enforce strict contracts at the edge&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LLMs are probabilistic. They will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;omit required fields&lt;/li&gt;
&lt;li&gt;invent parameters&lt;/li&gt;
&lt;li&gt;send values in the wrong shape&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only validate deep inside application code, you pay for side effects and partial failures before discovering the problem.&lt;/p&gt;

&lt;p&gt;A governed runtime enforces contracts before execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validate inputs against a schema&lt;/li&gt;
&lt;li&gt;validate outputs before returning&lt;/li&gt;
&lt;li&gt;guarantee error shapes so callers can rely on them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is just as important for human‑driven CLI or HTTP calls as it is for agents.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Centralize governance semantics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When every surface (CLI, HTTP, MCP, a2a) re‑implements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ACL checks&lt;/li&gt;
&lt;li&gt;approval workflows&lt;/li&gt;
&lt;li&gt;environment / tenant routing&lt;/li&gt;
&lt;li&gt;logging and policy hooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…you end up with drift and blind spots.&lt;/p&gt;

&lt;p&gt;A runtime should provide a single pipeline where it can apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identity and ACL resolution&lt;/li&gt;
&lt;li&gt;approval gates for high‑risk actions&lt;/li&gt;
&lt;li&gt;call‑chain guards (who called on behalf of whom)&lt;/li&gt;
&lt;li&gt;middleware for custom policies and observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adapters then plug into that pipeline, instead of embedding their own partial implementation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make execution observable by default&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Governed systems need more than a log line. They need structured evidence.&lt;/p&gt;

&lt;p&gt;A runtime can emit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured errors tied to capability IDs&lt;/li&gt;
&lt;li&gt;trace context that spans agent reasoning and execution&lt;/li&gt;
&lt;li&gt;events (started, retried, completed, failed)&lt;/li&gt;
&lt;li&gt;usage hooks suitable for metrics and billing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes capabilities safe to expose through multiple channels, because you can audit and debug behavior no matter who called them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Separate reasoning from orchestration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agent frameworks excel at planning and choosing tools, not at guaranteeing exactly‑once execution across a fleet of workers.&lt;/p&gt;

&lt;p&gt;A robust design pairs the governed runtime with a workflow / orchestration layer that handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;distributed task execution&lt;/li&gt;
&lt;li&gt;retries, backoff, and idempotency&lt;/li&gt;
&lt;li&gt;timeouts and cancellation&lt;/li&gt;
&lt;li&gt;compensation logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent chooses; the runtime and orchestrator guarantee how.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stay protocol‑neutral&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Today’s hot protocol is MCP. Tomorrow it might be something else.&lt;/p&gt;

&lt;p&gt;If all your semantics live in one protocol layer, you’re locked in. A protocol‑neutral runtime keeps your:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;schemas&lt;/li&gt;
&lt;li&gt;governance&lt;/li&gt;
&lt;li&gt;execution semantics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…independent of any single protocol. MCP, a2a bridges, CLIs, HTTP APIs, and in‑process calls all project the same capability definition.&lt;/p&gt;

&lt;p&gt;What to look for in a governed agent runtime&lt;/p&gt;

&lt;p&gt;When you evaluate libraries and platforms, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where do capability contracts live, and are they language‑agnostic?&lt;/li&gt;
&lt;li&gt;How are identity, ACLs, and approvals enforced?&lt;/li&gt;
&lt;li&gt;Can I expose the same capability to MCP, HTTP, CLI, and internal code without rewriting logic?&lt;/li&gt;
&lt;li&gt;What structured evidence do I get when something goes wrong?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A runtime that answers those questions cleanly will make your agents safer, more debuggable, and easier to operate in production than yet another pile of glue code between an LLM and your systems.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>devtools</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Cross-Language SDKs for a Single Agent Capability Standard</title>
      <dc:creator>tercel</dc:creator>
      <pubDate>Thu, 10 Sep 2026 08:05:30 +0000</pubDate>
      <link>https://dev.to/tercelyi/cross-language-sdks-for-a-single-agent-capability-standard-2hn8</link>
      <guid>https://dev.to/tercelyi/cross-language-sdks-for-a-single-agent-capability-standard-2hn8</guid>
      <description>&lt;p&gt;In most real-world systems, “AI agents” sit on top of a polyglot stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python for data and ML&lt;/li&gt;
&lt;li&gt;TypeScript/Node for backend and APIs&lt;/li&gt;
&lt;li&gt;Rust/Go for performance-sensitive pieces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your capability model only really exists in one language, you end up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate logic in other languages&lt;/li&gt;
&lt;li&gt;Inconsistent validation and error handling&lt;/li&gt;
&lt;li&gt;Governance rules that only apply to the Python part&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more sustainable pattern is to treat the &lt;strong&gt;capability protocol&lt;/strong&gt; as the primary artifact and the language SDKs as implementations.&lt;/p&gt;

&lt;p&gt;Concretely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specify a wire-level protocol and schema format.&lt;/li&gt;
&lt;li&gt;Define how metadata (risk, cost, ownership) and governance hooks (ACL, approvals, audit) attach to a capability.&lt;/li&gt;
&lt;li&gt;Build SDKs in your target languages that:

&lt;ul&gt;
&lt;li&gt;Use the same conformance tests&lt;/li&gt;
&lt;li&gt;Expose idiomatic APIs&lt;/li&gt;
&lt;li&gt;Produce identical runtime behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now a capability implemented in Rust can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Called by a Python-based agent&lt;/li&gt;
&lt;li&gt;Exposed as an HTTP endpoint by a TypeScript service&lt;/li&gt;
&lt;li&gt;Invoked via CLI by ops teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…without reinventing validation, approvals, or tracing.&lt;/p&gt;

&lt;p&gt;If you are designing your own internal runtime, consider starting with the protocol and tests first, and only then layering language-specific ergonomics on top. It is slower upfront but pays off when your stack inevitably becomes polyglot.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
