<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="https://perrotta.dev/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Terrateam on ¬ just serendipity 🍀</title>
    <link>https://perrotta.dev/</link>
    <description>Recent content in Terrateam on ¬ just serendipity 🍀</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <managingEditor>serendipity@perrotta.dev (Thiago Perrotta)</managingEditor>
    <webMaster>serendipity@perrotta.dev (Thiago Perrotta)</webMaster>
    <copyright>© 2013 - 2026 Thiago Perrotta ·
  a fork of [hugo ʕ•ᴥ•ʔ bear](https://github.com/janraasch/hugo-bearblog/)
</copyright>
    <lastBuildDate>Tue, 25 Aug 2026 01:11:15 +0200</lastBuildDate>
    <atom:link href="https://perrotta.dev/tags/terrateam/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>terrateam: plan from drift issues
      </title>
      <link>https://perrotta.dev/2026/08/terrateam-plan-from-drift-issues/</link>
      <pubDate>Mon, 24 Aug 2026 18:38:39 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bloggify</category>
      <category>dev</category>
      <category>terraform</category>
      <category>terrateam</category>
      <guid>https://perrotta.dev/2026/08/terrateam-plan-from-drift-issues/</guid>
      <description>&lt;p&gt;♠ &lt;strong&gt;Problem statement&lt;/strong&gt;: Terrateam opens drift reports as GitHub issues, but &lt;code&gt;terrateam plan&lt;/code&gt; only works on pull requests.&lt;/p&gt;&#xA;&lt;p&gt;The distinction is explicit in Terrateam&amp;rsquo;s &lt;a href=&#34;https://github.com/terrateamio/terrateam/blob/cc723447ff80023b8627df6f8719bfb38462cf87/code/src/terrat_vcs_service_github/terrat_vcs_service_github_ep_events3.ml#L550-L655&#34;&gt;issue comment handler&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-ocaml&#34;&gt;{ primary = Primary.{ number = pull_request_id; pull_request = Some _; _ }; _ };&#xA;&#xA;| Gw.Issue_comment_event.Issue_comment_created _ -&amp;gt;&#xA;    Logs.debug (fun m -&amp;gt; m &amp;#34;%s : NOOP : ISSUE_COMMENT_CREATED&amp;#34; request_id);&#xA;    Prmths.Counter.inc_one (Metrics.comment_events_total &amp;#34;noop&amp;#34;);&#xA;    Abbs_future_combinators.return_ok ()&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Calling the repository workflow directly was not an option either. Its work token comes from the Terrateam backend.&lt;/p&gt;&#xA;&lt;p&gt;So I kept Terrateam in charge and gave it the pull request it expects. A GitHub Actions relay checks that the source is an open Terrateam drift issue and that the commenter has repository write access. It then puts a comment-only Terraform file in each selected drift directory:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;markers = [&#xA;    InputGitTreeElement(&#xA;        path=f&amp;#34;{directory}/terrateam_issue_relay.tf&amp;#34;,&#xA;        mode=&amp;#34;100644&amp;#34;,&#xA;        type=&amp;#34;blob&amp;#34;,&#xA;        content=f&amp;#34;# Terrateam plan relay for drift issue #{issue_number}, comment {comment_id}.\n&amp;#34;,&#xA;    )&#xA;    for directory in directories&#xA;]&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;That path change gives Terrateam a real dirspace without changing infrastructure. The relay opens a temporary draft PR and posts the original command on it:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;pull = repo.create_pull(&#xA;    base=repo.default_branch,&#xA;    head=branch,&#xA;    title=f&amp;#34;Terrateam plan relay for drift issue #{issue_number}&amp;#34;,&#xA;    body=relay_body(issue_number, comment_id, event[&amp;#34;comment&amp;#34;][&amp;#34;html_url&amp;#34;]),&#xA;    draft=True,&#xA;)&#xA;pull.as_issue().create_comment(command)&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Terrateam uses its normal locks, hooks, credentials, and batching. Another workflow copies its comments back to the drift issue. &lt;code&gt;apply&lt;/code&gt; remains unsupported: an issue has no PR approval or review intent.&lt;/p&gt;&#xA;&lt;p&gt;The live test planned the requested directory and returned the result:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;## Plans :thumbsup:&#xA;&#xA;## Terrateam Plan Output :thumbsup:&#xA;&#xA;**Plan: 0 to add, 8 to change, 0 to destroy**&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The temporary PR ended where it should:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% gh pr view 6687 --json number,state,headRefName,title&#xA;{&amp;#34;headRefName&amp;#34;:&amp;#34;bot/terrateam-issue-relay/6663-5398113346&amp;#34;,&amp;#34;number&amp;#34;:6687,&amp;#34;state&amp;#34;:&amp;#34;CLOSED&amp;#34;,&amp;#34;title&amp;#34;:&amp;#34;Terrateam plan relay for drift issue #6663&amp;#34;}&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% ./ci/run_python_tests.sh ci/terrateam_issue_relay&#xA;collected 19 items&#xA;tests/test_relay.py ...................                                  [100%]&#xA;============================== 19 passed in 1.45s ==============================&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;A scheduled job deletes inactive relay branches after 30 hours. Terrateam still owns plan execution; the relay only translates the issue command into its existing PR protocol.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;🤖 &lt;em&gt;Drafted with &lt;a href=&#34;https://github.com/thiagowfx/skills/blob/master/plugins/thiagowfx/skills/bloggify/SKILL.md&#34;&gt;&lt;code&gt;/bloggify&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt; ∎&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: terrateam: plan from drift issues&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bloggify/&#34;&gt;#bloggify&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terraform/&#34;&gt;#terraform&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terrateam/&#34;&gt;#terrateam&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Justfile with checks
      </title>
      <link>https://perrotta.dev/2026/04/justfile-with-checks/</link>
      <pubDate>Mon, 27 Apr 2026 10:42:00 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>dev</category>
      <category>serenity</category>
      <category>terrateam</category>
      <guid>https://perrotta.dev/2026/04/justfile-with-checks/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2024/12/just/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I love &lt;a href=&#34;https://just.systems/&#34;&gt;&lt;code&gt;just&lt;/code&gt;&lt;/a&gt; to manage a small collection of related&#xA;scripts within a given codebase. An example in our Terraform codebase&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/justfile-with-checks/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% just check-{hit TAB for completion}&#xA;completing values&#xA;check-aws-config         -- Validate AWS profiles in ~/.aws/config&#xA;check-aws-provider-tags  -- Check AWS provider default_tags configuration&#xA;check-backend-locking    -- Verify S3 backends have use_lockfile = true&#xA;check-import-blocks      -- Check for Terraform import blocks&#xA;check-lockfiles          -- Check that all projects have lockfiles&#xA;check-moved-blocks       -- Check for Terraform moved blocks&#xA;check-secret-accounts    -- Check expected_account_id in terraform-secrets&#xA;check-secrets-tf         -- Validate secrets.tf file structure&#xA;check-shared-values      -- Check for hardcoded values that duplicate shared modules&#xA;check-stacks             -- Verify garden projects have correct stack tags&#xA;check-terraform-version  -- Validate .terraform-version format&#xA;check-terrateam-tags     -- Verify projects are tagged in Terrateam config&#xA;check-tfdocs             -- Check that all README.md have TF_DOCS blocks&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Adopting a common prefix (&lt;code&gt;check-&lt;/code&gt;) improves their discoverability.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s no need to rely on interactivity to take advantage of &lt;code&gt;just&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% just --list&#xA;Available recipes:&#xA;    default                                            # Show categorized help for available commands&#xA;    help                                               # Display categorized help for available commands&#xA;&#xA;[...]&#xA;&#xA;    [terraform]&#xA;    apply module_path=invocation_directory() *args=&amp;#34;&amp;#34;  # Run terraform apply&#xA;    clean module_path=invocation_directory()           # Remove .terraform artifacts&#xA;    destroy module_path *args=&amp;#34;&amp;#34;                       # Run terraform destroy&#xA;    fmt module_path=invocation_directory() *args=&amp;#34;&amp;#34;    # Format terraform files&#xA;    import module_path *args=&amp;#34;&amp;#34;                        # Run terraform import&#xA;    init module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Initialize terraform with backend config&#xA;    output module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Show terraform outputs&#xA;    plan module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Run terraform plan&#xA;    providers-lock module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Lock providers for multiple platforms&#xA;    refresh module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Run terraform refresh&#xA;    show module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Show terraform state or plan&#xA;    stack-apply *args=&amp;#34;&amp;#34;                               # Apply projects in Terrateam stack order (--dry-run for preview)&#xA;    stack-plan *args=&amp;#34;&amp;#34;                                # Plan projects in Terrateam stack order&#xA;    state module_path=invocation_directory() *args=&amp;#34;&amp;#34;  # Run terraform state commands&#xA;    test module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Run terraform tests&#xA;    unlock *args=&amp;#34;&amp;#34;                                    # Force unlock state lock (auto-detects lock ID) [alias: force-unlock]&#xA;    upgrade module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Upgrade providers to latest versions&#xA;    validate module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Validate terraform configuration&#xA;&#xA;[...]&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Justfile &lt;a href=&#34;https://perrotta.dev/2026/02/justfile-groups/&#34;&gt;groups&lt;/a&gt; enhance &lt;code&gt;--list&lt;/code&gt; by&#xA;grouping(!) entries together.&lt;/p&gt;&#xA;&lt;p&gt;This is what a typical entry looks like:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-just&#34;&gt;[doc(&amp;#39;Validate AWS profiles in ~/.aws/config&amp;#39;)]&#xA;[group(&amp;#39;checks&amp;#39;)]&#xA;check-aws-config:&#xA;    @./ci/check_aws_config.sh&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;code&gt;just&lt;/code&gt; is &lt;em&gt;just&lt;/em&gt; (pun intended) a glue for various shell and Python scripts in&#xA;&lt;code&gt;ci/&lt;/code&gt;. ∎&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;I wrote all of these.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/justfile-with-checks/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Justfile with checks&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terrateam/&#34;&gt;#terrateam&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Gimme subagents
      </title>
      <link>https://perrotta.dev/2026/02/gimme-subagents/</link>
      <pubDate>Mon, 23 Feb 2026 10:57:55 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>bestof</category>
      <category>claude</category>
      <category>dev</category>
      <category>terrateam</category>
      <guid>https://perrotta.dev/2026/02/gimme-subagents/</guid>
      <description>&lt;p&gt;♠ &lt;strong&gt;Scenario&lt;/strong&gt;: we&amp;rsquo;re test-driving the adoption of a&#xA;&lt;a href=&#34;https://terrateam.io/&#34;&gt;Terrateam&lt;/a&gt; feature&#xA;&lt;a href=&#34;https://docs.terrateam.io/reference/configuration/stacks/&#34;&gt;called&lt;/a&gt;&#xA;&lt;a href=&#34;https://terrateam.io/stacks&#34;&gt;stacks&lt;/a&gt;. The specifics aren&amp;rsquo;t relevant here.&lt;/p&gt;&#xA;&lt;p&gt;In a typical agentic LLM session with &lt;a href=&#34;https://claude.ai/code&#34;&gt;Claude Code&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/02/gimme-subagents/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;,&#xA;the feature was drafted (planned) and then subsequently implemented.&lt;/p&gt;&#xA;&lt;p&gt;Following that comes the important part: &lt;strong&gt;testing&lt;/strong&gt;! As part of the testing&#xA;process I tend to resonate with &lt;a href=&#34;https://registerspill.thorstenball.com/p/joy-and-curiosity-71&#34;&gt;Thorsten&#xA;Ball&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Most of the time, when I work with Amp, I know in advance (a) what I want the&#xA;resulting code to do and (b) how I will test that it does exactly that.&lt;/p&gt;&#xA;&lt;p&gt;Once Amp declares it&amp;rsquo;s done writing code, I test. And what I mean is that I&#xA;&amp;ldquo;test&amp;rdquo;, in every possible meaning of the word. The goal is to make sure the&#xA;code actually does what it&amp;rsquo;s supposed to do. That can mean: asking Amp to run&#xA;the unit tests, asking it to manually test in a browser, asking it to run a&#xA;command, or check the data in the database, run the curl. With every tool I&#xA;have — Amp, code, my hands and eyes — I test the happy path, the teary path,&#xA;the edge cases. I make sure to test with existing data, no data, real data,&#xA;fake data. I think about what might be different in production and how I could&#xA;test that. Sometimes I ask Amp itself how I can manually verify what it just&#xA;did and ask it to walk me through the testing.&lt;/p&gt;&#xA;&lt;p&gt;How exactly I test very much depends on what I&amp;rsquo;m testing. Not all&#xA;functionality and code have the same blast radius. Some sit at the heart of a&#xA;system, some are peripheral. Adjust accordingly.&lt;/p&gt;&#xA;&lt;p&gt;But once I&amp;rsquo;ve tested something and compared how it works with my mental model&#xA;of how it&amp;rsquo;s supposed to work, then the code, I find, becomes less important.&lt;/p&gt;&#xA;&lt;p&gt;Yes, I&amp;rsquo;ll do spot-checks to make sure it isn&amp;rsquo;t completely insane (less and&#xA;less of a problem with these new models). I also go through my mental list of&#xA;always-check-these things like (a) where and how is the data stored (b) will&#xA;this box us in and prevent future changes (c) security (d) does it touch&#xA;functionality I hadn&amp;rsquo;t considered. Sometimes that can take a while, other&#xA;times there&amp;rsquo;s barely anything to do.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&amp;hellip;hence I surely prompt the LLM to suggest me how to test the feature:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;⏺ Here&amp;#39;s how to test the stacks feature:&#xA;&#xA;  1. Validate the config syntax&#xA;&#xA;  just check-terrateam-tags&#xA;&#xA;  This confirms all projects referenced in .terrateam/config.yml have valid tags, including the new corp-network-check tags.&#xA;&#xA;  2. Verify tag assignments are correct&#xA;&#xA;  Check that the right projects land in each stack:&#xA;&#xA;  # Foundation layer projects&#xA;  just list-projects-by-tag network&#xA;  just list-projects-by-tag terraform-secrets&#xA;  just list-projects-by-tag atlas&#xA;&#xA;  # Compute layer projects&#xA;  just list-projects-by-tag eks&#xA;  just list-projects-by-tag corp-network-check&#xA;&#xA;  # Services layer (future)&#xA;  just list-projects-by-tag service-identity&#xA;&#xA;  Confirm that every cluster project falls into exactly one of the three stacks.&#xA;&#xA;  3. Validate the config file itself&#xA;&#xA;  just validate-terrateam-config   # if this recipe exists&#xA;  # or simply:&#xA;  yamllint .terrateam/config.yml   # basic YAML syntax check&#xA;&#xA;  4. Test on a real PR (the real test)&#xA;&#xA;  Stacks are a Terrateam server-side feature — the ordering logic runs in Terrateam&amp;#39;s CI, not locally. The only real end-to-end test is:&#xA;&#xA;  [...]&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;For the sake of preserving the context window of my current session, I employ&#xA;the following technique:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;❯ 1) OK (in a subagent)&#xA;  2) OK (in a subagent, in parallel)&#xA;  3) OK (in a subagent, in parallel)&#xA;&#xA;  let&amp;#39;s do these first. Prompt me before going to 4&#xA;&#xA;⏺ 3 agents finished (ctrl&amp;#43;o to expand)&#xA;   ├─ Bash (Check terrateam tags validation) · 1 tool use · 13.3k tokens&#xA;   │  ⎿  Done&#xA;   ├─ Task (Verify tag assignments per stack) · 17 tool uses · 32.3k tokens&#xA;   │  ⎿  Done&#xA;   └─ Bash (Validate terrateam config YAML) · 7 tool uses · 16.5k tokens&#xA;      ⎿  Done&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;And that works exactly as you would expect it to.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;⏺ All three checks passed:&#xA;&#xA;  1. Tag validation (just check-terrateam-tags)&#xA;&#xA;  All {redacted – number of projects} standalone projects are properly tagged.&#xA;&#xA;  2. Stack tag assignment verification&#xA;&#xA;  ┌─────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐&#xA;  │                  Check                  │                                                    Result                                                    │&#xA;  ├─────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤&#xA;  │ Cluster projects missing from all stacks│ None — all {redacted – number of projects} cluster projects are covered                                      │&#xA;  ├─────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤&#xA;  │ Cluster projects in multiple stacks     │ None — tag sets are disjoint                                                                                 │&#xA;  ├─────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤&#xA;  │ Non-cluster projects in stacks          │ 10 projects (6 terraform-secrets, 1 opsgenie, 3 atlas) — all in cluster-foundation, expected/harmless per ADR│&#xA;  ├─────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤&#xA;  │ Placeholder tags (not yet in use)       │ deploy, rds, service-identity — cluster-services stack is currently empty                                    │&#xA;  └─────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘&#xA;&#xA;  3. Config validation&#xA;&#xA;  - yamllint: passed (zero warnings/errors)&#xA;  - just check: all checks passed (AWS profiles, terrateam tags, AWS provider tags)&#xA;&#xA;  Everything looks good locally. Ready for step 4 (push branch, open PR, test Terrateam&amp;#39;s stack ordering on a real PR) whenever you want to proceed.&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;em&gt;In prose&lt;/em&gt;: consider using&#xA;&lt;a href=&#34;https://code.claude.com/docs/en/sub-agents&#34;&gt;subagents&lt;/a&gt; (i) to preserve your&#xA;&lt;a href=&#34;https://perrotta.dev/2025/10/mcp-model-context-protocol-considered-harmful/&#34;&gt;context window&lt;/a&gt;, and (ii) to&#xA;speed up testing by running them in parallel.&lt;/p&gt;&#xA;&lt;p&gt;One disadvantage: I&amp;rsquo;d avoid using subagents in this manner whenever the testing&#xA;procedures aren&amp;rsquo;t clearly well-defined and scoped (for example, whenever they&#xA;are ambiguous or uncertain). Why? Because I&amp;rsquo;d rather have full control in these&#xA;complex scenarios, by having the ability to manually steer the LLM in real-time.&#xA;With subagents you have limited ability to do so.&lt;/p&gt;&#xA;&lt;p&gt;Last but not least: subagents are not an exclusive feature of Claude Code:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Pi has a couple of extensions that add subagents capabilities to it.&#xA;&lt;a href=&#34;https://github.com/nicobailon/pi-subagents&#34;&gt;Example&lt;/a&gt; (untested)&lt;/li&gt;&#xA;&lt;li&gt;And so does &lt;a href=&#34;https://opencode.ai/docs/agents/&#34;&gt;OpenCode&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;I am a bit surprised to find out that Codex &lt;a href=&#34;https://github.com/openai/codex/issues/2604&#34;&gt;does not&lt;/a&gt; support them&#xA;yet. Or &lt;a href=&#34;https://developers.openai.com/codex/multi-agent/&#34;&gt;does it&lt;/a&gt;?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Should I stop linking to their website? At this point, every Software&#xA;Engineer has heard of Claude Code at least once, right?&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/02/gimme-subagents/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;∎&lt;/p&gt;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Gimme subagents&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/claude/&#34;&gt;#claude&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terrateam/&#34;&gt;#terrateam&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>.terraform-version
      </title>
      <link>https://perrotta.dev/2025/10/.terraform-version/</link>
      <pubDate>Fri, 24 Oct 2025 15:12:18 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>terraform</category>
      <category>terrateam</category>
      <guid>https://perrotta.dev/2025/10/.terraform-version/</guid>
      <description>&lt;p&gt;♠ &lt;code&gt;.terraform-version&lt;/code&gt; at the root of a git repository is recognized by various&#xA;tools:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/tfutils/tfenv#terraform-version-file&#34;&gt;tfenv&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://tfswitch.warrensbox.com/usage/config-files/#use-versiontf-file&#34;&gt;tfswitch&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://docs.terrateam.io/integrations/iac-tools/terraform&#34;&gt;terrateam&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;You would expect the&#xA;&lt;a href=&#34;https://github.com/hashicorp/setup-terraform&#34;&gt;&lt;code&gt;hashicorp/setup-terraform&lt;/code&gt;&lt;/a&gt;&#xA;github action would also recognize it out-of-the-box, but it does not. We can&#xA;address this gap by reading it manually:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;jobs:&#xA;  terraform:&#xA;    runs-on: ubuntu-latest&#xA;    steps:&#xA;      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0&#xA;        with:&#xA;          persist-credentials: false&#xA;&#xA;      - name: Read Terraform version&#xA;        id: terraform-version&#xA;        run: echo &amp;#34;version=$(cat .terraform-version)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&#xA;&#xA;      - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2&#xA;        with:&#xA;          terraform_version: ${{ steps.terraform-version.outputs.version }}&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;There&amp;rsquo;s a &lt;a href=&#34;https://github.com/hashicorp/setup-terraform/issues/298&#34;&gt;feature&#xA;request&lt;/a&gt; for it. ∎&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: .terraform-version&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terraform/&#34;&gt;#terraform&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terrateam/&#34;&gt;#terrateam&lt;/a&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
