<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tutorials on scafctl</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/</link><description>Recent content in Tutorials on scafctl</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://oakwood-commons.github.io/scafctl/docs/tutorials/index.xml" rel="self" type="application/rss+xml"/><item><title>Getting Started</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/getting-started/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/getting-started/</guid><description>&lt;h1 id="getting-started-with-scafctl"&gt;Getting Started with scafctl&lt;a class="anchor" href="#getting-started-with-scafctl"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This guide will help you get up and running with scafctl in under 10 minutes.&lt;/p&gt;
&lt;h2 id="what-is-scafctl"&gt;What is scafctl?&lt;a class="anchor" href="#what-is-scafctl"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl is a CLI tool for declarative configuration and workflow automation. It uses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Resolvers&lt;/strong&gt; to gather and transform data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actions&lt;/strong&gt; to perform side effects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Providers&lt;/strong&gt; as the execution primitives for both&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Think of it as a way to define &amp;ldquo;what you want&amp;rdquo; (data + operations) in YAML, and let scafctl figure out &amp;ldquo;how to do it&amp;rdquo; (dependency order, parallelization, error handling).&lt;/p&gt;</description></item><item><title>Solution Scaffolding Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/scaffolding-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/scaffolding-tutorial/</guid><description>&lt;h1 id="solution-scaffolding-tutorial"&gt;Solution Scaffolding Tutorial&lt;a class="anchor" href="#solution-scaffolding-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using &lt;code&gt;scafctl new solution&lt;/code&gt; to quickly scaffold new solution files with the correct structure, providers, and best practices.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;new solution&lt;/code&gt; command generates a complete, valid solution YAML file based on your inputs. Instead of writing YAML from scratch (and getting field names wrong), scaffolding gives you a working starting point.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Parameters&amp;lt;br/&amp;gt;(name, etc)&amp;#34;] --&amp;gt; B[&amp;#34;scafctl&amp;lt;br/&amp;gt;new solution&amp;#34;] --&amp;gt; C[&amp;#34;Solution&amp;lt;br/&amp;gt;YAML File&amp;#34;]&lt;/pre&gt;&lt;h2 id="1-quick-start"&gt;1. Quick Start&lt;a class="anchor" href="#1-quick-start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="generate-a-basic-solution"&gt;Generate a Basic Solution&lt;a class="anchor" href="#generate-a-basic-solution"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="book-tabs"&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-0" checked="checked" /&gt;&lt;label for="tabs-0-0"&gt;Bash&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl new solution &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --name my-app &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --description &lt;span style="color:#a5d6ff"&gt;&amp;#34;My application configuration&amp;#34;&lt;/span&gt; &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --output my-app.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-1" /&gt;&lt;label for="tabs-0-1"&gt;PowerShell&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl new solution `
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --name my-app `
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --description &lt;span style="color:#a5d6ff"&gt;&amp;#34;My application configuration&amp;#34;&lt;/span&gt; `
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --output my-app.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This generates a valid solution file with:&lt;/p&gt;</description></item><item><title>Resolver Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/resolver-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/resolver-tutorial/</guid><description>&lt;h1 id="resolver-tutorial"&gt;Resolver Tutorial&lt;a class="anchor" href="#resolver-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using scafctl resolvers to dynamically resolve configuration values. You&amp;rsquo;ll learn how to define resolvers, use different providers, handle dependencies, and implement common patterns.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax&lt;/li&gt;
&lt;li&gt;Understanding of environment variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#your-first-resolver"&gt;Your First Resolver&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-parameters"&gt;Using Parameters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#resolver-dependencies"&gt;Resolver Dependencies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#transformations"&gt;Transformations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#validation"&gt;Validation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#conditional-execution"&gt;Conditional Execution&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#error-handling"&gt;Error Handling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#working-with-http-apis"&gt;Working with HTTP APIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="your-first-resolver"&gt;Your First Resolver&lt;a class="anchor" href="#your-first-resolver"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s create a simple solution with one resolver that returns a static value.&lt;/p&gt;</description></item><item><title>Run Resolver Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/run-resolver-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/run-resolver-tutorial/</guid><description>&lt;h1 id="run-resolver-tutorial"&gt;Run Resolver Tutorial&lt;a class="anchor" href="#run-resolver-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers the &lt;code&gt;scafctl run resolver&lt;/code&gt; command — a debugging and inspection tool for executing resolvers without running actions. You&amp;rsquo;ll learn how to run all resolvers, target specific resolvers, inspect execution metadata, skip phases, and visualize dependencies.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Familiarity with &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/resolver-tutorial/"&gt;resolvers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A solution file with defined resolvers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#run-all-resolvers"&gt;Run All Resolvers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#run-specific-resolvers"&gt;Run Specific Resolvers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#execution-metadata"&gt;Execution Metadata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#skipping-phases"&gt;Skipping Phases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#dependency-graph"&gt;Dependency Graph&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#snapshots"&gt;Snapshots&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#output-formats"&gt;Output Formats&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#debugging-dependencies"&gt;Debugging Dependencies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#working-with-parameters"&gt;Working with Parameters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-workflows"&gt;Common Workflows&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;blockquote class='book-hint note'&gt;
&lt;p&gt;&lt;strong&gt;A note on &lt;code&gt;__execution&lt;/code&gt; metadata&lt;/strong&gt;: When using JSON or YAML output, &lt;code&gt;run resolver&lt;/code&gt; automatically includes an &lt;code&gt;__execution&lt;/code&gt; key containing execution metadata (timing, dependency graph, provider stats). Throughout this tutorial, examples use &lt;code&gt;--hide-execution&lt;/code&gt; to keep output focused on resolver values. See &lt;a href="#execution-metadata"&gt;Execution Metadata&lt;/a&gt;
 for details on this feature.&lt;/p&gt;</description></item><item><title>Run Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/run-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/run-provider-tutorial/</guid><description>&lt;h1 id="run-provider-tutorial"&gt;Run Provider Tutorial&lt;a class="anchor" href="#run-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers the &lt;code&gt;scafctl run provider&lt;/code&gt; command — a tool for executing individual providers directly without a solution or resolver file. This is useful for testing, debugging, and exploring providers in isolation.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Familiarity with &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-reference/"&gt;providers&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#basic-usage"&gt;Basic Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#passing-inputs"&gt;Passing Inputs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#file-based-inputs"&gt;File-Based Inputs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#capabilities"&gt;Capabilities&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#dry-run"&gt;Dry Run&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#output-formats"&gt;Output Formats&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#plugin-providers"&gt;Plugin Providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#discovering-providers"&gt;Discovering Providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-examples"&gt;Common Examples&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="basic-usage"&gt;Basic Usage&lt;a class="anchor" href="#basic-usage"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;scafctl run provider&lt;/code&gt; command takes a provider name as its first argument. Provider inputs can be passed as positional &lt;code&gt;key=value&lt;/code&gt; arguments or via the traditional &lt;code&gt;--input&lt;/code&gt; flag:&lt;/p&gt;</description></item><item><title>Actions Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/actions-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/actions-tutorial/</guid><description>&lt;h1 id="actions-tutorial"&gt;Actions Tutorial&lt;a class="anchor" href="#actions-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial introduces the Actions feature in scafctl, which enables executing side-effect operations as a declarative action graph.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Actions are the execution phase of a scafctl solution. While &lt;strong&gt;resolvers&lt;/strong&gt; compute and gather data, &lt;strong&gt;actions&lt;/strong&gt; perform work based on that data.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Resolvers&amp;lt;br/&amp;gt;(compute)&amp;#34;] --&amp;gt; B[&amp;#34;Actions&amp;lt;br/&amp;gt;(execute)&amp;#34;] --&amp;gt; C[&amp;#34;Results&amp;lt;br/&amp;gt;(outputs)&amp;#34;]&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Key Principles:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resolvers compute data, actions perform work&lt;/li&gt;
&lt;li&gt;All resolvers evaluate before any action executes&lt;/li&gt;
&lt;li&gt;Actions can depend on other actions&lt;/li&gt;
&lt;li&gt;Actions can access results from completed actions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-start"&gt;Quick Start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="1-hello-world"&gt;1. Hello World&lt;a class="anchor" href="#1-hello-world"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The simplest action workflow. Create a file called &lt;code&gt;hello-actions.yaml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Authentication Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-tutorial/</guid><description>&lt;h1 id="authentication-tutorial"&gt;Authentication Tutorial&lt;a class="anchor" href="#authentication-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through setting up and using authentication in scafctl. You&amp;rsquo;ll learn how to authenticate with Microsoft Entra ID, GitHub, and Google Cloud Platform, manage credentials, and use authenticated HTTP requests in your solutions.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;For Entra: Access to a Microsoft Entra ID tenant&lt;/li&gt;
&lt;li&gt;For GitHub: A GitHub account (or GitHub Enterprise Server instance)&lt;/li&gt;
&lt;li&gt;For GCP: A Google Cloud account&lt;/li&gt;
&lt;li&gt;A web browser for completing the device code flow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#understanding-auth-in-scafctl"&gt;Understanding Auth in scafctl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#logging-in"&gt;Logging In&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#example-output"&gt;Entra Device Code Flow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#service-principal-authentication-cicd"&gt;Entra Service Principal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#workload-identity-authentication-kubernetes"&gt;Entra Workload Identity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#github-device-code-flow"&gt;GitHub Device Code Flow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#github-pat-authentication-cicd"&gt;GitHub PAT Flow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#github-interactive-flow-browser-oauth--pkce"&gt;GitHub Interactive Flow (Browser OAuth + PKCE)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#github-app-installation-token"&gt;GitHub App Installation Token&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#gcp-interactive-login-browser-oauth"&gt;GCP Interactive Login&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#gcp-service-account-key-authentication-cicd"&gt;GCP Service Account Key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#gcp-workload-identity-federation"&gt;GCP Workload Identity Federation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#gcp-metadata-server-gcegkecloud-run"&gt;GCP Metadata Server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#checking-auth-status"&gt;Checking Auth Status&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#listing-and-sorting-cached-tokens"&gt;Listing and Sorting Cached Tokens&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-auth-in-http-providers"&gt;Using Auth in HTTP Providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#getting-tokens-for-debugging"&gt;Getting Tokens for Debugging&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#configuration"&gt;Configuration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#logging-out"&gt;Logging Out&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#auth-diagnostics"&gt;Auth Diagnostics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#troubleshooting"&gt;Troubleshooting&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="understanding-auth-in-scafctl"&gt;Understanding Auth in scafctl&lt;a class="anchor" href="#understanding-auth-in-scafctl"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Authentication in scafctl follows these principles:&lt;/p&gt;</description></item><item><title>Docker Credential Helper Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/credential-helper-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/credential-helper-tutorial/</guid><description>&lt;h1 id="docker-credential-helper-tutorial"&gt;Docker Credential Helper Tutorial&lt;a class="anchor" href="#docker-credential-helper-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial shows how to use scafctl as a Docker/Podman credential helper, exposing scafctl&amp;rsquo;s AES-256-GCM encrypted credential store to the container ecosystem.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Docker, Podman, or Buildah installed&lt;/li&gt;
&lt;li&gt;Familiarity with &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-tutorial/"&gt;Authentication Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#quick-setup"&gt;Quick Setup&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#manual-setup"&gt;Manual Setup&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#per-registry-configuration"&gt;Per-Registry Configuration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#how-it-works"&gt;How It Works&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-with-podmanbuildah"&gt;Using with Podman/Buildah&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#verification"&gt;Verification&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#composing-with-catalog-login"&gt;Composing with catalog login&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#uninstall"&gt;Uninstall&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#troubleshooting"&gt;Troubleshooting&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Docker credential helper protocol allows external programs to manage registry credentials for Docker, Podman, and Buildah. By using scafctl as a credential helper, you get:&lt;/p&gt;</description></item><item><title>GCP Custom OAuth Client Setup</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/gcp-custom-oauth-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/gcp-custom-oauth-tutorial/</guid><description>&lt;h1 id="gcp-custom-oauth-client-setup"&gt;GCP Custom OAuth Client Setup&lt;a class="anchor" href="#gcp-custom-oauth-client-setup"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;By default, &lt;code&gt;scafctl auth login gcp&lt;/code&gt; runs a native browser OAuth flow using Google&amp;rsquo;s well-known ADC client credentials — the same ones used by &lt;code&gt;gcloud auth application-default login&lt;/code&gt;. This works out of the box with &lt;strong&gt;no gcloud installation required&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You may want to set up your own OAuth client if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your organization restricts which OAuth client IDs are allowed&lt;/li&gt;
&lt;li&gt;You need specific OAuth consent screen branding or approval&lt;/li&gt;
&lt;li&gt;You want full control over the client lifecycle and scopes&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class='book-hint caution'&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you were previously seeing &lt;code&gt;invalid_grant - reauth related error (invalid_rapt)&lt;/code&gt; errors, upgrading scafctl to the latest version resolves this — the native browser OAuth flow is no longer affected by gcloud&amp;rsquo;s RAPT token expiry.&lt;/p&gt;</description></item><item><title>Eval Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/eval-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/eval-tutorial/</guid><description>&lt;h1 id="eval-tutorial"&gt;Eval Tutorial&lt;a class="anchor" href="#eval-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using the &lt;code&gt;scafctl eval&lt;/code&gt; command group to test CEL expressions, render Go templates, and validate solution files — all without running a full solution.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;eval&lt;/code&gt; commands are developer tools for quick iteration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;eval cel&lt;/code&gt;&lt;/strong&gt; — Evaluate CEL expressions with inline or file-based data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;eval template&lt;/code&gt;&lt;/strong&gt; — Render Go templates against JSON/YAML data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For solution file validation, use the separate &lt;strong&gt;&lt;code&gt;scafctl lint&lt;/code&gt;&lt;/strong&gt; command (covered in &lt;a href="#3-validating-solution-files-with-scafctl-lint"&gt;Section 3&lt;/a&gt;
 below).&lt;/p&gt;</description></item><item><title>Linting Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/linting-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/linting-tutorial/</guid><description>&lt;h1 id="linting-tutorial"&gt;Linting Tutorial&lt;a class="anchor" href="#linting-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using scafctl&amp;rsquo;s lint commands to validate solution files, explore available lint rules, and understand how to fix issues.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl includes a built-in linter that checks solution YAML files for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Schema violations&lt;/strong&gt; — Invalid field names, wrong types, missing required fields&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best practices&lt;/strong&gt; — Missing descriptions, unused resolvers, naming conventions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Correctness&lt;/strong&gt; — Broken resolver references, invalid CEL expressions, circular dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Solution&amp;lt;br/&amp;gt;YAML&amp;#34;] --&amp;gt; B[&amp;#34;scafctl&amp;lt;br/&amp;gt;lint&amp;#34;] --&amp;gt; C[&amp;#34;Findings&amp;lt;br/&amp;gt;(warnings, errors)&amp;#34;]&lt;/pre&gt;&lt;h2 id="1-linting-a-solution"&gt;1. Linting a Solution&lt;a class="anchor" href="#1-linting-a-solution"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="basic-lint"&gt;Basic Lint&lt;a class="anchor" href="#basic-lint"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="book-tabs"&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-0" checked="checked" /&gt;&lt;label for="tabs-0-0"&gt;Bash&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl lint -f solution.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-1" /&gt;&lt;label for="tabs-0-1"&gt;PowerShell&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl lint &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If your solution file is in a well-known location (&lt;code&gt;solution.yaml&lt;/code&gt;, &lt;code&gt;scafctl.yaml&lt;/code&gt;, etc. in the current directory or &lt;code&gt;scafctl/&lt;/code&gt;/&lt;code&gt;.scafctl/&lt;/code&gt; subdirectories), you can omit &lt;code&gt;-f&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>CEL Expressions Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/cel-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/cel-tutorial/</guid><description>&lt;h1 id="cel-expressions-tutorial"&gt;CEL Expressions Tutorial&lt;a class="anchor" href="#cel-expressions-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using CEL (Common Expression Language) expressions in scafctl for data transformation, conditional logic, and dynamic configuration.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CEL is used throughout scafctl for dynamic evaluation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Resolver transforms&lt;/strong&gt; — Compute derived values from other resolvers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action inputs&lt;/strong&gt; — Build dynamic commands and configurations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditions&lt;/strong&gt; — Conditionally skip actions with &lt;code&gt;when&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;forEach&lt;/strong&gt; — Generate iteration lists dynamically&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Resolver&amp;lt;br/&amp;gt;Data&amp;#34;] -- &amp;#34;_ namespace&amp;#34; --&amp;gt; B[&amp;#34;CEL&amp;lt;br/&amp;gt;Expression&amp;#34;] --&amp;gt; C[&amp;#34;Result&amp;lt;br/&amp;gt;Value&amp;#34;]&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Key principle:&lt;/strong&gt; In CEL expressions, all resolved values are available under the &lt;code&gt;_&lt;/code&gt; namespace (e.g., &lt;code&gt;_.appName&lt;/code&gt;, &lt;code&gt;_.config.port&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>REST API Server Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/api-server-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/api-server-tutorial/</guid><description>&lt;h1 id="rest-api-server"&gt;REST API Server&lt;a class="anchor" href="#rest-api-server"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;scafctl includes a built-in REST API server that exposes all major CLI features as HTTP endpoints. The server uses &lt;a href="https://github.com/go-chi/chi" target="_blank" rel="noopener noreferrer"&gt;chi&lt;/a&gt;
 for routing and &lt;a href="https://huma.rocks" target="_blank" rel="noopener noreferrer"&gt;Huma&lt;/a&gt;
 for OpenAPI-compliant endpoint registration.&lt;/p&gt;
&lt;h2 id="starting-the-server"&gt;Starting the Server&lt;a class="anchor" href="#starting-the-server"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Start with defaults (port 8080, host 127.0.0.1)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl serve
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Start on a custom port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl serve --port &lt;span style="color:#a5d6ff"&gt;9090&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Start with TLS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl serve --enable-tls --tls-cert cert.pem --tls-key key.pem
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Custom API version prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl serve --api-version v2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The server reads its configuration from the &lt;code&gt;apiServer&lt;/code&gt; section of the scafctl config file:&lt;/p&gt;</description></item><item><title>Go Templates Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/go-templates-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/go-templates-tutorial/</guid><description>&lt;h1 id="go-templates-tutorial"&gt;Go Templates Tutorial&lt;a class="anchor" href="#go-templates-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using Go templates in scafctl to generate structured text output like configuration files, documentation, and code scaffolding. You&amp;rsquo;ll start with a simple template and progressively learn conditionals, loops, whitespace control, file-based templates, custom delimiters, and multi-file generation.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax&lt;/li&gt;
&lt;li&gt;Completion of the &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/resolver-tutorial/"&gt;Resolver Tutorial&lt;/a&gt;
 and &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/actions-tutorial/"&gt;Actions Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#your-first-template"&gt;Your First Template&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-conditionals"&gt;Using Conditionals&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#iterating-over-lists"&gt;Iterating Over Lists&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#iterating-over-maps"&gt;Iterating Over Maps&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#controlling-whitespace"&gt;Controlling Whitespace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#loading-templates-from-files"&gt;Loading Templates from Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-missing-keys"&gt;Handling Missing Keys&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#injecting-additional-data"&gt;Injecting Additional Data&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-custom-delimiters"&gt;Using Custom Delimiters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-tmpl-for-dynamic-inputs"&gt;Using &lt;code&gt;tmpl&lt;/code&gt; for Dynamic Inputs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#generating-multiple-files-with-foreach"&gt;Generating Multiple Files with ForEach&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#rendering-template-directories"&gt;Rendering Template Directories&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#putting-it-all-together-readme-generator"&gt;Putting It All Together: README Generator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-sprig-functions"&gt;Using Sprig Functions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#converting-data-to-hcl-with-tohcl"&gt;Converting Data to HCL with toHcl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#serializing-and-parsing-yaml-with-toyaml--fromyaml"&gt;Serializing and Parsing YAML with toYaml / fromYaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#dns-safe-strings-with-slugify--todnsstring"&gt;DNS-Safe Strings with slugify / toDnsString&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#filtering-lists-with-where--selectfield"&gt;Filtering Lists with where / selectField&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#inline-cel-with-cel"&gt;Inline CEL with cel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#debugging-template-type-errors"&gt;Debugging Template Type Errors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#discovering-available-functions"&gt;Discovering Available Functions&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl supports Go templates in two ways:&lt;/p&gt;</description></item><item><title>Catalog Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/catalog-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/catalog-tutorial/</guid><description>&lt;h1 id="catalog-tutorial"&gt;Catalog Tutorial&lt;a class="anchor" href="#catalog-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using scafctl&amp;rsquo;s local catalog to build, version, inspect, export, and share solutions. You&amp;rsquo;ll start by building your first solution into the catalog and progressively work through versioning, cleanup, air-gapped transfers, remote registries, tagging, and advanced bundling with file dependencies.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax&lt;/li&gt;
&lt;li&gt;Completion of the &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/resolver-tutorial/"&gt;Resolver Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#building-your-first-solution"&gt;Building Your First Solution&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#running-from-the-catalog"&gt;Running from the Catalog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#listing-and-inspecting"&gt;Listing and Inspecting&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#managing-multiple-versions"&gt;Managing Multiple Versions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#deleting-and-pruning"&gt;Deleting and Pruning&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#exporting-and-importing"&gt;Exporting and Importing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#tagging-artifacts"&gt;Tagging Artifacts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remote-registries"&gt;Remote Registries&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#bundling-file-dependencies"&gt;Bundling File Dependencies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#verifying-and-extracting-bundles"&gt;Verifying and Extracting Bundles&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#comparing-bundle-versions"&gt;Comparing Bundle Versions&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="building-your-first-solution"&gt;Building Your First Solution&lt;a class="anchor" href="#building-your-first-solution"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s build a simple solution and store it in the local catalog so you can run it by name from anywhere.&lt;/p&gt;</description></item><item><title>MCP Server Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/mcp-server-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/mcp-server-tutorial/</guid><description>&lt;h1 id="mcp-server-tutorial"&gt;MCP Server Tutorial&lt;a class="anchor" href="#mcp-server-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through setting up scafctl&amp;rsquo;s Model Context Protocol (MCP) server so that AI agents — GitHub Copilot, Claude, Cursor, Windsurf, and others — can discover and invoke scafctl tools programmatically.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and on your &lt;code&gt;$PATH&lt;/code&gt; (&lt;code&gt;scafctl version&lt;/code&gt; should work)&lt;/li&gt;
&lt;li&gt;An MCP-compatible AI client (VS Code with Copilot, Claude Desktop, Cursor, or Windsurf)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-is-the-mcp-server"&gt;What Is the MCP Server?&lt;a class="anchor" href="#what-is-the-mcp-server"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The MCP server is a &lt;strong&gt;local process&lt;/strong&gt; that translates between the AI agent&amp;rsquo;s JSON-RPC protocol and scafctl&amp;rsquo;s Go library functions. When an AI agent decides to use a tool (e.g., &amp;ldquo;lint this solution&amp;rdquo;), it sends a structured request to the MCP server, which calls the same code that the CLI commands use and returns structured JSON results.&lt;/p&gt;</description></item><item><title>Security Hardening</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/security-hardening/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/security-hardening/</guid><description>&lt;h1 id="security-hardening-guide"&gt;Security Hardening Guide&lt;a class="anchor" href="#security-hardening-guide"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This guide covers scafctl&amp;rsquo;s built-in security protections and how to configure them for production environments.&lt;/p&gt;
&lt;h2 id="http-provider-security"&gt;HTTP Provider Security&lt;a class="anchor" href="#http-provider-security"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="response-body-size-limits"&gt;Response Body Size Limits&lt;a class="anchor" href="#response-body-size-limits"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The HTTP provider limits the amount of data it will read from any single response to prevent denial-of-service via unbounded responses. The default limit is &lt;strong&gt;100 MB&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# config.yaml — adjust the limit&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;httpClient&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;maxResponseBodySize&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;104857600&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# 100 MB (default)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The limit applies to both direct requests &lt;strong&gt;and&lt;/strong&gt; each page in paginated requests. If a response exceeds the limit, the provider returns an error rather than consuming unbounded memory.&lt;/p&gt;</description></item><item><title>REST API Server Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/serve-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/serve-tutorial/</guid><description>&lt;h1 id="rest-api-server-tutorial"&gt;REST API Server Tutorial&lt;a class="anchor" href="#rest-api-server-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through starting scafctl&amp;rsquo;s REST API server and interacting with its endpoints. The API mirrors all major CLI features — solutions, providers, catalogs, schemas, eval, config, and more — over HTTP with OpenAPI documentation.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and on your &lt;code&gt;$PATH&lt;/code&gt; (&lt;code&gt;scafctl version&lt;/code&gt; should work)&lt;/li&gt;
&lt;li&gt;curl or any HTTP client for testing&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-start"&gt;Quick Start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="start-the-server"&gt;Start the Server&lt;a class="anchor" href="#start-the-server"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl serve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The server starts on &lt;code&gt;http://localhost:8080&lt;/code&gt; by default.&lt;/p&gt;</description></item><item><title>Validation Patterns Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/validation-patterns-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/validation-patterns-tutorial/</guid><description>&lt;h1 id="validation-patterns-tutorial"&gt;Validation Patterns Tutorial&lt;a class="anchor" href="#validation-patterns-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Learn how to validate resolver outputs, enforce constraints on inputs, and use schema validation to catch issues early.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl offers multiple validation layers that work together to ensure configuration correctness:&lt;/p&gt;
&lt;pre class="mermaid"&gt;block-beta
 columns 4
 block:top:4
 A[&amp;#34;Solution YAML&amp;#34;]
 end
 B[&amp;#34;Lint&amp;lt;br/&amp;gt;Rules&amp;#34;] C[&amp;#34;Schema&amp;lt;br/&amp;gt;Helper Tags&amp;#34;] D[&amp;#34;Validate&amp;lt;br/&amp;gt;Provider&amp;#34;] E[&amp;#34;Result&amp;lt;br/&amp;gt;Schema&amp;#34;]
 block:bottom:4
 F[&amp;#34;Runtime Validation (CEL + Regex)&amp;#34;]
 end&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Schema helper tags&lt;/strong&gt; — provider-level input constraints (type, length, pattern, enum)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validation provider&lt;/strong&gt; — runtime regex and CEL-based checks on resolver values&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Result schemas&lt;/strong&gt; — JSON Schema validation of action outputs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lint rules&lt;/strong&gt; — static analysis at &lt;code&gt;scafctl lint&lt;/code&gt; time&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-schema-level-validation-with-provider-inputs"&gt;1. Schema-Level Validation with Provider Inputs&lt;a class="anchor" href="#1-schema-level-validation-with-provider-inputs"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Provider schemas use JSON Schema constraints to reject invalid input before execution.&lt;/p&gt;</description></item><item><title>Provider Output Shapes</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-output-shapes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-output-shapes/</guid><description>&lt;h1 id="provider-output-shapes"&gt;Provider Output Shapes&lt;a class="anchor" href="#provider-output-shapes"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Quick reference for what each built-in provider returns in resolver output — the data shape you can access via &lt;code&gt;_.resolverName&lt;/code&gt; in CEL expressions and Go templates.&lt;/p&gt;
&lt;h2 id="how-provider-output-works"&gt;How Provider Output Works&lt;a class="anchor" href="#how-provider-output-works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a resolver uses a provider, the resolved value becomes accessible to other resolvers. The &lt;strong&gt;output shape&lt;/strong&gt; determines what fields are available:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Resolver: api_data&amp;lt;br/&amp;gt;provider: http&amp;lt;br/&amp;gt;output: body, statusCode, headers&amp;#34;] --&amp;gt; B[&amp;#34;Resolver: summary&amp;lt;br/&amp;gt;expr: _.api_data&amp;lt;br/&amp;gt;.body.items | size()&amp;#34;]&lt;/pre&gt;&lt;blockquote class='book-hint note'&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use the MCP tool &lt;code&gt;get_provider_output_shape&lt;/code&gt; to query output schemas programmatically, or &lt;code&gt;get_provider_schema&lt;/code&gt; for full provider documentation.&lt;/p&gt;</description></item><item><title>Message Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/message-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/message-provider-tutorial/</guid><description>&lt;h1 id="message-provider-tutorial"&gt;Message Provider Tutorial&lt;a class="anchor" href="#message-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using the &lt;strong&gt;message&lt;/strong&gt; provider for rich terminal output during solution execution — styled messages with icons, colors, and dynamic interpolation via &lt;code&gt;tmpl:&lt;/code&gt;/&lt;code&gt;expr:&lt;/code&gt; ValueRefs.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The message provider replaces awkward &lt;code&gt;exec&lt;/code&gt; + &lt;code&gt;echo&lt;/code&gt; patterns with first-class terminal messaging that integrates with scafctl&amp;rsquo;s &lt;code&gt;--quiet&lt;/code&gt;, &lt;code&gt;--no-color&lt;/code&gt;, and &lt;code&gt;--dry-run&lt;/code&gt; flags.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Resolver&amp;lt;br/&amp;gt;Data&amp;#34;] --&amp;gt; B[&amp;#34;Message&amp;lt;br/&amp;gt;Provider&amp;#34;]
 B -- &amp;#34;styled output&amp;#34; --&amp;gt; C[&amp;#34;Terminal&amp;lt;br/&amp;gt;(stdout/stderr)&amp;#34;]
 B -- &amp;#34;data&amp;#34; --&amp;gt; D[&amp;#34;Output&amp;lt;br/&amp;gt;{success, message}&amp;#34;]&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built-in message types: &lt;code&gt;success&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;plain&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Custom styling: colors (hex or named), bold, italic, custom icons/emoji&lt;/li&gt;
&lt;li&gt;Contextual labels: dimmed &lt;code&gt;[label]&lt;/code&gt; prefixes for step tracking (e.g., &lt;code&gt;[step 2/5]&lt;/code&gt;, &lt;code&gt;[deploy]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Dynamic interpolation via framework &lt;code&gt;tmpl:&lt;/code&gt; and &lt;code&gt;expr:&lt;/code&gt; ValueRefs (with automatic dependency detection)&lt;/li&gt;
&lt;li&gt;Respects &lt;code&gt;--quiet&lt;/code&gt; flag (messages suppressed in quiet mode)&lt;/li&gt;
&lt;li&gt;Trailing newline control via the &lt;code&gt;newline&lt;/code&gt; field&lt;/li&gt;
&lt;li&gt;Dry-run awareness via &lt;code&gt;--dry-run&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-start"&gt;Quick Start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="step-1-create-the-solution-file"&gt;Step 1: Create the Solution File&lt;a class="anchor" href="#step-1-create-the-solution-file"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Create a file called &lt;code&gt;message-basics.yaml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Snapshots Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/snapshots-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/snapshots-tutorial/</guid><description>&lt;h1 id="snapshots-tutorial"&gt;Snapshots Tutorial&lt;a class="anchor" href="#snapshots-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using execution snapshots for debugging, testing, and comparing solution runs.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Snapshots capture the state of resolver execution — values, timing, status, errors, and parameters — as a JSON file. They&amp;rsquo;re useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt; — Inspect what every resolver produced&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt; — Compare before/after to catch regressions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auditing&lt;/strong&gt; — Record what ran and what it produced&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharing&lt;/strong&gt; — Send a snapshot to a teammate for review (with redaction for secrets)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;render&amp;lt;br/&amp;gt;solution&amp;#34;] --&amp;gt; B[&amp;#34;Snapshot&amp;lt;br/&amp;gt;(JSON)&amp;#34;] --&amp;gt; C[&amp;#34;show / diff&amp;lt;br/&amp;gt;commands&amp;#34;]&lt;/pre&gt;&lt;h2 id="when-to-use-snapshots"&gt;When to Use Snapshots&lt;a class="anchor" href="#when-to-use-snapshots"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Snapshots are &lt;strong&gt;flag-triggered&lt;/strong&gt; (&lt;code&gt;--snapshot&lt;/code&gt;), never automatically created. Here are the real-world scenarios where they provide value:&lt;/p&gt;</description></item><item><title>Functional Testing</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/functional-testing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/functional-testing/</guid><description>&lt;h1 id="functional-testing"&gt;Functional Testing&lt;a class="anchor" href="#functional-testing"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Functional testing lets you define automated tests for your solutions directly in the solution YAML.
Tests execute scafctl commands in isolated sandboxes and validate output using assertions, snapshots,
and CEL expressions.&lt;/p&gt;
&lt;p&gt;This tutorial walks through every feature of &lt;code&gt;scafctl test functional&lt;/code&gt; — from basic tests to
advanced CI integration.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="writing-your-first-test"&gt;Writing Your First Test&lt;a class="anchor" href="#writing-your-first-test"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add a &lt;code&gt;testing&lt;/code&gt; section to your solution&amp;rsquo;s &lt;code&gt;spec&lt;/code&gt;. Create a file called &lt;code&gt;solution.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;apiVersion&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;scafctl.io/v1&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;kind&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;Solution&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;metadata&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;name&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;my-solution&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;spec&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;resolvers&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;greeting&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;description&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;A greeting message&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;resolve&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;with&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;- &lt;span style="color:#7ee787"&gt;provider&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;static&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;inputs&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;value&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;Hello, World!&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;testing&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;cases&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;render-basic&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;description&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;Verify solution renders successfully&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;command&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;[&lt;span style="color:#a5d6ff"&gt;render, solution]&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;assertions&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;- &lt;span style="color:#7ee787"&gt;expression&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;__exitCode == 0&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;- &lt;span style="color:#7ee787"&gt;contains&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;greeting&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the test:&lt;/p&gt;</description></item><item><title>Solution Diff Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/soldiff-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/soldiff-tutorial/</guid><description>&lt;p&gt;This tutorial covers comparing two solution files structurally to understand what changed between versions. The &lt;code&gt;soldiff&lt;/code&gt; package detects additions, removals, and modifications across metadata, resolvers, actions, and testing sections.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Solution diffing answers the question: &lt;strong&gt;&amp;ldquo;What structurally changed between two versions of a solution?&amp;rdquo;&lt;/strong&gt; Unlike &lt;code&gt;git diff&lt;/code&gt; which shows text changes, &lt;code&gt;soldiff&lt;/code&gt; understands the solution schema and reports meaningful structural differences.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌──────────────┐ ┌──────────────┐ ┌──────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ solution-v1 │ │ soldiff │ │ Result │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ .yaml │ ──► │ .Compare() │ ──► │ (changes, │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ │ │ │ summary) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ solution-v2 │ ──► │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ .yaml │ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└──────────────┘ └──────────────┘ └──────────────┘&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="when-to-use-solution-diff"&gt;When to Use Solution Diff&lt;a class="anchor" href="#when-to-use-solution-diff"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Use Case&lt;/th&gt;
 &lt;th&gt;Scenario&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Code review&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Review structural impact of solution YAML changes before merging&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Configuration drift&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Detect when a deployed solution has drifted from the expected baseline&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Refactoring validation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Confirm a refactor didn&amp;rsquo;t accidentally add/remove resolvers or actions&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Version comparison&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Compare v1 and v2 of a solution to document what changed&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cli-usage"&gt;CLI Usage&lt;a class="anchor" href="#cli-usage"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="basic-comparison"&gt;Basic Comparison&lt;a class="anchor" href="#basic-comparison"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="book-tabs"&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-0" checked="checked" /&gt;&lt;label for="tabs-0-0"&gt;Bash&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl solution diff -f solution-v1.yaml -f solution-v2.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-1" /&gt;&lt;label for="tabs-0-1"&gt;PowerShell&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl solution diff &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution-v1.&lt;span style="color:#79c0ff"&gt;yaml&lt;/span&gt; &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution-v2.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;</description></item><item><title>Dry-Run Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/dryrun-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/dryrun-tutorial/</guid><description>&lt;h1 id="dry-run-tutorial"&gt;Dry-Run Tutorial&lt;a class="anchor" href="#dry-run-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers using &lt;code&gt;--dry-run&lt;/code&gt; to preview what a solution execution would do without performing any side effects.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dry-run mode resolves all values and builds an action execution plan, but never executes actions. This gives you a complete picture of what &lt;em&gt;would&lt;/em&gt; happen:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;Solution&amp;lt;br/&amp;gt;(.yaml)&amp;#34;] --&amp;gt; B[&amp;#34;Dry-Run Generator&amp;lt;br/&amp;gt;⚠️ No side effects!&amp;#34;] --&amp;gt; C[&amp;#34;Report&amp;lt;br/&amp;gt;(resolvers, actions, phases)&amp;#34;]&lt;/pre&gt;&lt;h2 id="when-to-use-dry-run"&gt;When to Use Dry-Run&lt;a class="anchor" href="#when-to-use-dry-run"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Use Case&lt;/th&gt;
 &lt;th&gt;Scenario&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Pre-flight check&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Verify all resolvers produce expected values before executing actions&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Action plan review&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;See the execution order, phases, and dependencies before running&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;CI validation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Assert resolver outputs in a pipeline without side effects&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Debugging&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Understand why a solution behaves unexpectedly by inspecting resolved values&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Generate a report of what a solution does for review or audit&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cli-usage"&gt;CLI Usage&lt;a class="anchor" href="#cli-usage"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="dry-run-a-full-solution"&gt;Dry-Run a Full Solution&lt;a class="anchor" href="#dry-run-a-full-solution"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="book-tabs"&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-0" checked="checked" /&gt;&lt;label for="tabs-0-0"&gt;Bash&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl run solution -f solution.yaml --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-1" /&gt;&lt;label for="tabs-0-1"&gt;PowerShell&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl run solution &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution.&lt;span style="color:#79c0ff"&gt;yaml&lt;/span&gt; --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This resolves all values and shows the action plan without executing any actions.&lt;/p&gt;</description></item><item><title>Output Directory Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/output-dir-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/output-dir-tutorial/</guid><description>&lt;h1 id="output-directory-tutorial"&gt;Output Directory Tutorial&lt;a class="anchor" href="#output-directory-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using the &lt;code&gt;--output-dir&lt;/code&gt; flag to redirect action output to a specific directory. You&amp;rsquo;ll learn the phase-based directory model, how resolvers and actions differ in path handling, and how to reference the original working directory with &lt;code&gt;__cwd&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;li&gt;Completion of the &lt;a href="../getting-started/"&gt;Getting Started&lt;/a&gt;
 tutorial&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#phase-based-directory-model"&gt;Phase-Based Directory Model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#basic-usage"&gt;Basic Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-__cwd-for-original-directory-access"&gt;Using &lt;code&gt;__cwd&lt;/code&gt; for Original Directory Access&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#combining-with-dry-run"&gt;Combining with Dry-Run&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#per-provider-usage"&gt;Per-Provider Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#default-via-configuration"&gt;Default via Configuration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#absolute-paths-are-never-rewritten"&gt;Absolute Paths Are Never Rewritten&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#affected-providers"&gt;Affected Providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, actions resolve relative paths against the current working directory (CWD). The &lt;code&gt;--output-dir&lt;/code&gt; flag changes this so actions write to a designated output directory instead, while resolvers continue reading from CWD.&lt;/p&gt;</description></item><item><title>Auto-Discovery Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/auto-discovery-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/auto-discovery-tutorial/</guid><description>&lt;h1 id="auto-discovery-tutorial"&gt;Auto-Discovery Tutorial&lt;a class="anchor" href="#auto-discovery-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial explains how scafctl automatically discovers solution files, making the &lt;code&gt;-f&lt;/code&gt; flag optional for most commands.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;li&gt;Completion of the &lt;a href="../getting-started/"&gt;Getting Started&lt;/a&gt;
 tutorial&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#how-auto-discovery-works"&gt;How Auto-Discovery Works&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#search-order"&gt;Search Order&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#supported-commands"&gt;Supported Commands&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#examples"&gt;Examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#interaction-with---cwd"&gt;Interaction with &lt;code&gt;--cwd&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#when-auto-discovery-fails"&gt;When Auto-Discovery Fails&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#best-practices"&gt;Best Practices&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Many scafctl commands accept a &lt;code&gt;-f&lt;/code&gt; / &lt;code&gt;--file&lt;/code&gt; flag to specify the solution file path. When this flag is omitted, scafctl searches the current directory (or the &lt;code&gt;--cwd&lt;/code&gt; target) for a solution file using a well-defined search order.&lt;/p&gt;</description></item><item><title>Configuration Management</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/config-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/config-tutorial/</guid><description>&lt;h1 id="configuration-management-tutorial"&gt;Configuration Management Tutorial&lt;a class="anchor" href="#configuration-management-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers managing scafctl&amp;rsquo;s application configuration using the &lt;code&gt;config&lt;/code&gt; CLI commands.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl uses a YAML configuration file to control application behavior including logging, HTTP client settings, resolver timeouts, catalog locations, and more.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Command&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config init&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Create config file&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config view&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;View current config&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config get/set&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Read/write values&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config validate&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Validate config&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config schema&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;View JSON schema&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;config paths&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Show XDG paths&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="quick-start"&gt;Quick Start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="1-initialize-configuration"&gt;1. Initialize Configuration&lt;a class="anchor" href="#1-initialize-configuration"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Create a new config file:&lt;/p&gt;</description></item><item><title>File Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/file-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/file-provider-tutorial/</guid><description>&lt;h1 id="file-provider-tutorial"&gt;File Provider Tutorial&lt;a class="anchor" href="#file-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using the &lt;code&gt;file&lt;/code&gt; provider to read, write, check existence, delete files, and write multiple files at once with &lt;code&gt;write-tree&lt;/code&gt;. You&amp;rsquo;ll learn how to use conflict strategies, backups, append with deduplication, and dry-run mode.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#reading-files"&gt;Reading Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#writing-files"&gt;Writing Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#checking-file-existence"&gt;Checking File Existence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#deleting-files"&gt;Deleting Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#writing-multiple-files-write-tree"&gt;Writing Multiple Files (write-tree)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#conflict-strategies"&gt;Conflict Strategies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#append-with-deduplication"&gt;Append with Deduplication&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#backups"&gt;Backups&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#per-entry-overrides-in-write-tree"&gt;Per-Entry Overrides in write-tree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#cli-flags"&gt;CLI Flags&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#dry-run-mode"&gt;Dry-Run Mode&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="reading-files"&gt;Reading Files&lt;a class="anchor" href="#reading-files"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;read&lt;/code&gt; operation reads the contents of a file. Create a file called &lt;code&gt;read-file.yaml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Exec Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/exec-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/exec-provider-tutorial/</guid><description>&lt;h1 id="exec-provider-tutorial"&gt;Exec Provider Tutorial&lt;a class="anchor" href="#exec-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using the &lt;code&gt;exec&lt;/code&gt; provider to run shell commands cross-platform. You&amp;rsquo;ll learn how the embedded POSIX shell works, how to use pipes, environment variables, timeouts, and when to use external shells like bash or PowerShell.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;li&gt;(Optional) &lt;code&gt;bash&lt;/code&gt; and/or &lt;code&gt;pwsh&lt;/code&gt; installed for external shell examples&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#how-it-works"&gt;How It Works&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#running-simple-commands"&gt;Running Simple Commands&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#pipes-and-shell-features"&gt;Pipes and Shell Features&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#arguments"&gt;Arguments&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#environment-variables"&gt;Environment Variables&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#working-directory"&gt;Working Directory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#standard-input"&gt;Standard Input&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#timeouts"&gt;Timeouts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#shell-types"&gt;Shell Types&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#cross-platform-patterns"&gt;Cross-Platform Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#error-handling"&gt;Error Handling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="how-it-works"&gt;How It Works&lt;a class="anchor" href="#how-it-works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The exec provider uses an &lt;strong&gt;embedded POSIX shell&lt;/strong&gt; (powered by &lt;a href="https://github.com/mvdan/sh" target="_blank" rel="noopener noreferrer"&gt;mvdan.cc/sh&lt;/a&gt;
) as its default execution engine. This means:&lt;/p&gt;</description></item><item><title>Directory Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/directory-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/directory-provider-tutorial/</guid><description>&lt;h1 id="directory-provider-tutorial"&gt;Directory Provider Tutorial&lt;a class="anchor" href="#directory-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using the &lt;code&gt;directory&lt;/code&gt; provider to list, scan, create, remove, and copy directories. You&amp;rsquo;ll learn how to use filtering, recursive traversal, content reading, and checksums for filesystem-oriented workflows.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;li&gt;A local directory with some files to experiment with&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#listing-directory-contents"&gt;Listing Directory Contents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#recursive-traversal"&gt;Recursive Traversal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#filtering-with-globs-and-regex"&gt;Filtering with Globs and Regex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#reading-file-contents"&gt;Reading File Contents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#computing-checksums"&gt;Computing Checksums&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#creating-directories"&gt;Creating Directories&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#removing-directories"&gt;Removing Directories&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#copying-directories"&gt;Copying Directories&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#dry-run-mode"&gt;Dry Run Mode&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="listing-directory-contents"&gt;Listing Directory Contents&lt;a class="anchor" href="#listing-directory-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest use of the directory provider is listing files and directories in a given path. Create a file called &lt;code&gt;list-dir.yaml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Logging &amp; Debugging</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/logging-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/logging-tutorial/</guid><description>&lt;h1 id="logging--debugging-tutorial"&gt;Logging &amp;amp; Debugging Tutorial&lt;a class="anchor" href="#logging--debugging-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers controlling scafctl&amp;rsquo;s log output — verbosity, format, destination, and environment variable overrides.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, scafctl produces &lt;strong&gt;no structured log output&lt;/strong&gt;. Only styled user messages (errors, warnings, success indicators) are shown. This keeps the CLI clean for human users and pipe-friendly for scripts.&lt;/p&gt;
&lt;p&gt;When you need to see what&amp;rsquo;s happening under the hood — debugging a solution, reporting a bug, or feeding structured logs to a log aggregation system — scafctl gives you full control over log verbosity, format, and destination.&lt;/p&gt;</description></item><item><title>HCL Provider Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/hcl-provider-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/hcl-provider-tutorial/</guid><description>&lt;h1 id="hcl-provider-tutorial"&gt;HCL Provider Tutorial&lt;a class="anchor" href="#hcl-provider-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through using the &lt;code&gt;hcl&lt;/code&gt; provider to parse Terraform and OpenTofu configuration files. You&amp;rsquo;ll learn how to extract variables, resources, modules, outputs, and other block types from HCL content.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with YAML syntax and solution files&lt;/li&gt;
&lt;li&gt;Basic understanding of Terraform/OpenTofu configuration syntax&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#parsing-inline-hcl-content"&gt;Parsing Inline HCL Content&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#parsing-hcl-files"&gt;Parsing HCL Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#multi-file-and-directory-support"&gt;Multi-File and Directory Support&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#extracting-variables"&gt;Extracting Variables&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#extracting-resources"&gt;Extracting Resources&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#working-with-modules"&gt;Working with Modules&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#terraform-block-extraction"&gt;Terraform Block Extraction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#combining-with-cel-expressions"&gt;Combining with CEL Expressions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#transform-capability"&gt;Transform Capability&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#expression-handling"&gt;Expression Handling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#common-patterns"&gt;Common Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#formatting-hcl-content"&gt;Formatting HCL Content&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#validating-hcl-syntax"&gt;Validating HCL Syntax&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#generating-hcl-from-structured-data"&gt;Generating HCL from Structured Data&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#generating-terraform-json-tfjson"&gt;Generating Terraform JSON (&lt;code&gt;.tf.json&lt;/code&gt;)&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="parsing-inline-hcl-content"&gt;Parsing Inline HCL Content&lt;a class="anchor" href="#parsing-inline-hcl-content"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest way to use the HCL provider is with inline content. Create a file called &lt;code&gt;parse-hcl.yaml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Telemetry (Traces, Metrics, Logs)</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/telemetry-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/telemetry-tutorial/</guid><description>&lt;h1 id="telemetry-tutorial"&gt;Telemetry Tutorial&lt;a class="anchor" href="#telemetry-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;scafctl emits &lt;strong&gt;all three OpenTelemetry signals&lt;/strong&gt; — logs, traces, and metrics.
By default, telemetry is silent (noop providers). When you point scafctl at an
OTLP endpoint every signal is exported for backend analysis.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Signal&lt;/th&gt;
 &lt;th&gt;Default output&lt;/th&gt;
 &lt;th&gt;With &lt;code&gt;--otel-endpoint&lt;/code&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Logs&lt;/td&gt;
 &lt;td&gt;slog text/JSON → stderr (via &lt;code&gt;--log-level&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;Also batched via OTLP gRPC&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Traces&lt;/td&gt;
 &lt;td&gt;Disabled (noop)&lt;/td&gt;
 &lt;td&gt;Exported via OTLP gRPC&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Metrics&lt;/td&gt;
 &lt;td&gt;Prometheus &lt;code&gt;/metrics&lt;/code&gt; (MCP server)&lt;/td&gt;
 &lt;td&gt;Also pushed via OTLP gRPC&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="flags-per-invocation"&gt;Flags (per-invocation)&lt;a class="anchor" href="#flags-per-invocation"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="book-tabs"&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-0" checked="checked" /&gt;&lt;label for="tabs-0-0"&gt;Bash&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Point at a local OTel Collector&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl run solution -f solution.yaml &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --otel-endpoint localhost:4317 &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --otel-insecure &lt;span style="color:#8b949e;font-style:italic"&gt;# disable TLS (development only)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Override with environment variable instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/span&gt;&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;localhost:4317 &lt;span style="color:#79c0ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; scafctl run solution -f solution.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;input type="radio" class="toggle" name="tabs-0" id="tabs-0-1" /&gt;&lt;label for="tabs-0-1"&gt;PowerShell&lt;/label&gt;&lt;div class="book-tabs-content markdown-inner"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Point at a local OTel Collector&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl run solution &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution.&lt;span style="color:#79c0ff"&gt;yaml&lt;/span&gt; `
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --otel-endpoint localhost&lt;span style="color:#f85149"&gt;:&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;4317&lt;/span&gt; `
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --otel-insecure &lt;span style="color:#8b949e;font-style:italic"&gt;# disable TLS (development only)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# Override with environment variable instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;$env:OTEL_EXPORTER_OTLP_ENDPOINT&lt;/span&gt; = &lt;span style="color:#a5d6ff"&gt;&amp;#39;localhost:4317&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scafctl run solution &lt;span style="color:#ff7b72;font-weight:bold"&gt;-f&lt;/span&gt; solution.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Flag&lt;/th&gt;
 &lt;th&gt;Env override&lt;/th&gt;
 &lt;th&gt;Default&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--otel-endpoint&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;em&gt;(none)&lt;/em&gt;&lt;/td&gt;
 &lt;td&gt;OTLP gRPC endpoint. When unset, tracing is disabled (noop).&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;--otel-insecure&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;em&gt;(none)&lt;/em&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Skip TLS verification. Use in local dev only.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="signals-in-detail"&gt;Signals in Detail&lt;a class="anchor" href="#signals-in-detail"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="logs"&gt;Logs&lt;a class="anchor" href="#logs"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Logs use the &lt;code&gt;go-logr/logr&lt;/code&gt; interface throughout the codebase. The underlying
sink is a &lt;code&gt;multiSink&lt;/code&gt; that fans out to:&lt;/p&gt;</description></item><item><title>Template Directory Rendering</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/template-directory-rendering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/template-directory-rendering/</guid><description>&lt;h1 id="template-directory-rendering-tutorial"&gt;Template Directory Rendering Tutorial&lt;a class="anchor" href="#template-directory-rendering-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks you through the recommended pattern for rendering a directory
tree of Go templates into output files while preserving the directory structure.
You&amp;rsquo;ll learn how to combine three providers — &lt;code&gt;directory&lt;/code&gt;, &lt;code&gt;go-template&lt;/code&gt;, and
&lt;code&gt;file&lt;/code&gt; — in a single solution to scaffold entire projects from templates.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl installed and available in your PATH&lt;/li&gt;
&lt;li&gt;Basic familiarity with solution files and Go template syntax&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;a class="anchor" href="#table-of-contents"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#setting-up-templates"&gt;Setting Up Templates&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#reading-templates-with-the-directory-provider"&gt;Reading Templates with the Directory Provider&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#batch-rendering-with-render-tree"&gt;Batch Rendering with render-tree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#writing-files-with-write-tree"&gt;Writing Files with write-tree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#path-transformation-with-outputpath"&gt;Path Transformation with outputPath&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#putting-it-all-together"&gt;Putting It All Together&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#advanced-patterns"&gt;Advanced Patterns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A common scaffolding task is:&lt;/p&gt;</description></item><item><title>Cache Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/cache-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/cache-tutorial/</guid><description>&lt;h1 id="managing-the-cache"&gt;Managing the Cache&lt;a class="anchor" href="#managing-the-cache"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial covers how to use scafctl&amp;rsquo;s cache management commands to view and clear cached data.&lt;/p&gt;
&lt;h2 id="what-is-cached"&gt;What is Cached?&lt;a class="anchor" href="#what-is-cached"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;scafctl caches certain data to improve performance:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Cache Type&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;th&gt;Use Case&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;HTTP Cache&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Responses from HTTP provider requests&lt;/td&gt;
 &lt;td&gt;Avoid repeated network calls&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Build Cache&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Incremental build fingerprints&lt;/td&gt;
 &lt;td&gt;Skip unchanged solution rebuilds&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Remote Artifact Cache&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Auto-cached artifacts from remote catalogs&lt;/td&gt;
 &lt;td&gt;Offline access to previously fetched solutions&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Caching reduces network latency, speeds up builds, and allows offline access to previously fetched resources.&lt;/p&gt;</description></item><item><title>Provider Reference</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-reference/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-reference/</guid><description>&lt;h1 id="provider-reference"&gt;Provider Reference&lt;a class="anchor" href="#provider-reference"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This document provides a reference for all built-in providers in scafctl.&lt;/p&gt;
&lt;blockquote class='book-hint tip'&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All YAML examples in this reference show only the relevant resolver or action snippet. To use them, place each snippet inside a complete solution file with &lt;code&gt;apiVersion&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt;, &lt;code&gt;metadata&lt;/code&gt;, and &lt;code&gt;spec&lt;/code&gt; sections. See the &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/getting-started/"&gt;Getting Started&lt;/a&gt;
 tutorial for the full solution structure.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Providers are execution primitives used by resolvers and actions. Each provider has &lt;strong&gt;capabilities&lt;/strong&gt; that determine where it can be used:&lt;/p&gt;</description></item><item><title>Extension Concepts</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/extension-concepts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/extension-concepts/</guid><description>&lt;h1 id="extension-concepts"&gt;Extension Concepts&lt;a class="anchor" href="#extension-concepts"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;scafctl is built on two types of &lt;strong&gt;extensions&lt;/strong&gt;: &lt;strong&gt;providers&lt;/strong&gt; and &lt;strong&gt;auth handlers&lt;/strong&gt;. Each can be delivered as a &lt;strong&gt;builtin&lt;/strong&gt; (compiled into the scafctl binary) or as a &lt;strong&gt;plugin&lt;/strong&gt; (a standalone binary communicating over gRPC).&lt;/p&gt;
&lt;p&gt;This page defines the core terminology and links to the detailed development guides.&lt;/p&gt;
&lt;h2 id="terminology"&gt;Terminology&lt;a class="anchor" href="#terminology"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Term&lt;/th&gt;
 &lt;th&gt;Definition&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A stateless execution unit that performs a single operation: fetching data (&lt;code&gt;from&lt;/code&gt;), transforming values (&lt;code&gt;transform&lt;/code&gt;), validating inputs (&lt;code&gt;validation&lt;/code&gt;), executing side effects (&lt;code&gt;action&lt;/code&gt;), or authenticating requests (&lt;code&gt;authentication&lt;/code&gt;). Providers are the building blocks used inside solution resolvers.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Auth Handler&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A stateful authentication manager that handles identity verification, credential storage, token acquisition, and request injection. Auth handlers manage OAuth flows, cache tokens across invocations, and are used by providers (like &lt;code&gt;http&lt;/code&gt;) to authenticate outgoing requests.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Builtin&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;An extension compiled directly into the scafctl binary. Builtin extensions are registered at startup and require no external binaries. Contributing a builtin extension means adding code to the scafctl repository.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Plugin&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;An extension delivered as a standalone executable that communicates with scafctl over gRPC using &lt;a href="https://github.com/hashicorp/go-plugin" target="_blank" rel="noopener noreferrer"&gt;hashicorp/go-plugin&lt;/a&gt;
. Plugins run as separate processes, can be written in any gRPC-capable language, and are distributed independently via OCI catalogs, Go modules, or binary releases.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Extension&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Umbrella term for any provider or auth handler, whether builtin or plugin.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Capability&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A declared feature of a provider (e.g., &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;action&lt;/code&gt;) or auth handler (e.g., &lt;code&gt;scopes_on_login&lt;/code&gt;, &lt;code&gt;tenant_id&lt;/code&gt;). Capabilities let scafctl adapt behavior dynamically without hardcoded knowledge of each extension.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="extension-matrix"&gt;Extension Matrix&lt;a class="anchor" href="#extension-matrix"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Builtin&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Plugin&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Compiled into scafctl; 16 built-in providers (http, cel, exec&amp;hellip;)&lt;/td&gt;
 &lt;td&gt;Standalone gRPC binary; auto-fetched from OCI catalogs&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Auth Handler&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Compiled into scafctl; 3 built-in handlers (entra, github, gcp)&lt;/td&gt;
 &lt;td&gt;Standalone gRPC binary; auto-fetched from OCI catalogs&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="when-to-choose-builtin-vs-plugin"&gt;When to Choose Builtin vs Plugin&lt;a class="anchor" href="#when-to-choose-builtin-vs-plugin"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Factor&lt;/th&gt;
 &lt;th&gt;Builtin&lt;/th&gt;
 &lt;th&gt;Plugin&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Ships with scafctl&lt;/td&gt;
 &lt;td&gt;Distributed independently&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Go only&lt;/td&gt;
 &lt;td&gt;Any language with gRPC support&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Dependency management&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Part of scafctl&amp;rsquo;s &lt;code&gt;go.mod&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Isolated dependencies&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Process isolation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Runs in-process&lt;/td&gt;
 &lt;td&gt;Separate process (crash isolation)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Update cycle&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Tied to scafctl releases&lt;/td&gt;
 &lt;td&gt;Independent release cadence&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Use case&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Core functionality, general-purpose&lt;/td&gt;
 &lt;td&gt;Third-party integrations, proprietary logic&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Contributing&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;PR to scafctl repo&lt;/td&gt;
 &lt;td&gt;Publish to any OCI registry&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences-providers-vs-auth-handlers"&gt;Key Differences: Providers vs Auth Handlers&lt;a class="anchor" href="#key-differences-providers-vs-auth-handlers"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Aspect&lt;/th&gt;
 &lt;th&gt;Provider&lt;/th&gt;
 &lt;th&gt;Auth Handler&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;2 methods: &lt;code&gt;Descriptor()&lt;/code&gt;, &lt;code&gt;Execute()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;8+ methods: &lt;code&gt;Login()&lt;/code&gt;, &lt;code&gt;Logout()&lt;/code&gt;, &lt;code&gt;Status()&lt;/code&gt;, &lt;code&gt;GetToken()&lt;/code&gt;, &lt;code&gt;InjectAuth()&lt;/code&gt;, &amp;hellip;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Stateless — each execution is independent&lt;/td&gt;
 &lt;td&gt;Stateful — manages cached tokens, refresh tokens, sessions&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Solution resolvers (via &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt;, etc.)&lt;/td&gt;
 &lt;td&gt;Providers (e.g., &lt;code&gt;http&lt;/code&gt; provider calls &lt;code&gt;InjectAuth()&lt;/code&gt; on requests)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Registry&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;provider.Registry&lt;/code&gt; (versioned, overwrite-protected)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;auth.Registry&lt;/code&gt; (name-keyed)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;from&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;validation&lt;/code&gt;, &lt;code&gt;action&lt;/code&gt;, &lt;code&gt;authentication&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;scopes_on_login&lt;/code&gt;, &lt;code&gt;scopes_on_token_request&lt;/code&gt;, &lt;code&gt;tenant_id&lt;/code&gt;, &lt;code&gt;hostname&lt;/code&gt;, &lt;code&gt;federated_token&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Plugin artifact kind&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;provider&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;auth-handler&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="plugin-communication"&gt;Plugin Communication&lt;a class="anchor" href="#plugin-communication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both provider plugins and auth handler plugins use &lt;a href="https://github.com/hashicorp/go-plugin" target="_blank" rel="noopener noreferrer"&gt;hashicorp/go-plugin&lt;/a&gt;
 with gRPC:&lt;/p&gt;</description></item><item><title>Provider Development Guide</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-development/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-development/</guid><description>&lt;h1 id="provider-development-guide"&gt;Provider Development Guide&lt;a class="anchor" href="#provider-development-guide"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This guide explains how to create custom providers for scafctl. Providers are the building blocks that perform operations like fetching data, transforming values, validating inputs, and executing actions.&lt;/p&gt;
&lt;p&gt;Providers can be delivered in two ways:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Builtin&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Plugin&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Where it lives&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Compiled into the scafctl binary&lt;/td&gt;
 &lt;td&gt;Separate executable (any language with gRPC)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Registration&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;registry.Register(...)&lt;/code&gt; in &lt;code&gt;builtin.go&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Discovered at runtime from plugin cache or catalog&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Crash isolation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Shares process with scafctl&lt;/td&gt;
 &lt;td&gt;Isolated process — plugin crash doesn&amp;rsquo;t take down CLI&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Ships with scafctl releases&lt;/td&gt;
 &lt;td&gt;OCI catalog artifact (&lt;code&gt;kind: provider&lt;/code&gt;) or standalone binary&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;provider.Provider&lt;/code&gt; (2 methods)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;plugin.ProviderPlugin&lt;/code&gt; (3 methods)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote class='book-hint warning'&gt;
&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;: Read the &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/extension-concepts/"&gt;Extension Concepts&lt;/a&gt;
 page for terminology (provider vs plugin vs auth handler).&lt;/p&gt;</description></item><item><title>Auth Handler Development Guide</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-handler-development/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-handler-development/</guid><description>&lt;h1 id="auth-handler-development-guide"&gt;Auth Handler Development Guide&lt;a class="anchor" href="#auth-handler-development-guide"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This guide explains how to create custom auth handlers for scafctl. Auth handlers manage identity verification, credential storage, and token acquisition for identity providers (e.g., Entra ID, GitHub, GCP, Okta, AWS SSO).&lt;/p&gt;
&lt;p&gt;Auth handlers can be delivered in two ways:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Builtin&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Plugin&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Where it lives&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Compiled into the scafctl binary&lt;/td&gt;
 &lt;td&gt;Separate executable (any language with gRPC)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Registration&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;authRegistry.Register(...)&lt;/code&gt; in &lt;code&gt;root.go&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Discovered at runtime from plugin cache or catalog&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Credential storage&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Uses &lt;code&gt;pkg/secrets&lt;/code&gt; (OS keychain)&lt;/td&gt;
 &lt;td&gt;Plugin manages its own credential storage&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Crash isolation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Shares process with scafctl&lt;/td&gt;
 &lt;td&gt;Isolated process — plugin crash doesn&amp;rsquo;t take down CLI&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Ships with scafctl releases&lt;/td&gt;
 &lt;td&gt;OCI catalog artifact (&lt;code&gt;kind: auth-handler&lt;/code&gt;) or standalone binary&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;auth.Handler&lt;/code&gt; (8 methods)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;plugin.AuthHandlerPlugin&lt;/code&gt; (7 methods)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote class='book-hint warning'&gt;
&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;: Read the &lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/extension-concepts/"&gt;Extension Concepts&lt;/a&gt;
 page for terminology (provider vs auth handler vs plugin).&lt;/p&gt;</description></item><item><title>Plugin Development Guide</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/plugin-development/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/plugin-development/</guid><description>&lt;h1 id="plugin-development-guide"&gt;Plugin Development Guide&lt;a class="anchor" href="#plugin-development-guide"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint note'&gt;
&lt;p&gt;&lt;strong&gt;This page is an overview.&lt;/strong&gt; Detailed plugin development instructions are now part of each extension type&amp;rsquo;s development guide.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id="what-is-a-plugin"&gt;What is a Plugin?&lt;a class="anchor" href="#what-is-a-plugin"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A plugin is a standalone executable that extends scafctl by communicating over gRPC using &lt;a href="https://github.com/hashicorp/go-plugin" target="_blank" rel="noopener noreferrer"&gt;hashicorp/go-plugin&lt;/a&gt;
. Plugins run in separate processes, providing crash isolation and independent distribution.&lt;/p&gt;
&lt;p&gt;scafctl supports two types of plugins:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Plugin Type&lt;/th&gt;
 &lt;th&gt;Artifact Kind&lt;/th&gt;
 &lt;th&gt;Interface&lt;/th&gt;
 &lt;th&gt;Guide&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Provider Plugin&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;provider&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;plugin.ProviderPlugin&lt;/code&gt; (3 methods)&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/provider-development/#delivering-as-a-plugin"&gt;Provider Development Guide — Delivering as a Plugin&lt;/a&gt;
&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Auth Handler Plugin&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;auth-handler&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;plugin.AuthHandlerPlugin&lt;/code&gt; (7 methods)&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://oakwood-commons.github.io/scafctl/docs/tutorials/auth-handler-development/#delivering-as-a-plugin"&gt;Auth Handler Development Guide — Delivering as a Plugin&lt;/a&gt;
&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;a class="anchor" href="#architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[&amp;#34;scafctl&amp;lt;br/&amp;gt;- Discovers plugin&amp;lt;br/&amp;gt;- Calls extension&amp;lt;br/&amp;gt;- Manages lifecycle&amp;#34;] &amp;lt;-- &amp;#34;gRPC&amp;#34; --&amp;gt; B[&amp;#34;Your Plugin&amp;lt;br/&amp;gt;- Implements gRPC&amp;lt;br/&amp;gt;- Exposes handlers&amp;lt;br/&amp;gt;- Handles execution&amp;#34;]&lt;/pre&gt;&lt;p&gt;Each plugin binary exposes &lt;strong&gt;one&lt;/strong&gt; extension type (provider OR auth handler). The handshake cookie determines which type the host expects.&lt;/p&gt;</description></item><item><title>Plugin Auto-Fetching</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/plugin-auto-fetch-tutorial/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/plugin-auto-fetch-tutorial/</guid><description>&lt;h1 id="plugin-auto-fetching-from-catalogs"&gt;Plugin Auto-Fetching from Catalogs&lt;a class="anchor" href="#plugin-auto-fetching-from-catalogs"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial explains how scafctl automatically fetches plugin binaries from remote catalogs at runtime. You can declare plugin dependencies in your solution, and scafctl will resolve, download, cache, and load them without a prior build step.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The plugin auto-fetch flow:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Solution declares Catalog chain Plugin cache Provider
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;plugin dependencies → resolves version → checks cache → registration
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (local → remote) (cache hit/miss) (gRPC plugin)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Declare&lt;/strong&gt; plugin dependencies in your solution&amp;rsquo;s &lt;code&gt;bundle.plugins&lt;/code&gt; section&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resolve&lt;/strong&gt; — scafctl looks up the plugin version in the catalog chain (local first, then remote OCI registries)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache&lt;/strong&gt; — if the binary is already cached locally, it&amp;rsquo;s reused; otherwise it&amp;rsquo;s fetched and written to the cache&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Load&lt;/strong&gt; — the cached binary is launched as a gRPC plugin and its providers are registered&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="declaring-plugin-dependencies"&gt;Declaring Plugin Dependencies&lt;a class="anchor" href="#declaring-plugin-dependencies"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add a &lt;code&gt;bundle.plugins&lt;/code&gt; section to your solution:&lt;/p&gt;</description></item><item><title>Multi-Platform Plugin Build Tutorial</title><link>https://oakwood-commons.github.io/scafctl/docs/tutorials/multi-platform-plugin-build/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://oakwood-commons.github.io/scafctl/docs/tutorials/multi-platform-plugin-build/</guid><description>&lt;h1 id="multi-platform-plugin-build-tutorial"&gt;Multi-Platform Plugin Build Tutorial&lt;a class="anchor" href="#multi-platform-plugin-build-tutorial"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This tutorial walks through building and distributing multi-platform plugin
artifacts using OCI image indexes.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Plugin artifacts (providers, auth handlers) are platform-specific binaries.
To distribute a single plugin that works on multiple OS/architecture
combinations, scafctl stores them as an &lt;strong&gt;OCI image index&lt;/strong&gt; (also called a
&amp;ldquo;fat manifest&amp;rdquo;). At runtime, scafctl automatically selects the correct
binary for the current platform.&lt;/p&gt;
&lt;h3 id="supported-platforms"&gt;Supported Platforms&lt;a class="anchor" href="#supported-platforms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Platform&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;linux/amd64&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Linux x86-64&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;linux/arm64&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Linux ARM64 (e.g. AWS Graviton)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;darwin/amd64&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;macOS Intel&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;darwin/arm64&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;macOS Apple Silicon&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;windows/amd64&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Windows x86-64&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;scafctl CLI installed&lt;/li&gt;
&lt;li&gt;Go toolchain (for cross-compilation)&lt;/li&gt;
&lt;li&gt;Plugin source code that builds for multiple platforms&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="step-1-cross-compile-the-plugin"&gt;Step 1: Cross-Compile the Plugin&lt;a class="anchor" href="#step-1-cross-compile-the-plugin"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use Go&amp;rsquo;s cross-compilation to build binaries for each target platform:&lt;/p&gt;</description></item></channel></rss>