<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged orchestration</title>
<link>https://coderlegion.com/tag/orchestration</link>
<description>Powered by Question2Answer</description>
<item>
<title>Introducing AIWorkHub: a repository-native control plane for AI coding agents</title>
<link>https://coderlegion.com/23849/introducing-aiworkhub-a-repository-native-control-plane-for-ai-coding-agents</link>
<description>&lt;p&gt; &lt;strong&gt;Suggested canonical URL:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/AIWorkHub&quot;&gt;https://github.com/shrec/AIWorkHub&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Meta description:&lt;/strong&gt; AIWorkHub is an open-source, local-first VS Code control&lt;br&gt;
plane for planning, delegating and reviewing software-development tasks across&lt;br&gt;
multiple AI coding models without giving up repository authority.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;AI coding tools are increasingly capable, but coordinating more than one of&lt;br&gt;
them still feels improvised. A task is copied into a chat, context is scanned&lt;br&gt;
again, a worker changes files, and the result is accepted because the model&lt;br&gt;
says it is finished. The conversation, evidence and project state are often&lt;br&gt;
scattered across tools.&lt;/p&gt;
&lt;p&gt;I built &lt;strong&gt;AIWorkHub&lt;/strong&gt; to turn that workflow into a repository-owned engineering&lt;br&gt;
system.&lt;/p&gt;
&lt;p&gt;AIWorkHub is an open-source, local-first control plane for multi-model software&lt;br&gt;
development in VS Code. It gives each Git repository its own task queue, code&lt;br&gt;
index, durable context, worker isolation, evidence bundles and manager review&lt;br&gt;
loop. It works with model routes already available through VS Code or their&lt;br&gt;
authenticated CLIs, rather than moving project authority into an AIWorkHub&lt;br&gt;
cloud service.&lt;/p&gt;
&lt;p&gt;The project is available under the MIT License:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/AIWorkHub&quot;&gt;https://github.com/shrec/AIWorkHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-problem-is-coordination-not-another-chat-box&quot;&gt;The problem is coordination, not another chat box&lt;/h3&gt;
&lt;p&gt;Once several coding agents participate in a project, the hard questions are no&lt;br&gt;
longer only about generation quality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which task is ready, and which one is blocked by another change?&lt;/li&gt;
&lt;li&gt;Which model is appropriate for the work and currently available?&lt;/li&gt;
&lt;li&gt;What files may a worker modify?&lt;/li&gt;
&lt;li&gt;Did the worker use the repository's approved context tools throughout the&lt;br&gt;
task, or fall back to repeatedly scanning the tree?&lt;/li&gt;
&lt;li&gt;Which tests, diffs and artifacts support the claimed result?&lt;/li&gt;
&lt;li&gt;Who accepts the result and updates canonical project state?&lt;/li&gt;
&lt;li&gt;How do callbacks return to the correct manager, repository and chat?&lt;/li&gt;
&lt;li&gt;What survives a reload, a long session or context compaction?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AIWorkHub treats these as control-plane concerns. The model remains useful for&lt;br&gt;
reasoning and implementation, while deterministic software owns identity,&lt;br&gt;
routing, state transitions, isolation and evidence.&lt;/p&gt;
&lt;h3 id=&quot;one-isolated-workspace-per-repository&quot;&gt;One isolated workspace per repository&lt;/h3&gt;
&lt;p&gt;After explicit initialization, AIWorkHub creates a repository-local&lt;br&gt;
&lt;code&gt;.aiworkhub/&lt;/code&gt; state directory. Tasks, callback records, indexes, sessions,&lt;br&gt;
memories, knowledge entries and audit evidence belong to that repository.&lt;/p&gt;
&lt;p&gt;There is no shared project database and no AIWorkHub HTTP service. The VS Code&lt;br&gt;
extension communicates with a repository-bound MCP runtime over stdio. This&lt;br&gt;
keeps two projects open in two editor windows from silently sharing task state&lt;br&gt;
or context.&lt;/p&gt;
&lt;p&gt;The same verified manager chat can switch between live repositories by stable&lt;br&gt;
repository identity. The selected repository changes; the manager thread does&lt;br&gt;
not need to be recreated for every project.&lt;/p&gt;
&lt;h3 id=&quot;a-task-lifecycle-with-a-real-review-boundary&quot;&gt;A task lifecycle with a real review boundary&lt;/h3&gt;
&lt;p&gt;AIWorkHub models work as dependency-aware task cards. A card can declare:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;its objective and acceptance criteria;&lt;/li&gt;
&lt;li&gt;the runner and model route;&lt;/li&gt;
&lt;li&gt;allowed write paths and forbidden actions;&lt;/li&gt;
&lt;li&gt;dependencies and collision constraints;&lt;/li&gt;
&lt;li&gt;required outputs and validation commands.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Workers run in bounded workspaces. A completed process does not silently become&lt;br&gt;
an accepted change: it enters review with its terminal status and evidence. The&lt;br&gt;
manager can inspect the diff, tests, logs, artifacts, validation history and&lt;br&gt;
tool-use receipts, then accept the change or return a precise residual for&lt;br&gt;
rework.&lt;/p&gt;
&lt;p&gt;That distinction matters. &quot;The agent finished&quot; and &quot;the repository accepted&lt;br&gt;
the change&quot; are different events.&lt;/p&gt;
&lt;h3 id=&quot;source-intelligence-instead-of-repeated-tree-scans&quot;&gt;Source intelligence instead of repeated tree scans&lt;/h3&gt;
&lt;p&gt;AIWorkHub maintains an automatically refreshed &lt;strong&gt;Source Graph&lt;/strong&gt; for the active&lt;br&gt;
repository. Managers and workers can request bounded structural context instead&lt;br&gt;
of repeatedly rediscovering the codebase with broad filesystem scans.&lt;/p&gt;
&lt;p&gt;The goal is not to publish an unverifiable &quot;tokens saved&quot; number. AIWorkHub&lt;br&gt;
records context evidence: what was requested, what was delivered, what the&lt;br&gt;
worker acknowledged, whether content was truncated and why a route degraded.&lt;br&gt;
This makes context efficiency measurable without pretending that bytes are&lt;br&gt;
automatically tokens or dollars.&lt;/p&gt;
&lt;p&gt;Source Graph usage is part of the task evidence, so teams can measure whether&lt;br&gt;
agents use the intended code-intelligence path throughout their work rather&lt;br&gt;
than only mentioning it at the start of a prompt.&lt;/p&gt;
&lt;h3 id=&quot;durable-context-has-more-than-one-job&quot;&gt;Durable context has more than one job&lt;/h3&gt;
&lt;p&gt;AIWorkHub deliberately separates several context authorities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Session Manager&lt;/strong&gt; holds current execution state, checkpoints and handoffs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI Memory&lt;/strong&gt; stores reusable decisions and lessons with lifecycle state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge Base&lt;/strong&gt; stores curated project contracts and authoritative facts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Source Graph&lt;/strong&gt; provides bounded structural code intelligence.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manager Context Graph&lt;/strong&gt; optionally preserves exact completed manager-chat&lt;br&gt;
evidence and deterministic links between repositories, threads, sessions,&lt;br&gt;
tasks, actors and events.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Context Graph is a recovery layer, not an automatic policy engine. A past&lt;br&gt;
conversation can explain why a decision was made; it does not silently override&lt;br&gt;
the current knowledge base or task contract. Current passive capture supports&lt;br&gt;
completed Codex user and assistant messages. It excludes reasoning, streaming&lt;br&gt;
deltas, tool output, commands and approval prompts.&lt;/p&gt;
&lt;h3 id=&quot;multi-model-routing-without-copying-credentials&quot;&gt;Multi-model routing without copying credentials&lt;/h3&gt;
&lt;p&gt;AIWorkHub can route work to Codex, Claude, DeepSeek, GLM and models exposed by&lt;br&gt;
the VS Code Language Model API, depending on what is installed and authorized&lt;br&gt;
on the user's machine.&lt;/p&gt;
&lt;p&gt;Editor routes use models already visible in VS Code and ask for the editor's&lt;br&gt;
normal one-time model consent. CLI routes reuse that CLI's authenticated&lt;br&gt;
session. AIWorkHub does not copy editor or CLI credentials into the repository.&lt;/p&gt;
&lt;p&gt;Availability is discovered at runtime because subscriptions and model catalogs&lt;br&gt;
differ. A preflight surface reports which adapters are installed, authorized&lt;br&gt;
and launchable before a task is claimed.&lt;/p&gt;
&lt;h3 id=&quot;safety-is-part-of-the-architecture&quot;&gt;Safety is part of the architecture&lt;/h3&gt;
&lt;p&gt;Autonomous coding needs narrow authority. AIWorkHub includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;separate write and process-launch gates, both disabled by default;&lt;/li&gt;
&lt;li&gt;shell-free exact-task launches;&lt;/li&gt;
&lt;li&gt;explicit allowed-write scopes;&lt;/li&gt;
&lt;li&gt;isolated worker workspaces and Landlock where available;&lt;/li&gt;
&lt;li&gt;owner-only credentials outside repositories;&lt;/li&gt;
&lt;li&gt;secret-redacted logs;&lt;/li&gt;
&lt;li&gt;durable callback delivery with lease, retry and deduplication;&lt;/li&gt;
&lt;li&gt;fail-closed repository, manager, task and claim identity checks;&lt;/li&gt;
&lt;li&gt;append-only audit evidence and authenticated tool-use receipts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The manager keeps acceptance authority. Launched workers do not inherit the&lt;br&gt;
manager's ability to launch more workers.&lt;/p&gt;
&lt;h3 id=&quot;the-dashboard&quot;&gt;The dashboard&lt;/h3&gt;
&lt;p&gt;The AIWorkHub VS Code dashboard exposes the task queue, dependency state,&lt;br&gt;
review inbox, live output, callback health, adapter preflight, storage usage,&lt;br&gt;
Source Graph status and repository context stores. It opens as an editor tab so&lt;br&gt;
the orchestration surface can sit beside code and model chats.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../assets/screenshots/aiworkhub-self-hosted-dashboard.png&quot; alt=&quot;AIWorkHub dashboard&quot;&gt;&lt;/p&gt;
&lt;p&gt;AIWorkHub is also self-hosted in the practical sense: its own development can&lt;br&gt;
be planned, delegated and reviewed through an AIWorkHub repository instance.&lt;/p&gt;
&lt;h3 id=&quot;install-it&quot;&gt;Install it&lt;/h3&gt;
&lt;p&gt;The current public distribution channel is a GitHub Release VSIX. Marketplace,&lt;br&gt;
Open VSX and PyPI publication are planned but are not live yet.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download &lt;code&gt;aiworkhub-*.vsix&lt;/code&gt; from the&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/AIWorkHub/releases/latest&quot;&gt;latest release&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;code --install-extension aiworkhub-*.vsix
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open a Git repository in VS Code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;strong&gt;AIWorkHub: Open Dashboard&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Initialize AIWorkHub&lt;/strong&gt; once.&lt;/li&gt;
&lt;li&gt;Open a new model chat so it discovers the repository MCP tools.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The packaged extension is qualified for Linux, macOS, native Windows, WSL and&lt;br&gt;
Remote-SSH. Initialization is explicit and idempotent; it creates the local&lt;br&gt;
stores and starts the first Source Graph index.&lt;/p&gt;
&lt;h3 id=&quot;what-comes-next&quot;&gt;What comes next&lt;/h3&gt;
&lt;p&gt;The engineering foundation is in place, but this is still an early open-source&lt;br&gt;
release. The near-term work is focused on distribution, provider-independent&lt;br&gt;
callback qualification, richer visual planning, historical reliability&lt;br&gt;
analytics and making context economics easier to inspect.&lt;/p&gt;
&lt;p&gt;If this direction is useful to you, try the release on a non-critical&lt;br&gt;
repository, read the security model before enabling launches, and share the&lt;br&gt;
rough edges you find.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/AIWorkHub&quot;&gt;https://github.com/shrec/AIWorkHub&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Releases:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/AIWorkHub/releases&quot;&gt;https://github.com/shrec/AIWorkHub/releases&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/null0xxx&quot;&gt;null0xxx&lt;/a&gt; for sharing&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/null0xxx/kimi-atlas&quot;&gt;kimi-atlas&lt;/a&gt; and useful ideas about&lt;br&gt;
multi-agent orchestration and evidence-driven verification.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/23849/introducing-aiworkhub-a-repository-native-control-plane-for-ai-coding-agents</guid>
<pubDate>Fri, 31 Jul 2026 10:08:41 +0000</pubDate>
</item>
<item>
<title>AI-SLOP-DETECTOR v3.8.1: When Code Generation Gets Cheap, Structural Trust Gets Expensive</title>
<link>https://coderlegion.com/19775/ai-slop-detector-v3-8-1-when-code-generation-gets-cheap-structural-trust-gets-expensive</link>
<description>&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=443347642390904533&quot; alt=&quot;cover&quot;&gt;&lt;br&gt;
For a long time, the hardest part of software development was writing code.&lt;/p&gt;
&lt;p&gt;That is no longer true.&lt;/p&gt;
&lt;p&gt;As AI-assisted coding and agent-driven workflows become mainstream, the cost of generating code is collapsing. But the cost of understanding, reviewing, simplifying, and deleting code is rising just as quickly. Code is now easier to append than to validate. Easier to duplicate than to consolidate. Easier to generate than to safely remove.&lt;/p&gt;
&lt;p&gt;That asymmetry is creating a new engineering problem. The question is no longer only:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;How do we generate more code faster?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is increasingly:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;How do we stop generated code from silently degrading the structure of a codebase?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is the space AI-SLOP-DETECTOR is being built for.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;v3.8.1&lt;/code&gt; matters because the project is moving from &lt;strong&gt;detection&lt;/strong&gt; toward &lt;strong&gt;governed cleanup&lt;/strong&gt;, while keeping three layers separate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;scoring&lt;/strong&gt;: measure structural risk&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;action planning&lt;/strong&gt;: prioritize what is safe or important to review&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;enforcement&lt;/strong&gt;: verify what must fail closed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That separation is the real story of this release. It is also the strongest reason to take the project seriously.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-this-release-matters-now&quot;&gt;Why This Release Matters Now&lt;/h3&gt;
&lt;p&gt;There are many tools that claim to measure “AI code quality.” The meaningful distinction is not whether they can emit findings. It is whether they preserve boundary discipline when the findings start to drive workflow.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;v3.8.1&lt;/code&gt; is important because it sharpens three claims:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The scoring path became safer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cleanup became more actionable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Governance became harder to bypass&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Everything else in this release is evidence for one of those three claims.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;changelog-evidence-since-v3-6-0&quot;&gt;Changelog Evidence Since v3.6.0&lt;/h3&gt;
&lt;p&gt;The recent releases make more sense as a sequence than as isolated feature drops.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Version  &lt;/th&gt;&lt;th&gt;Key Change                                                                      &lt;/th&gt;&lt;th&gt;Why It Mattered&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.6.0&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Claude Code Skill, CI gate fix, pre-commit rewrite, VS Code packaging           &lt;/td&gt;&lt;td&gt;The project became more workflow-aware, not just scan-aware&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.0&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Dogfooding calibration, renderer/module splits, self-repair from internal audit &lt;/td&gt;&lt;td&gt;Maintainability and internal trust improved&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.1&lt;/code&gt; &lt;/td&gt;&lt;td&gt;False-positive reduction, richer skill routing, VS Code modularization          &lt;/td&gt;&lt;td&gt;Lower friction and better usability&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.2&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Config/schema validation and runtime data guards                                &lt;/td&gt;&lt;td&gt;The scoring path became harder to corrupt&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.3&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Import/package stability and CI fixes                                           &lt;/td&gt;&lt;td&gt;The tool became more reliable in real environments&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.4&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Major false-positive patch wave                                                 &lt;/td&gt;&lt;td&gt;Trustworthiness improved materially&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.5&lt;/code&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;phantom_import&lt;/code&gt; flat-project fix                                               &lt;/td&gt;&lt;td&gt;A visible correctness gap was closed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.6&lt;/code&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;deficit_breakdown&lt;/code&gt;, idempotent &lt;code&gt;--init&lt;/code&gt;, first-run UX improvements             &lt;/td&gt;&lt;td&gt;Explainability and onboarding improved&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.7&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Cross-language aggregation fix, ignore matching fix, ML reproducibility fix     &lt;/td&gt;&lt;td&gt;Project-level correctness improved&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.8&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Structural scaling, suppression ledger, cache, hotspots, agent API              &lt;/td&gt;&lt;td&gt;The tool became more operational&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.7.9&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Governance verification gate and math/policy separation                         &lt;/td&gt;&lt;td&gt;Enforcement became explicit and fail-closed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.8.0&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Canonical CLI: &lt;code&gt;scan / review / pulse / sweep&lt;/code&gt;                                  &lt;/td&gt;&lt;td&gt;The public surface became simpler and more stable&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;v3.8.1&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Cleanup confidence planning, manifest hygiene, layered architecture review      &lt;/td&gt;&lt;td&gt;The tool moved from issue listing toward action planning&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Seen together, these releases show a pattern: not just more features, but more correctness, more explainability, more governance, and more usable workflow surfaces.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;claim-1-the-scoring-path-became-safer&quot;&gt;Claim 1: The Scoring Path Became Safer&lt;/h3&gt;
&lt;p&gt;The most important technical reinforcement since &lt;code&gt;v3.6.0&lt;/code&gt; is not that the project added more signals. It is that the project made the scoring path safer to trust.&lt;/p&gt;
&lt;p&gt;The core model still uses a weighted geometric aggregation across four dimensions:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65z6q1c8k6f2e8r35mph.png&quot; alt=&quot;1&quot;&gt;&lt;/p&gt;
&lt;p&gt;with the deficit-oriented score driven by:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ny6zvz3veh8rd800c1u.png&quot; alt=&quot;2&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here, &lt;em&gt;&lt;strong&gt;P pattern&lt;/strong&gt;&lt;/em&gt; represents the additional penalty assigned when repeated structural patterns reinforce the deficit.&lt;/p&gt;
&lt;p&gt;That formula is not the interesting part by itself. The important part is what was reinforced around it.&lt;/p&gt;
&lt;h4 id=&quot;what-changed&quot;&gt;What changed&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;config values are validated before they enter the model&lt;/li&gt;
&lt;li&gt;metric ranges are guarded before they can poison the score&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deficit_breakdown&lt;/code&gt; makes score attribution inspectable&lt;/li&gt;
&lt;li&gt;cross-language aggregation no longer misstates project summaries&lt;/li&gt;
&lt;li&gt;structural coherence now scales with deterministic fallback above a ceiling&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;why-it-matters&quot;&gt;Why it matters&lt;/h4&gt;
&lt;p&gt;Without those reinforcements, the formula risks becoming authority texture. With them, it behaves more like an engineering instrument.&lt;/p&gt;
&lt;p&gt;For a technical reader, the observable improvement is not abstract math prestige. It is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fewer broken summaries&lt;/li&gt;
&lt;li&gt;fewer config-induced distortions&lt;/li&gt;
&lt;li&gt;better explanation of where a score came from&lt;/li&gt;
&lt;li&gt;predictable behavior on large repositories&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short, the model became harder to misuse, easier to explain, and more stable at scale.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;claim-2-cleanup-became-more-actionable&quot;&gt;Claim 2: Cleanup Became More Actionable&lt;/h3&gt;
&lt;p&gt;Most code-quality tools stop at issue emission. That is useful, but incomplete.&lt;/p&gt;
&lt;p&gt;Developers do not only need to know what exists. They need to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what is important&lt;/li&gt;
&lt;li&gt;what is probably safe to review&lt;/li&gt;
&lt;li&gt;what needs human caution&lt;/li&gt;
&lt;li&gt;what should be looked at first&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is where &lt;code&gt;v3.8.1&lt;/code&gt; makes its clearest product-level leap.&lt;/p&gt;
&lt;h4 id=&quot;cleanup-confidence-planning&quot;&gt;Cleanup confidence planning&lt;/h4&gt;
&lt;p&gt;Cleanup-family outputs can now carry:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;confidence&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;action_class&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;evidence&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The important architectural choice is that this was &lt;strong&gt;not&lt;/strong&gt; implemented as a second disconnected scoring model. Cleanup confidence is a reuse layer over existing signals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;deficit_score&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;churn&lt;/li&gt;
&lt;li&gt;coverage gap&lt;/li&gt;
&lt;li&gt;cleanup-local evidence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A simplified mental model looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;confidence = base_evidence
confidence += low_churn_bonus
confidence += low_coverage_bonus
confidence -= active_churn_penalty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The exact arithmetic is less important than the architecture: the system is not maintaining one truth model for scoring and another truth model for cleanup.&lt;/p&gt;
&lt;h4 id=&quot;manifest-aware-dependency-hygiene&quot;&gt;Manifest-aware dependency hygiene&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;unused-deps&lt;/code&gt; also grew beyond file-local hints. It now reads:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and can emit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;manifest_unused_dependency&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;undeclared_import&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That matters because many dependency problems are not visible inside a single file. They exist at the boundary between source code and project metadata.&lt;/p&gt;
&lt;h4 id=&quot;why-it-matters-1&quot;&gt;Why it matters&lt;/h4&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;sweep -&amp;gt; list of candidates
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;sweep -&amp;gt; ranked issues -&amp;gt; action class -&amp;gt; evidence-backed review plan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the difference between a detector and a cleanup instrument.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;claim-3-governance-became-harder-to-bypass&quot;&gt;Claim 3: Governance Became Harder To Bypass&lt;/h3&gt;
&lt;p&gt;This is arguably the article’s strongest credibility anchor, and it deserves to be said plainly:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The project does not ask the score to become policy, and it does not let policy quietly mutate the score.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That is the right architectural judgment.&lt;/p&gt;
&lt;h4 id=&quot;what-changed-1&quot;&gt;What changed&lt;/h4&gt;
&lt;p&gt;The project now treats governance as a separate fail-closed path:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;analysis emits a deterministic governance artifact&lt;/li&gt;
&lt;li&gt;verification recomputes the artifact hash&lt;/li&gt;
&lt;li&gt;policy checks run in a dedicated verification gate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The workflow is intentionally layered:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;analysis -&amp;gt; governance_record.json -&amp;gt; verify-governance -&amp;gt; pass/fail enforcement
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;why-it-matters-2&quot;&gt;Why it matters&lt;/h4&gt;
&lt;p&gt;This separation means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;math can evolve without silently changing CI policy&lt;/li&gt;
&lt;li&gt;policy can become stricter without corrupting the scoring model&lt;/li&gt;
&lt;li&gt;governance can be audited as an artifact, not just inferred from a transient report&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a category crowded with vague “AI code quality” claims, this is the kind of subsystem separation that actually signals seriousness.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;supporting-reinforcements&quot;&gt;Supporting Reinforcements&lt;/h3&gt;
&lt;p&gt;The release also includes several important supporting improvements that strengthen the three main claims without replacing them.&lt;/p&gt;
&lt;h4 id=&quot;layered-architecture-review&quot;&gt;Layered architecture review&lt;/h4&gt;
&lt;p&gt;Architecture analysis can now opt into a layered preset rather than stopping at import cycles alone.&lt;/p&gt;
&lt;p&gt;A simplified configuration looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;architecture:
  enabled: true
  preset: layered
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The built-in intent is narrow by design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;api -&amp;gt; domain&lt;/code&gt; allowed&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domain -&amp;gt; data&lt;/code&gt; forbidden&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domain -&amp;gt; service&lt;/code&gt; forbidden&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domain -&amp;gt; api&lt;/code&gt; forbidden&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not enabled by default, and that is correct. Architecture review is valuable only if it avoids becoming a false-positive factory.&lt;/p&gt;
&lt;h4 id=&quot;canonical-cli&quot;&gt;Canonical CLI&lt;/h4&gt;
&lt;p&gt;The public CLI is now much easier to hold in memory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scan&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pulse&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sweep&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That simplification matters because adoption dies when the interface surface grows faster than user confidence.&lt;/p&gt;
&lt;h4 id=&quot;selective-rust-acceleration&quot;&gt;Selective Rust acceleration&lt;/h4&gt;
&lt;p&gt;Performance work also stayed disciplined. The project did &lt;strong&gt;not&lt;/strong&gt; rewrite itself around native code. It kept Python as the product core and used Rust only for measured hot paths such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;file walking&lt;/li&gt;
&lt;li&gt;glob-heavy traversal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is the right trade. Native code is a performance helper here, not a product identity.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;five-topics-worth-a-deeper-follow-up&quot;&gt;Five Topics Worth A Deeper Follow-Up&lt;/h3&gt;
&lt;p&gt;The following five areas deserve separate technical notes because they are where the release’s architecture becomes most visible.&lt;/p&gt;
&lt;h4 id=&quot;1-mathematical-model-hardening&quot;&gt;1. Mathematical Model Hardening&lt;/h4&gt;
&lt;p&gt;The scoring model did not need a louder formula. It needed a safer boundary.&lt;/p&gt;
&lt;p&gt;That is why the important work happened around validation, metric guards, cross-language aggregation, attributed deficit output, and deterministic fallback above scale thresholds. The benefit is practical: fewer strange summaries, safer config changes, and score outputs that are easier to debug.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;scan -&amp;gt; validated metrics -&amp;gt; attributed score -&amp;gt; project summary
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The model now behaves less like an opaque detector and more like a measurement subsystem.&lt;/p&gt;
&lt;h4 id=&quot;2-cleanup-confidence-planning&quot;&gt;2. Cleanup Confidence Planning&lt;/h4&gt;
&lt;p&gt;“This might be dead code” is not enough guidance for real cleanup work.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;v3.8.1&lt;/code&gt; moves cleanup closer to a review plan by attaching confidence, action class, and evidence to cleanup-family findings. The key design choice is reuse: cleanup confidence draws from existing signals such as deficit, churn, coverage, and local evidence instead of inventing a second truth system.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;sweep dead-code -&amp;gt; ranked issue -&amp;gt; action class -&amp;gt; evidence
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That makes cleanup safer for humans and easier for agents to consume.&lt;/p&gt;
&lt;h4 id=&quot;3-manifest-aware-dependency-hygiene&quot;&gt;3. Manifest-Aware Dependency Hygiene&lt;/h4&gt;
&lt;p&gt;Dependency debt is often project-level, not file-local.&lt;/p&gt;
&lt;p&gt;By comparing declared dependencies, imported dependencies, and normalized top-level mappings across &lt;code&gt;pyproject.toml&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt;, the tool can now surface manifest-level problems such as unused declared packages or missing declarations.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;manifest -&amp;gt; imports -&amp;gt; used / unused / missing -&amp;gt; cleanup output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That turns &lt;code&gt;unused-deps&lt;/code&gt; from a file hint into a repository hygiene signal.&lt;/p&gt;
&lt;h4 id=&quot;4-layered-architecture-review&quot;&gt;4. Layered Architecture Review&lt;/h4&gt;
&lt;p&gt;Cycle detection is useful, but many architecture failures appear before cycles do.&lt;/p&gt;
&lt;p&gt;The layered architecture preset gives teams an opt-in way to express allowed and forbidden import directions, with evidence attached to the violation. The important part is restraint: this is not forced on every repository.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;boundary-violations -&amp;gt; cycles + optional layered rule review
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That keeps architecture review useful without turning it into noisy certainty.&lt;/p&gt;
&lt;h4 id=&quot;5-governance-verification-gate&quot;&gt;5. Governance Verification Gate&lt;/h4&gt;
&lt;p&gt;Measurement and enforcement should not collapse into the same layer.&lt;/p&gt;
&lt;p&gt;The governance gate creates a deterministic artifact, verifies it separately, and fails closed when policy or integrity checks break. That makes CI behavior more explicit and audit-friendly.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;scan -&amp;gt; governance artifact -&amp;gt; verify-governance -&amp;gt; pass / fail
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is one of the strongest separations in the system: measurement, artifact generation, and enforcement each have their own boundary.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-this-category-will-keep-growing&quot;&gt;Why This Category Will Keep Growing&lt;/h3&gt;
&lt;p&gt;We are still early.&lt;/p&gt;
&lt;p&gt;Most teams are only beginning to feel what large-scale AI-assisted development actually does to a repository over time. At first it feels like acceleration. Then it starts to feel like churn, duplication, abandoned logic, inflated structure, and uncertainty about what is still safe to touch.&lt;/p&gt;
&lt;p&gt;That is why interest in slop will keep rising.&lt;/p&gt;
&lt;p&gt;The more code agents can generate, the more valuable tools become that help humans decide what should never have remained in the codebase in the first place.&lt;/p&gt;
&lt;p&gt;As agent-driven code development becomes more mainstream, the need for systems like this will likely accelerate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;measure structural trust&lt;/li&gt;
&lt;li&gt;prioritize cleanup&lt;/li&gt;
&lt;li&gt;separate evidence from policy&lt;/li&gt;
&lt;li&gt;make deletion safer&lt;/li&gt;
&lt;li&gt;make governance explicit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI-SLOP-DETECTOR is being built gradually in that direction.&lt;/p&gt;
&lt;p&gt;Not as a one-shot idea.&lt;br&gt;
Not as a trend-chasing wrapper.&lt;br&gt;
Not as a linter with a fashionable label.&lt;/p&gt;
&lt;p&gt;But as a system shaped step by step around a simple reality:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;if AI makes code generation cheap, then structural review, cleanup discipline, and governance become more valuable than ever.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is the craft mindset behind this project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;refine the instrument&lt;/li&gt;
&lt;li&gt;tighten the workflow&lt;/li&gt;
&lt;li&gt;separate the layers&lt;/li&gt;
&lt;li&gt;improve the trust surface one release at a time&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;That is the craft mindset behind this project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;refine the instrument&lt;/li&gt;
&lt;li&gt;tighten the workflow&lt;/li&gt;
&lt;li&gt;separate the layers&lt;/li&gt;
&lt;li&gt;improve the trust surface one release at a time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=3477246220904432325&quot; alt=&quot;repo&quot;&gt;&lt;/p&gt;
&lt;p&gt;Repository: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/flamehaven01/AI-SLOP-Detector&quot;&gt;https://github.com/flamehaven01/AI-SLOP-Detector&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19775/ai-slop-detector-v3-8-1-when-code-generation-gets-cheap-structural-trust-gets-expensive</guid>
<pubDate>Fri, 05 Jun 2026 16:30:58 +0000</pubDate>
</item>
<item>
<title>Sibling Rivalry? How to Make Kestra Tasks Talk to Each Other</title>
<link>https://coderlegion.com/15665/sibling-rivalry-how-to-make-kestra-tasks-talk-to-each-other</link>
<description>&lt;p&gt;I'm putting together a video on sibling tasks in Kestra and thought I would build this idea out loud with you in a blog first.&lt;/p&gt;
&lt;p&gt;Let's jump in!&lt;/p&gt;
&lt;h3 id=&quot;what-are-sibling-tasks-&quot;&gt;What are sibling tasks?&lt;/h3&gt;
&lt;p&gt;Sibling tasks are tasks that have the same parent task. For the rest of this blog, we'll refer to sibling tasks within the context of a dynamic or looping construct.&lt;/p&gt;
&lt;p&gt;So in this case, we can be more specific and say sibling tasks are the tasks defined within the &lt;code&gt;tasks&lt;/code&gt; list of a loop. If we use &lt;code&gt;ForEach&lt;/code&gt; as an example, we could have something that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: my_loop
  type: io.kestra.plugin.core.flow.ForEach
  values: [&quot;alpha&quot;, &quot;beta&quot;]
  tasks:
    - id: first_sibling
      type: io.kestra.plugin.core.debug.Return
      format: &quot;Data for {{ taskrun.value }}&quot;

    - id: second_sibling
      type: io.kestra.plugin.core.log.Log
      # Accessing the sibling's output for the current iteration
      message: &quot;The first sibling said: {{ outputs.first_sibling[taskrun.value].value }}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;ForEach&lt;/code&gt;, or &lt;code&gt;my_loop&lt;/code&gt;, is the parent, with the siblings being &lt;code&gt;first_sibling&lt;/code&gt; and &lt;code&gt;second_sibling&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;In this example you can see our log message contains info passed from &lt;code&gt;first_sibling&lt;/code&gt; with the expression syntax. You will see this in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/qTxlru&quot;&gt;docs&lt;/a&gt; as &quot;sibling task lookup&quot;. Pay attention to the differences between sequential and dynamic tasks, like looping. &lt;/p&gt;
&lt;h3 id=&quot;execution-amp-taskrun-context&quot;&gt;Execution &amp;amp; &lt;code&gt;TaskRun&lt;/code&gt; context&lt;/h3&gt;
&lt;p&gt;You may be familiar with the concept of context or scope and I think this is where things can start to get confusing.&lt;/p&gt;
&lt;p&gt;A task run is a single execution of an individual task within a larger workflow execution. When you are within a &lt;code&gt;ForEach&lt;/code&gt;'s task list, you'll want to use &lt;code&gt;taskrun.value&lt;/code&gt; to get the value associated with that run or iteration.&lt;/p&gt;
&lt;p&gt;This might be a bit different to how you've done looping with programming languages where you are scoped within the brackets of the loop. You don't need to think about iterations, just the work happening within the loop. &lt;/p&gt;
&lt;p&gt;Think of it like a &quot;You Are Here&quot; marker on a map. If you were hiking on a trail and came across a trail map with no marker to tell you where you are, it's not very helpful. You know you are on a trail and you could probably make a guess of where you are based on landmarks or time spent on the trail, but you could also be really wrong. And then get really lost.&lt;/p&gt;
&lt;p&gt;Bringing it back to programming and workflows, using a key to indicate what run or iteration becomes hugely important when you are running tasks concurrently. This means the context needs a hint at what iteration you are interested in. I know I'm looking for data in the loop, but which run? &lt;/p&gt;
&lt;h3 id=&quot;outputs&quot;&gt;Outputs&lt;/h3&gt;
&lt;p&gt;Outputs are how you pass data between tasks or flows. Standard tasks usually reference outputs via &lt;code&gt;{{ outputs.task_id.value }}&lt;/code&gt;. This gives you the value of a specific task's output.  &lt;/p&gt;
&lt;p&gt;In this case, we want to pass data between sibling tasks, which may look something like this &lt;code&gt;{{ outputs.first_sibling[taskrun.value].value }}&lt;/code&gt;. This gives you the values of a specific run or iteration from the &lt;code&gt;first_sibling&lt;/code&gt; task's output. This is very specific and helps prevent any conflict with concurrency or tasks firing in parallel.&lt;/p&gt;
&lt;p&gt;We can't assume &lt;code&gt;ForEach&lt;/code&gt; child tasks will run in parallel unless we set loop concurrency or use a parallel task.&lt;/p&gt;
&lt;p&gt;I highly recommend reading our &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/gYXgq5&quot;&gt;best practices page&lt;/a&gt; on this topic.&lt;/p&gt;
&lt;h3 id=&quot;outputs-vs-execution-amp-taskrun-context&quot;&gt;Outputs vs. execution &amp;amp; TaskRun context&lt;/h3&gt;
&lt;p&gt;But let's say we want to access data outside of the loop. We can do that too, modifying our example from above:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: my_loop
  type: io.kestra.plugin.core.flow.ForEach
  values: [&quot;alpha&quot;, &quot;beta&quot;]
  tasks:
    - id: first_sibling
      type: io.kestra.plugin.core.debug.Return
      format: &quot;Data for {{ taskrun.value }}&quot;

    - id: second_sibling
      type: io.kestra.plugin.core.log.Log
      # Accessing the sibling's output for the current iteration
      message: &quot;The first sibling said: {{ outputs.first_sibling[taskrun.value].value }}&quot;

- id: outside
  type: io.kestra.plugin.core.log.Log
  # Accessing the data for the `alpha` run specifically
  message: &quot;{{ outputs.first_sibling['alpha'].value }}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would give us the &quot;alpha&quot; iteration's output from the &lt;code&gt;first_sibling&lt;/code&gt; task as a value.&lt;/p&gt;
&lt;h3 id=&quot;where-it-gets-confusing&quot;&gt;Where it gets confusing&lt;/h3&gt;
&lt;p&gt;This tends to get confusing when you start using a mix of outputs and &lt;code&gt;taskRun&lt;/code&gt;. When your output exists outside of the loop, you use the standard syntax. Inside the loop? You need to give Kestra the key (or value) associated with the particular iteration. &lt;/p&gt;
&lt;p&gt;Additionally, your error messages can seem non-intuitive. You can will typically get an error where the value isn't found when you forget to use a key.&lt;/p&gt;
&lt;p&gt;So let's look again at this example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: outside
  type: io.kestra.plugin.core.log.Log
  message: &quot;{{ outputs.first_sibling['alpha'].value }}&quot; # correct
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But if we ran this with the key, the value of the iteration we want to capture, we'll get an error.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: outside
  type: io.kestra.plugin.core.log.Log
  message: &quot;{{ outputs.first_sibling.value }}&quot; # will error
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;Unable to find `value` used in the expression `{{ outputs.first_sibling.value }}` at line 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;when-to-use-double-quotes&quot;&gt;When to use double quotes&lt;/h4&gt;
&lt;p&gt;Double quotes around your expressions give a clear indicator that this value is a string. Without them, you may get that unintuitive error that the value in the expression cannot be found.&lt;/p&gt;
&lt;p&gt;When I'm debugging my workflows, I usually try to make sure I have a key for my iteration and I've wrapped my expression in double quotes before I do any more extensive investigation. That usually solves it for me.&lt;/p&gt;
&lt;p&gt;This should show up as a linting warning with a nice yellow squiggle, but it depends on the task properties and types you are working with.&lt;/p&gt;
&lt;h4 id=&quot;when-to-use-foreach-and-foreachitem&quot;&gt;When to use &lt;code&gt;ForEach&lt;/code&gt; and &lt;code&gt;ForEachItem&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;A bigger topic is the differences between &lt;code&gt;ForEach&lt;/code&gt; and &lt;code&gt;ForEachItem&lt;/code&gt;, which we have a great &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/GQ2cTW&quot;&gt;best practices page&lt;/a&gt; on.&lt;/p&gt;
&lt;p&gt;The TL;DR is use &lt;code&gt;ForEachItem&lt;/code&gt; when you want subflows and you are doing a lot of work on a lot of things. &lt;/p&gt;
&lt;p&gt;Let me know if in the comments if you want a blog or video (or both!) on this topic. &lt;/p&gt;
&lt;h3 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h3&gt;
&lt;p&gt;So that covers sibling tasks and outputs and expressions, oh my! Hopefully this adds a little more supplemental details to our docs on this topic. &lt;/p&gt;
&lt;p&gt;As always, let me know if there is something you want me to explain in a little more detail! I'll get a video related to this topic out next week too. &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15665/sibling-rivalry-how-to-make-kestra-tasks-talk-to-each-other</guid>
<pubDate>Thu, 23 Apr 2026 15:49:01 +0000</pubDate>
</item>
<item>
<title>Vulnerability Check &amp; Triage Walkthrough</title>
<link>https://coderlegion.com/14799/vulnerability-check-triage-walkthrough</link>
<description>&lt;p&gt;Use Kestra, Gemini, and Notion to automate a CVE (Common Vulnerabilities &amp;amp; Exposures) checker. Uses AI to get a little more assistance with triage. &lt;/p&gt;
&lt;p&gt;Join me in this video walkthrough to see how you can build a similar solution and stay tuned until the end when I talk about pointers for what I would do to continue building or improve this! &lt;/p&gt;
</description>
<category>Videos</category>
<guid isPermaLink="true">https://coderlegion.com/14799/vulnerability-check-triage-walkthrough</guid>
<pubDate>Tue, 14 Apr 2026 14:36:20 +0000</pubDate>
</item>
<item>
<title>Building a Self-Triaging CVE Checker with Gemini, Kestra, and Notion</title>
<link>https://coderlegion.com/14084/building-a-self-triaging-cve-checker-with-gemini-kestra-and-notion</link>
<description>&lt;p&gt;I built a CVE checker for a nice enterprise-y use case, and of course, it's getting bigger and bigger as I go &quot;ooooh, what if I add this?!&quot; So this is me taking a break and telling you what I've done so far because this was the original stopping point.&lt;/p&gt;
&lt;h3 id=&quot;the-idea&quot;&gt;The idea&lt;/h3&gt;
&lt;p&gt;I needed some kind of data to populate a Notion database (basically a table) so I could do something interesting with our &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/bEUrbf&quot;&gt;Notion + Kestra plugins&lt;/a&gt;. Bonus points if I could sprinkle in some AI augmentation. Extra bonus points if I could make it a realistic enterprise example. Something that really resonates with the enterprise crowd.&lt;/p&gt;
&lt;p&gt;And immediately I was like - CVEs! &lt;/p&gt;
&lt;h4 id=&quot;the-distraction&quot;&gt;The distraction&lt;/h4&gt;
&lt;p&gt;Side note, I spent far too long last week discovering that things may look like and act like Notion Pages, but a Notion Database is not a Notion Page. So if you give the API a Database id when it wants a Page id, it tells you it doesn't exist. Because a database is not a page. Hence, we have a Kestra plugin for Pages and a separate one for Databases now!&lt;/p&gt;
&lt;p&gt;The Notion API makes you use UUIDs, but the value you need is presented in the URL if you are looking at Notion in a browser... but you need to turn that into a UUID. So my search history looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgbv0lx46m005brnlq5m.png&quot; alt=&quot;A Google Search bar and AI summary turning a string of characters into a UUID format&quot;&gt;&lt;/p&gt;
&lt;p&gt;I also use Google Search to do calculations because I could not be bothered to open the calculator app when I'm already in a browser. Follow me for more tips on what Google Search can do. &lt;/p&gt;
&lt;h3 id=&quot;what-i-built&quot;&gt;What I built&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iukkyaoze64fbmvqqsgi.png&quot; alt=&quot;The Kestra flow code editor and topology panels open to show the completed (for now) demo&quot;&gt;&lt;/p&gt;
&lt;p&gt;I needed a list of CVEs, so I went out to CISA and found their &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.cisa.gov/known-exploited-vulnerabilities-catalog&quot;&gt;Known Exploited Vulnerabilities Catalog&lt;/a&gt;. They make this available in a few formats, so I found it in &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json&quot;&gt;JSON&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The objects are pretty clean and tidy and look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &quot;cveID&quot;: &quot;CVE-2026-33017&quot;,
    &quot;vendorProject&quot;: &quot;Langflow&quot;,
    &quot;product&quot;: &quot;Langflow&quot;,
    &quot;vulnerabilityName&quot;: &quot;Langflow Code Injection Vulnerability&quot;,
    &quot;dateAdded&quot;: &quot;2026-03-25&quot;,
    &quot;shortDescription&quot;: &quot;Langflow contains a code injection vulnerability that could allow building public flows without requiring authentication.&quot;,
    &quot;requiredAction&quot;: &quot;Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.&quot;,
    &quot;dueDate&quot;: &quot;2026-04-08&quot;,
    &quot;knownRansomwareCampaignUse&quot;: &quot;Unknown&quot;,
    &quot;notes&quot;: &quot;https:\/\/github.com\/langflow-ai\/langflow\/security\/advisories\/GHSA-vwmf-pq79-vjvx ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2026-33017&quot;,
    &quot;cwes&quot;: [
        &quot;CWE-94&quot;,
        &quot;CWE-95&quot;,
        &quot;CWE-306&quot;
    ]
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CVEs are kind of notorious for being hard to understand. They can pop up randomly and the anxiety that comes with trying to decide if your codebase is impacted, plus how fast you need to mitigate them, can make things harder than necessary. So I wanted to augment this a bit and sprinkle in some AI to help. I want Gemini to help me set the priority and action plan and hopefully make it a little easier for a human to parse than the CVE itself.&lt;/p&gt;
&lt;p&gt;I want to pass &lt;em&gt;new&lt;/em&gt; vulnerabilities to AI because, as of writing this, the list is &lt;strong&gt;1557 CVEs&lt;/strong&gt; long and I want to be conscious of token use. I also think it's more realistic for my demo to have a smallish subset of CVEs to triage. &lt;/p&gt;
&lt;p&gt;Once I have this, I want to send it to a Notion Database, where I can have a nice little visual table to assign a human reviewer and create a Notion Page on the specific CVE to capture any implementation details or other notes the human wants to provide for more context on how this applies (or doesn't apply) to us. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329grbjguct486hkf97e.png&quot; alt=&quot;A screenshot of the Notion Database for CVE tracking with 4 items&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;more-on-the-design&quot;&gt;More on the design&lt;/h3&gt;
&lt;p&gt;I should start by saying, as always, I'm not looking to make highly performant, production-ready demos. There are times I want to do something less than ideal to show particular aspects or features of the product and workflow mechanics. The things I make should spark a conversation or ideation. Besides, you know your use case better than I do.&lt;/p&gt;
&lt;p&gt;Now that I got the disclaimer out of the way, let's talk about the design of this demo.&lt;/p&gt;
&lt;h4 id=&quot;store-individual-cve-ids-in-kv-store&quot;&gt;Store individual CVE IDs in KV Store&lt;/h4&gt;
&lt;p&gt;I wanted to store the known CVE IDs in a way that was searchable within Kestra, and to do that I used the &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/THnUJV&quot;&gt;KV Store&lt;/a&gt;. The keys map to the CVE IDs and the values are the names. The CVE IDs will always be a specific format, but the names could be quite lengthy. However, I could see a case where I need to reference both in my demo.&lt;/p&gt;
&lt;p&gt;This searchability within Kestra gives an admin a fast way to reference whether this is a known CVE in the system since the table in Notion will only show &lt;em&gt;new&lt;/em&gt; known CVEs. &lt;/p&gt;
&lt;h4 id=&quot;iterate-through-the-json&quot;&gt;Iterate through the JSON&lt;/h4&gt;
&lt;p&gt;Since I have this running during off hours, I don't really care how long it takes. With 1500+ CVEs to iterate through, this takes about 20-30 minutes with the concurrency limit set to run some tasks in parallel (&lt;code&gt;5&lt;/code&gt;). Without setting the concurrency limit and just letting this default to running everything sequentially, it takes over an hour. Again, running off hours, I could easily tolerate this.&lt;/p&gt;
&lt;h3 id=&quot;what-s-next&quot;&gt;What's next&lt;/h3&gt;
&lt;p&gt;I'm always like &lt;strong&gt;HOW DO I MAKE THIS EVEN BIGGER&lt;/strong&gt;. What more can I pack into this demo?&lt;/p&gt;
&lt;h4 id=&quot;could-i-just-iterate-over-the-top-of-the-json-&quot;&gt;Could I just iterate over the top of the JSON?&lt;/h4&gt;
&lt;p&gt;Rethinking how I iterate over the JSON. CVEs don't get reported every day, and sometimes multiple get reported in a single day. I could probably be smarter with the iteration and only &quot;read&quot; until I hit a known CVE in my system and then stop since CVEs are added to the top of the JSON response.&lt;/p&gt;
&lt;p&gt;However, if I wanted to build a really robust example and look for &lt;em&gt;any&lt;/em&gt; edits or updates to the CVE information (like whether there is a new known ransomware campaign) I would still need to iterate through all of them.&lt;/p&gt;
&lt;p&gt;This assumes that the behavior I'm seeing, where the CVEs are added to the top of the JSON, is the typical practice. Since I've only been working with this list for ~4 days, this seems typical. &lt;/p&gt;
&lt;p&gt;How would you approach this?&lt;/p&gt;
&lt;h4 id=&quot;pre-populate-notion-pages-with-more-cve-info&quot;&gt;Pre-populate Notion pages with more CVE info&lt;/h4&gt;
&lt;p&gt;I want to pre-populate the page with more info from the CVE. When I add a new item to the database, I get the page id returned. I could then take this page id and send over some content with the rest of the info in the JSON. In the execution outputs, I actually have all that info returned in the Database &lt;code&gt;CreateItem&lt;/code&gt; task, so this would be quite trivial. They even give me the page ID as a UUID!!!!&lt;/p&gt;
&lt;h4 id=&quot;oops-found-a-bug&quot;&gt;Oops, found a bug&lt;/h4&gt;
&lt;p&gt;I wanted to add a checkbox about whether it should be mitigated now. To me, this is different than priority, but more of an urgency indicator. There's a bug with the Notion Database plugin where I couldn't pass in a boolean, so I removed the checkbox for now. &lt;/p&gt;
&lt;h3 id=&quot;wrapping-up-1&quot;&gt;Wrapping up&lt;/h3&gt;
&lt;p&gt;If you want to view or use &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akeller/kestra-demos/blob/main/cve_checker.yaml&quot;&gt;this example&lt;/a&gt; you can find it over on GitHub. I do not recommend running it the first time with the AI and Notion tasks enabled because you'll get &lt;strong&gt;1557+ CVEs&lt;/strong&gt; run through Gemini and added to your Notion database. Comment those out for the first run.&lt;/p&gt;
&lt;p&gt;In fact, as I was building this demo the last ~4 days, the CVEs trickled in at a near perfect rate for me to see 1-3 pop into the table, but often I would have to delete a KV item manually to ensure I could get something to populate in my table. &lt;/p&gt;
&lt;p&gt;If you use it as inspiration, let me know what you are building, or what you want to build! Keen eyes will notice I used Kestra EE, but you could definitely build this with Kestra OSS too with a few tweaks for things like secret management. &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14084/building-a-self-triaging-cve-checker-with-gemini-kestra-and-notion</guid>
<pubDate>Mon, 06 Apr 2026 14:41:55 +0000</pubDate>
</item>
<item>
<title>Anatomy of a Kestra Flow: How It All Fits Together</title>
<link>https://coderlegion.com/13223/anatomy-of-a-kestra-flow-how-it-all-fits-together</link>
<description>&lt;p&gt;Join Developer Advocate Amara Graham as she walks through 4 example flows of increasing complexity to show you different workflow components, required properties, and tactics for making your flows easier to read and maintain. &lt;/p&gt;
&lt;p&gt; Try Kestra for free: &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/yt/try-kestra&quot;&gt;https://go.kestra.io/yt/try-kestra&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All flows in this video, except the hello world boilerplate, are available as blueprints:&lt;br&gt;
log_off_flow (available in two options: Notion or Confluence)&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/rjkn5b&quot;&gt;With Notion&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/TARr7a&quot;&gt;With Confluence&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/UaFWSj&quot;&gt;airbyte-sync-parallel-with-dbt&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/X1YzmY&quot;&gt;argocd-single-tenant-wave-rollout&lt;/a&gt;&lt;/p&gt;
</description>
<category>Videos</category>
<guid isPermaLink="true">https://coderlegion.com/13223/anatomy-of-a-kestra-flow-how-it-all-fits-together</guid>
<pubDate>Thu, 19 Mar 2026 15:48:35 +0000</pubDate>
</item>
<item>
<title>Workshopping my &quot;Anatomy of a Kestra Flow&quot; idea</title>
<link>https://coderlegion.com/12544/workshopping-my-anatomy-of-a-kestra-flow-idea</link>
<description>&lt;p&gt;I pulled together a quick video where I step through 4 different workflows and kind of talk through some ideas I had for more of a polished video. Let me know what you'd like me to focus on or where I should go into more details!&lt;/p&gt;
&lt;p&gt;Like these &quot;working out loud videos&quot;? Let me know that too! I'm happy to share more rough drafts in my quest to &lt;em&gt;learn in public&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;This was originally posted on dev.to via &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/missamarakay/workshopping-my-anatomy-of-a-kestra-flow-video-idea-d8h&quot;&gt;https://dev.to/missamarakay/workshopping-my-anatomy-of-a-kestra-flow-video-idea-d8h&lt;/a&gt;. &lt;/p&gt;
</description>
<category>Videos</category>
<guid isPermaLink="true">https://coderlegion.com/12544/workshopping-my-anatomy-of-a-kestra-flow-idea</guid>
<pubDate>Tue, 10 Mar 2026 20:53:44 +0000</pubDate>
</item>
<item>
<title>What even is orchestration?</title>
<link>https://coderlegion.com/11918/what-even-is-orchestration</link>
<description>&lt;p&gt;I accidentally ended up in the process automation and orchestration space when I started my career, and somehow even more accidentally I'm still there. As Taylor Swift says, &quot;help, I'm still at the restaurant.&quot;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExY3VpenFmYmR0cDl6ZnV5cXp5YXFvc290NnpxcTk3aGRtNm9jeDEyZSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/zhyjappep7O1bj2bsL/giphy.gif&quot; alt=&quot;Taylor Swift waving to the crowd at the beginning of the Eras Tour&quot;&gt;&lt;/p&gt;
&lt;p&gt;Being in the enterprise software space this long, I feel like the pendulum has swung back and forth between &quot;buy a full suite platform, it has everything you need&quot; and &quot;avoid vendor lock-in&quot; and something in between. AI has certainly left it's mark, but hasn't changed things all that dramatically.&lt;/p&gt;
&lt;p&gt;You'll find people and companies saying you need a specialized purpose-built platform with a very specific set of use cases or personas or one that's agnostic and fits any and all needs.&lt;/p&gt;
&lt;p&gt;It's no different in the process automation and orchestration space. &lt;/p&gt;
&lt;p&gt;All of this to say, we still have the same problem - this separation in ownership and responsibilities from the thing we want to improve and how it's actually going to be improved. You often here this positioned as &quot;the business&quot; and &quot;the development team&quot;. &quot;The business&quot; gets pitched as this non-technical group of diagram drawing, process optimizing suits while &quot;the development team&quot; adds the code and system integrations to make the diagram actually work, but doesn't &lt;em&gt;own&lt;/em&gt; the process.&lt;/p&gt;
&lt;p&gt;I still look back on my early career days and remember our business partner asking if she could just give me a Visio diagram and could I turn that into BPMN for her because the standards were too technical. BPMN... as in the standards that were supposed to be the literal language that filled this &quot;gap&quot; between &quot;the business&quot; and &quot;the development team&quot;... was too technical. Interesting. &lt;/p&gt;
&lt;p&gt;I have this hypothesis that people in tech generally understand process automation and why it's beneficial, but only certain areas and roles within tech seem to really resonate with the term &quot;orchestration&quot;. So maybe let's talk about that a bit and give you a few examples of where orchestration really shines. Then you can tell me your definition. &lt;/p&gt;
&lt;h3 id=&quot;ok-so-what-is-orchestration-&quot;&gt;Ok, so what is orchestration?&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExeTNybXV3NDBxZnd3cDhoNnVqMWkyZXU5ZDYyYmZ2MTlqenRkdDFlNSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3ohhwBL1q1I66srvAA/giphy.gif&quot; alt=&quot;A broad zoom in on a conductor of a string orchestra&quot;&gt;&lt;/p&gt;
&lt;p&gt;You would think it's overdone, but the analogy of a conductor with an orchestra really fits here. You have a bunch of different instruments kind of doing their own thing, but together, with the help of a conductor, making a beautiful coherent piece of music happen. They get clues on when to speed up, slow down, or when to play with more or less intensity. &lt;/p&gt;
&lt;p&gt;But I can see how that doesn't translate super well to tech.&lt;/p&gt;
&lt;p&gt;Let's get some help from the internets. &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Orchestration is the coordinated execution of multiple IT automation tasks or processes. Orchestration is usually applied across multiple computer systems, applications, and services to ensure that deployment, configuration management, and other processes are performed in the proper sequence.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Via RedHat&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Orchestration is the coordination and management of multiple computer systems, applications and/or services, stringing together multiple tasks in order to execute a larger workflow or process. More specifically, orchestration is the coordinated execution of multiple IT automation tasks or processes across multiple computer systems, applications and services. These processes can consist of multiple tasks that are automated and can involve multiple systems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Via Databricks&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Orchestration is the process of coordinating distributed software components and systems so that they execute seamlessly as an automated, repeatable process.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Via Orkes&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;These definitions read a lot like the DevOps definitions - multiple systems, coordination, working together with automation, etc.&lt;/p&gt;
&lt;p&gt;Basically, anytime you want to do something complex and chain together a sequence of tasks or coordinate and manage multiple systems, applications, or services either ad-hoc, scheduled, or when &lt;em&gt;something&lt;/em&gt; happens &lt;em&gt;somewhere&lt;/em&gt; you probably want to do it in a clear and reusable way with orchestration. Got it? So clear!&lt;/p&gt;
&lt;p&gt;You'll see orchestration and automation together quite often, but it's typically positioned around the involvement of humans where automation is helping humans, without intervention, complete a single task. Orchestration tends to be more complex, but may involve humans (human-in-the-loop). To what extent humans participate depends. &lt;/p&gt;
&lt;h3 id=&quot;i-think-i-get-it-but-i-need-examples-&quot;&gt;I think I get it, but I need examples...&lt;/h3&gt;
&lt;p&gt;Let's try to make this a little more tangible. &lt;/p&gt;
&lt;h4 id=&quot;data-orchestration&quot;&gt;Data Orchestration&lt;/h4&gt;
&lt;p&gt;You have data everywhere, in multiple disparate systems, and now you want to do something with it. Very everything, everywhere, all at once. This is where you see data pipelines, ETL, etc. come into play. You don't necessarily want to merge all the data together into one big database, but you do want to coordinate across the systems to, say, use the data to make informed decisions. &lt;/p&gt;
&lt;h4 id=&quot;business-orchestration&quot;&gt;Business Orchestration&lt;/h4&gt;
&lt;p&gt;This tends to be where process automation and orchestration live in the traditional IT, HR, and finance workflows. My favorite example in this space is a two-step approval process, because it involved a human-in-the-loop aspect (maybe even two!), but many people have seen this at work or in their personal life. &lt;/p&gt;
&lt;p&gt;If you know what &quot;signature authority&quot; is you've definitely been a part of a process like this, and the larger the organization, the more systems might be involved to make decisions.&lt;/p&gt;
&lt;p&gt;You may encounter a set of rules that fast track you through the process (like my &quot;signature authority&quot; was once $100, which was basically desk trinkets) and anything more than that was escalated to my manager until his &quot;signature authority&quot; limit was hit and then it escalated to his manager. So this system needs to know the org chart, the individuals' &quot;signature authority&quot;, the price of the items to be purchased, etc. All of that info is definitely in different databases, if not completely different systems.  &lt;/p&gt;
&lt;h4 id=&quot;ai-orchestration&quot;&gt;AI Orchestration&lt;/h4&gt;
&lt;p&gt;This is relatively new and gets us into murky territory as well. Agent orchestration, multi-agent systems (MAS), AI pipelines can all fall into this bucket of AI orchestration. MAS for me is really the foundation for where we are at now with AI agents and potentially having them do coordinated work together.&lt;/p&gt;
&lt;p&gt;The agents need data, then with that data they do something with other agents, and something complex happens. &lt;/p&gt;
&lt;p&gt;I'm intentionally being a bit handwavy here because I don't have a great real world example of this yet, just a lot of marketing blogs around specialized agents working together to complete a common goal. &lt;/p&gt;
&lt;h3 id=&quot;but-when-do-you-need-an-orchestrator-&quot;&gt;But when do you need an orchestrator?&lt;/h3&gt;
&lt;p&gt;It depends, of course. &lt;/p&gt;
&lt;p&gt;Some organizations will start building some stitched together, homegrown solution and ultimately hit a point where there is a maintenance or scale issue. Others will realize they want to do something beyond CRON and scheduled jobs, something more real-time and event-based where they need listeners or webhooks.&lt;/p&gt;
&lt;p&gt;Others still will realize they need to do a mix of scheduled, event-based, and manual executions with responsibilities spanning across technical and non-technical roles, and this is usually when they start investigating platforms to handle some of this. &lt;/p&gt;
&lt;h3 id=&quot;so-how-do-you-define-orchestration-&quot;&gt;So, how do you define orchestration?&lt;/h3&gt;
&lt;p&gt;Hopefully, I've given you a bit to think about and start to formulate your own opinion on orchestration. &lt;/p&gt;
&lt;p&gt;What's your definition of orchestration? Are you doing orchestration within your organization? And how did you evaluate your options? &lt;/p&gt;
&lt;h3 id=&quot;sources-amp-further-reading&quot;&gt;Sources &amp;amp; further reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.redhat.com/en/topics/automation/what-is-orchestration&quot;&gt;https://www.redhat.com/en/topics/automation/what-is-orchestration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.databricks.com/glossary/orchestration&quot;&gt;https://www.databricks.com/glossary/orchestration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.prefect.io/blog/what-i-talk-about-when-i-talk-about-orchestration&quot;&gt;https://www.prefect.io/blog/what-i-talk-about-when-i-talk-about-orchestration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://kestra.io/blogs/orchestration-differences&quot;&gt;https://kestra.io/blogs/orchestration-differences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://orkes.io/blog/what-is-orchestration/&quot;&gt;https://orkes.io/blog/what-is-orchestration/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/11918/what-even-is-orchestration</guid>
<pubDate>Thu, 19 Feb 2026 20:41:09 +0000</pubDate>
</item>
<item>
<title>My First Flow with Kestra.io</title>
<link>https://coderlegion.com/11144/my-first-flow-with-kestra-io</link>
<description>&lt;p&gt;As I'm learning more about &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/k91sTC&quot;&gt;Kestra.io&lt;/a&gt;, the community, and the possible use cases, I wanted to build a small PoC (proof of concept) that resonated with me and leveraged a fair amount of the platform aspects so I could get some hands on learning beyond the existing tutorials and examples (which are great! Give them a try!).&lt;/p&gt;
&lt;p&gt;After talking with a coworker, I loved his daily reminder to log off scheduled on his calendar. This kind of daily ritual is really great for wrapping up your day and leaving work at work. Or at least trying to. &lt;/p&gt;
&lt;p&gt;I told him I was going to 100% steal his idea.&lt;/p&gt;
&lt;p&gt;Let me walk you through what I'm doing and learning as I go. This won't be a tutorial, but you can see how I learn and explore a new platform, following along with links back to the docs if you want to learn even more.&lt;/p&gt;
&lt;h3 id=&quot;requirements-of-the-poc&quot;&gt;Requirements of the PoC&lt;/h3&gt;
&lt;p&gt;I wanted to make sure this PoC covered multiple aspects of the platform, even if it might be a little trivial at times. I wanted to see the dashboards populate with some data, use a few &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/3LbDFD&quot;&gt;plugins&lt;/a&gt;, and start to see the difference between the OSS Edition you can access for free and the paid experience with the Kestra &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/efPFOh&quot;&gt;Enterprise Edition&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;I needed to interact with the following during my daily or weekly shutdown:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scheduler/chron - what? You think I would remember to do this daily?&lt;/li&gt;
&lt;li&gt;Slack - our main communication tool and where my weekly recap ultimately needed to land, but also where I'll get the reminder&lt;/li&gt;
&lt;li&gt;GitHub - no surprise here, where the bugs, feature requests, issues, and PRs live for the source code and docs&lt;/li&gt;
&lt;li&gt;Notion - Throw this recap into my &quot;Weekly recaps&quot; so it doesn't get lost on Slack&lt;/li&gt;
&lt;li&gt;Google Calendar - Read my calendar and remind me who I talked to today or this week&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these looked like plugins that should reasonably work well for my PoC. Excellent!&lt;/p&gt;
&lt;p&gt;For my first iteration, I won't make this too terribly smart and it will prompt and grab the same info everyday, just for that day. Maybe v2 will do something more comprehensive on Friday when I actually write my weekly recap.&lt;/p&gt;
&lt;p&gt;After a quick search through the &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/fW0AX8&quot;&gt;Blueprints&lt;/a&gt;, I didn't find anything specific that I wanted to build off of, so I ended up starting from scratch. I usually recommend building from or extending tutorials and existing examples.&lt;/p&gt;
&lt;p&gt;I should also mention I'm building this flow with the flow code editor, directly editing the YAML. &lt;/p&gt;
&lt;h3 id=&quot;what-s-a-plugin-&quot;&gt;What's a plugin?&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/3LbDFD&quot;&gt;Plugins&lt;/a&gt; are the essential building blocks for tasks and triggers in your workflow in Kestra. This might be a subtle shift from some platforms where the plugins are extensions or integrations, which they are in Kestra too, but they also include core functionality. You'll probably end up using several plugins in your flow, and many more if you are doing something non-trivial.&lt;/p&gt;
&lt;p&gt;See if you can spot the plugins I use in the YAML snippets below. You'll see a mix of 3rd party integrations and core functionality.&lt;/p&gt;
&lt;h3 id=&quot;kestra-ui&quot;&gt;Kestra UI&lt;/h3&gt;
&lt;p&gt;Learning new tools always requires spending a little time mapping your existing knowledge to the UI and terms. &lt;/p&gt;
&lt;p&gt;One of the things that I really struggled with early on was the purple, primary action button in the top right corner of the UI changes depending on what screen I'm on. So it could be used to create a flow, execute a flow, create a user (in Kestra &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/efPFOh&quot;&gt;Enterprise Edition&lt;/a&gt;), etc. &lt;/p&gt;
&lt;p&gt;Leave me a comment and let me know how you feel about this UI design choice. Is it intuitive for you? Do you want a more descriptive button name?&lt;/p&gt;
&lt;h3 id=&quot;triggers&quot;&gt;Triggers&lt;/h3&gt;
&lt;p&gt;You probably want to do something when something happens, whether that's a moment in time or based on an event like a form being submitted or new data arriving. You need a &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/XWhPvc&quot;&gt;trigger&lt;/a&gt; for that. For my PoC, I want this to run every weekday around 4pm, when I'm thinking about wrapping up for the day. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;triggers:
  - id: daily_shutdown
    type: io.kestra.plugin.core.trigger.Schedule
    #UTC Austin @ 4pm (could add timezone), except weekends
    cron: 0 22 * * 1-5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like these at the top of the YAML because they show me exactly when this flow happens.&lt;/p&gt;
&lt;h3 id=&quot;tasks&quot;&gt;Tasks&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/epVpkj&quot;&gt;Flows&lt;/a&gt; require at least one &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/hE2je5&quot;&gt;task&lt;/a&gt;. You simply cannot save a flow without a task. This makes sense because why would you have a flow that does nothing. &lt;/p&gt;
&lt;p&gt;I'll have several tasks in my flow, but I want to make sure I see a reminder or prompt in Slack. That will look something like this with the &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/yUdbHp&quot;&gt;Slack plugin&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;id: send_reminder_message_to_slack
    type: io.kestra.plugin.notifications.slack.SlackIncomingWebhook
    url: &quot;{{ secret('SLACK_WEBHOOK') }}&quot;
    payload: |
      {
        &quot;text&quot;: &quot;Time to shutdown&quot;
      }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I'll need to revisit this to add something more interesting to the payload (like info from other tasks), but sending a Slack message is as easy as getting the tokens and secrets configured.&lt;/p&gt;
&lt;p&gt;Eventually, it will look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;id: send_meetings_to_slack
      type: io.kestra.plugin.notifications.slack.SlackIncomingWebhook
      url: &quot;{{ secret('SLACK_WEBHOOK') }}&quot;
      payload: |
        {
          &quot;text&quot;: &quot;Here are the meetings you went to today: {{ outputs.get_calendar_events.events }} &quot;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But we'll talk more about outputs a bit later.&lt;/p&gt;
&lt;h4 id=&quot;logging&quot;&gt;Logging&lt;/h4&gt;
&lt;p&gt;I ended up doing a lot of logging tasks between the tasks that used plugins, mostly to verify what was coming back in the response and if I wanted to do anything else. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: get_cal_list_log
    type: io.kestra.plugin.core.log.Log
    message: &quot;{{ outputs.get_calendar_events }}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I'm still having some trouble getting the Google Calendar plugin to send more than an empty array back, so for now I'm logging the whole object I get back to see if I get any clues. &lt;/p&gt;
&lt;h4 id=&quot;flowable-tasks&quot;&gt;Flowable tasks&lt;/h4&gt;
&lt;p&gt;I threw in a &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/czIlIi&quot;&gt;flowable task&lt;/a&gt; because depending on how you classify a meeting, I don't have meetings everyday. I do have a blocker for lunch everyday, which is technically a meeting...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;- id: if
    type: io.kestra.plugin.core.flow.If
    condition: &quot; {{ outputs.get_calendar_events.events  == [] }} &quot;
    then:
    - id: send_no_meetings_to_slack
      type: io.kestra.plugin.notifications.slack.SlackIncomingWebhook
      url: &quot;{{ secret('SLACK_WEBHOOK') }}&quot;
      payload: |
        {
          &quot;text&quot;: &quot;Hooray! No meetings today.&quot;
        }
    else:
    - id: send_meetings_to_slack
      type: io.kestra.plugin.notifications.slack.SlackIncomingWebhook
      url: &quot;{{ secret('SLACK_WEBHOOK') }}&quot;
      payload: |
        {
          &quot;text&quot;: &quot;Here are the meetings you went to today: {{ outputs.get_calendar_events.events }} &quot;
        }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I really like the human readable way this, well, reads. If, then, else shows me what the condition is and what's going to happen for the two branches.&lt;/p&gt;
&lt;p&gt;I know some platforms allow you to define a default path for flows, but I didn't see that here, which I actually really like. Introducing a default path feels confusing when you should rely on the evaluation of the condition.&lt;/p&gt;
&lt;p&gt;As I mentioned above this is currently always getting  &lt;code&gt;[]&lt;/code&gt; back from the Google Calendar plugin, so apparently I never have meetings, but when it works I'll have that taken care of with this flowable task. &lt;/p&gt;
&lt;h3 id=&quot;outputs-1&quot;&gt;Outputs&lt;/h3&gt;
&lt;p&gt;I added an &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/L78byv&quot;&gt;output&lt;/a&gt; that was trivial because I was most likely going to send the summary of the work I did to Slack in the message payload and wasn't sure if there would be any difference if I did or didn't have an output. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;outputs:
  - id: sent_bool
    type: BOOLEAN
    value: &quot;true&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the execution outputs, I wanted to see something I added and where it would show up in the UI. Again, trivial, because in this iteration I don't anticipate this flow making data available for a subsequent flow.&lt;/p&gt;
&lt;p&gt;I did use outputs across the various tasks too, so I could use the data from one task in the following task. &lt;/p&gt;
&lt;h3 id=&quot;revisions&quot;&gt;Revisions&lt;/h3&gt;
&lt;p&gt;Don't do what I did as a lazy developer and put my secrets right into my flow. They stay in your &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/QxmWNf&quot;&gt;revision&lt;/a&gt; history. Plain text. Oops.&lt;/p&gt;
&lt;p&gt;Secret handling in the Enterprise Edition is too easy to not use, so don't put your secrets plain text in your flow. Keep your secrets secret. Then use an expression like below:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;{{ secret('SLACK_WEBHOOK') }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Revisions become really powerful as you are making changes to your flow, particularly while you are building and testing because sometimes a change doesn't work like you want, and through revisions you can see exactly what changes were made.&lt;/p&gt;
&lt;h3 id=&quot;where-i-m-at&quot;&gt;Where I'm at&lt;/h3&gt;
&lt;p&gt;I love that I can export an image of my topology directly in Kestra.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cd5z8jmar0p7kon88agg.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;So for now I don't have a &quot;working&quot; increment that I'm happy with. While it is firing every day, I still need to dig into why Google Calendar thinks I have no meetings... when I definitely have meetings. I'm currently playing around with public/private event visibility to see if that changes anything. More on that next week I'm sure when I also add the Notion and GitHub plugins.&lt;/p&gt;
&lt;p&gt;Have you built something with Kestra? Link me to your repo in a comment below. &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/11144/my-first-flow-with-kestra-io</guid>
<pubDate>Fri, 06 Feb 2026 13:00:00 +0000</pubDate>
</item>
<item>
<title>Contributing to Kestra - Where to start and pointers to get there</title>
<link>https://coderlegion.com/10941/contributing-to-kestra-where-to-start-and-pointers-to-get-there</link>
<description>&lt;p&gt;I recently did a &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/16L7TT&quot;&gt;webinar&lt;/a&gt; where I talked with two Kestra contributors about their contribution experience. While our discussion was mostly centered around plugins, this reminded me we have multiple ways to contribute to Kestra and I figured I should cover them. While I know there is a big push to contribute during Hacktoberfest, contributions are accepted all year round!&lt;/p&gt;
&lt;p&gt;Kestra has several areas or opportunities for contributions, and depending on your expertise, you may find some more interesting than others. We have a &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/hMFwmd&quot;&gt;general contribution guide&lt;/a&gt; that covers the code base and documentation.&lt;/p&gt;
&lt;h3 id=&quot;where-to-start-&quot;&gt;Where to start?&lt;/h3&gt;
&lt;p&gt;Both contributors mentioned started with technology they were already familiar with and looking for issues labeled &lt;code&gt;good first issue&lt;/code&gt;. This is such a great strategy because the less you have to learn, the quicker you can get to doing! &lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/dv7jHp&quot;&gt;Good first issue&lt;/a&gt;, at least at the time of writing this post, had a mix of front end, back end, and plugin issues. You may also see some issues for our docs, although most of those tend to be in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/DkxlSO&quot;&gt;docs repo&lt;/a&gt;. &lt;/p&gt;
&lt;h3 id=&quot;docs&quot;&gt;Docs&lt;/h3&gt;
&lt;p&gt;Having fresh eyes on a product and the docs gives you a really great perspective to review for intuitive design, clarity, and overall user experience. As you are reading and using the Kestra docs you may have questions or improvements that you notice. These make great opportunities for creating an issue (particularly if you need to clarify your understanding). If you have questions about documentation, it's entirely likely that others do as well. &lt;/p&gt;
&lt;p&gt;We don't often label issues in the docs repo for &lt;code&gt;good first issue&lt;/code&gt; but there are a &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/iJn0Pa&quot;&gt;few&lt;/a&gt; (at least at the time of writing this). &lt;/p&gt;
&lt;h3 id=&quot;plugins&quot;&gt;Plugins&lt;/h3&gt;
&lt;p&gt;Plugins are the foundation of tasks in Kestra flows and offer integrations outside of Kestra itself. Kestra has an extensive plugin library, but depending on the plugin, it may not offer complete cover of the API. Sometimes this is a bit of a design choice, other times it's simply because there was no use case for that particular endpoint of functionality. Extending the plugin is a great place to contribute. &lt;/p&gt;
&lt;p&gt;If you are looking for ways to contribute to plugins, each plugin has it's own repo. You can look for issues there. Some plugin issues are also in the main Kestra repo.&lt;/p&gt;
&lt;p&gt;There is also a dedicated &lt;a rel=&quot;nofollow&quot; href=&quot;https://go.kestra.io/tVslET&quot;&gt;plugin developer guide&lt;/a&gt; to help you understand the overall plugin landscape.&lt;/p&gt;
&lt;h3 id=&quot;blueprints&quot;&gt;Blueprints&lt;/h3&gt;
&lt;p&gt;Seeing things in action with more of an end-to-end example is really helpful in truly understanding how something works. Blueprints combine multiple plugins to accomplish a goal and make it easy to get a flow started.&lt;/p&gt;
&lt;p&gt;Find a plugin with no blueprint? This is a great opportunity to create a blueprint yourself. Think of a real world example. Bonus points if you use it when you are done.&lt;/p&gt;
&lt;p&gt;Where will you make your first contribution to Kestra?&lt;/p&gt;
&lt;p&gt;Photo by &lt;a rel=&quot;nofollow&quot; href=&quot;https://unsplash.com/@tayannphoto?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Taylor Burnfield&lt;/a&gt; on &lt;a rel=&quot;nofollow&quot; href=&quot;https://unsplash.com/photos/neon-sign-illuminated-to-announce-open-d2-rXpgx_MU?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10941/contributing-to-kestra-where-to-start-and-pointers-to-get-there</guid>
<pubDate>Mon, 02 Feb 2026 19:05:31 +0000</pubDate>
</item>
<item>
<title>DevLog 20250807: Microservice for Cloud Scheduling (and Running)</title>
<link>https://coderlegion.com/4500/devlog-20250807-microservice-for-cloud-scheduling-and-running</link>
<description>&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;/h3&gt;
&lt;p&gt;When working with routine tasks, it's convenient to have some form of automatic scheduling. Windows has &lt;strong&gt;Task Scheduler&lt;/strong&gt;, Linux has &lt;code&gt;cron&lt;/code&gt;, and in AWS, you can use &lt;strong&gt;Lambda&lt;/strong&gt; with &lt;strong&gt;EventBridge&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Wouldn't it be nice if we could periodically pull data from the web, do some light processing, and then dump the results into a database - maybe update a website, trigger a CI/CD process, or send a few emails?&lt;/p&gt;
&lt;p&gt;I haven't used it, but I imagine that's what &lt;strong&gt;Zapier&lt;/strong&gt; is designed for. Azure/GitHub Actions are certainly handy for CI/CD. But what if we just want to quickly prototype something, ship it to a server, and forget about it?&lt;/p&gt;
&lt;p&gt;That's the vision, anyway.&lt;/p&gt;
&lt;h3 id=&quot;the-first-attempts&quot;&gt;The First Attempts&lt;/h3&gt;
&lt;p&gt;When I first started building services for cloud computing, I combined both &quot;trigger a run&quot; and &quot;schedule repeated tasks&quot; into a single service. That sort of worked - but it didn't feel elegant. &lt;strong&gt;Something was off.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Even now, after deciding to completely separate the &quot;runner&quot; and &quot;scheduler&quot; into two distinct microservices, I can't fully articulate &lt;em&gt;why&lt;/em&gt; this approach feels better. It just does. Of course, this means maintaining three or four separate programs now (runner, runner service, scheduler, scheduler service) - but each one is responsible for a single task, and that somehow feels more reassuring.&lt;/p&gt;
&lt;h3 id=&quot;separation-of-concerns-amp-the-single-responsibility-principle&quot;&gt;Separation of Concerns &amp;amp; the Single Responsibility Principle&lt;/h3&gt;
&lt;p&gt;I asked ChatGPT for a rationale that aligned with my intuition, and here's what it gave me:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;What you're discovering is a classic case of &lt;strong&gt;separation of concerns&lt;/strong&gt; (and in the microservice world, the &quot;scheduler-worker&quot; or &quot;cron-vs-runner&quot; pattern), underpinned by the Single Responsibility Principle. Here's why splitting &quot;who decides when&quot; from &quot;what actually does the work&quot; just &lt;em&gt;feels&lt;/em&gt; better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;1-single-responsibility-amp-cognitive-load&quot;&gt;1. Single Responsibility &amp;amp; Cognitive Load&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scheduler service&lt;/strong&gt; - its sole job is: &quot;At 8 AM on Tuesdays, kick off job X.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runner service&lt;/strong&gt; - its sole job is: &quot;When told to run X, do the fetch/process/dump.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By assigning each service a clear, focused purpose, you reduce logic complexity in any single codebase. You don't need to sift through your fetch logic to understand date calculations, and you don't need to worry about HTTP clients inside your scheduler.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Feels better&lt;/strong&gt; because each code path is narrow, easy to reason about, and small enough to hold entirely in your head.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;2-loose-coupling-amp-replaceability&quot;&gt;2. Loose Coupling &amp;amp; Replaceability&lt;/h4&gt;
&lt;p&gt;When the scheduler and runner communicate through a simple interface (e.g., message queue, webhook, or HTTP call), either can be swapped out independently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Want to switch from cron-style fixed schedules to GitHub webhook events?&lt;/li&gt;
&lt;li&gt;Need to rewrite your worker in another language for better library support?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You only have to reimplement one microservice - not the whole system.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Feels better&lt;/strong&gt; because the impact of change is localized.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;3-independent-scaling-amp-reliability&quot;&gt;3. Independent Scaling &amp;amp; Reliability&lt;/h4&gt;
&lt;p&gt;Scheduling frequency and execution workload rarely match 1:1.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maybe you schedule jobs every minute, but each run only takes a few seconds.&lt;/li&gt;
&lt;li&gt;Or you only need one scheduler, but dozens of parallel workers to clear a backlog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Separating the two allows for independent sizing, deployment, and monitoring.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Feels better&lt;/strong&gt; because you avoid resource contention (e.g., a busy worker delaying the next schedule) and can autoscale each component based on its own metrics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;4-clear-boundaries-for-observability-amp-error-handling&quot;&gt;4. Clear Boundaries for Observability &amp;amp; Error Handling&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scheduler logs&lt;/strong&gt; should only show: &quot;Job X was triggered at time T.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runner logs&lt;/strong&gt; should only show: &quot;Processing of job X succeeded/failed.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This allows for more targeted alerting and diagnostics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alert if a scheduled trigger &lt;em&gt;never&lt;/em&gt; reaches the runner.&lt;/li&gt;
&lt;li&gt;Alert if the runner fails more than N times, regardless of the schedule.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Feels better&lt;/strong&gt; because root cause analysis is straightforward - you know where to look first.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;5-pattern-analogues-amp-ecosystem-support&quot;&gt;5. Pattern Analogues &amp;amp; Ecosystem Support&lt;/h4&gt;
&lt;p&gt;This approach mirrors patterns built into major platforms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS CloudWatch Events (scheduler) → Lambda (worker)&lt;/li&gt;
&lt;li&gt;Kubernetes CronJob (scheduler) → Job pods (workers)&lt;/li&gt;
&lt;li&gt;Celery Beat (scheduler) → Celery workers (task executors)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of them separate the &quot;when&quot; from the &quot;what,&quot; and you're starting to feel the same advantages they offer at scale.&lt;/p&gt;
&lt;h4 id=&quot;in-summary&quot;&gt;In Summary&lt;/h4&gt;
&lt;p&gt;You're gravitating toward a &lt;strong&gt;Scheduler–Worker&lt;/strong&gt; (or &quot;Cron-as-a-Service&quot; + &quot;Stateless Runner&quot;) pattern because it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reduces cognitive load&lt;/strong&gt; by narrowing each service's scope&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decouples&lt;/strong&gt; timing logic from business logic&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enables independent scaling&lt;/strong&gt; and more precise reliability controls&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improves testability&lt;/strong&gt; (you can mock the scheduler in runner tests, and vice versa)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aligns&lt;/strong&gt; with proven cloud-native and messaging patterns&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That &quot;reassuring&quot; feeling is the comfort of a clean, modular architecture - you can see exactly &lt;em&gt;what&lt;/em&gt; does &lt;em&gt;what&lt;/em&gt;, and update or extend each part without unraveling the rest.&lt;/p&gt;
&lt;h3 id=&quot;the-analogy&quot;&gt;The Analogy&lt;/h3&gt;
&lt;p&gt;Here is the way I understand it: a rough analogy might be batch-processing vs programming - when chaining multiple operations, it's better to use shell scripting than to rely on spawning subprocesses directly in your source code.&lt;/p&gt;
</description>
<category>Backend Dev</category>
<guid isPermaLink="true">https://coderlegion.com/4500/devlog-20250807-microservice-for-cloud-scheduling-and-running</guid>
<pubDate>Fri, 08 Aug 2025 04:22:53 +0000</pubDate>
</item>
</channel>
</rss>