<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Amara Graham</title>
    <description>The latest articles on DEV Community by Amara Graham (@missamarakay).</description>
    <link>https://dev.to/missamarakay</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1330%2Fe4706a09-0796-4d76-a451-832c6897bda5.jpg</url>
      <title>DEV Community: Amara Graham</title>
      <link>https://dev.to/missamarakay</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/missamarakay"/>
    <language>en</language>
    <item>
      <title>Building PoCs with Codex and GitHub Copilot while they try to adjust my PoC requirements along the way</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Wed, 16 Sep 2026 17:04:22 +0000</pubDate>
      <link>https://dev.to/missamarakay/building-pocs-with-codex-and-github-copilot-while-they-try-to-adjust-my-poc-requirements-along-the-1fc9</link>
      <guid>https://dev.to/missamarakay/building-pocs-with-codex-and-github-copilot-while-they-try-to-adjust-my-poc-requirements-along-the-1fc9</guid>
      <description>&lt;p&gt;I think it took about 10 minutes after I published my &lt;a href="https://dev.to/missamarakay/admit-it-you-have-a-favorite-ai-just-like-you-have-a-favorite-coworker-1fa0"&gt;last blog&lt;/a&gt; for someone to ask about yet-another-AI-tool. &lt;/p&gt;

&lt;p&gt;So here's two more. Then I'm done for now so I can write about the audit I did with all these tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  ChatGPT + Codex
&lt;/h2&gt;

&lt;p&gt;This felt like Claude without the orange splat logo. With a fresh download I was on 5.6 Terra Medium. &lt;/p&gt;

&lt;p&gt;Codex created a React PoC that loaded fairly quickly, but I did have to go back and forth with it a few times to get a functional PDF viewer running and then a few more times to get the extraction not only working, but working well if the data was missing or redacted (and, if done properly, missing). &lt;/p&gt;

&lt;p&gt;More effectively than the other AIs, it found (or made, as it claimed) valid PDFs with interesting data and formats. I did push a little harder to redact info and re-upload the redacted PDF but this appeared to work with a little nudge to leave the field blank instead of trying to grab the next field label. &lt;/p&gt;

&lt;p&gt;This was definitely the most seamless experience. It modified the code in the directory (and yes, it did ask for approval as that's the setting it's on) and I would stop and restart the &lt;code&gt;npm run dev&lt;/code&gt; command to see what the new updates would yield. &lt;/p&gt;

&lt;p&gt;It did feel like it was initially a little too quick to stub or mock things, including in the initial project stubbing the WebViewer... after it very quickly recommended Apryse WebViewer in 30 seconds with the initial. So why stub it? Maybe it was scared it needed a license key to function at all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is intentionally a frontend prototype; the next implementation step is replacing the mock paper viewer with Apryse WebViewer and wiring the extraction/audit actions to backend APIs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you know I was like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Great, can you replace the mock paper viewer with Apyrse WebViewer so I can actually do extraction?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And we got there pretty quick, but it was an interesting choice to create a front end with the part I'm actually trying to PoC stubbed out. Very pay-no-attention-to-the-man-behind-the-curtain if you ask me.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;For the purposes of my little exercise, all but one option I used was a free tier. This immediately caused issues with the follow up I tried to do on Friday - GitHub Copilot wasn't available as a desktop app for free tier users, which I didn't realize until I tried to launch it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faw3uhmmw1tyfzk67pq3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faw3uhmmw1tyfzk67pq3h.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Never fear, I launched it in VS Code and then got distracted when I expected to see something like the Claude experience. I assumed it just didn't work or install properly.&lt;/p&gt;

&lt;p&gt;Turns out, it installed just fine, but unlike my other AI chat experiences, I needed to make sure I was in a new project and didn't have any files actively opened, because it was certainly going to use those as context. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm GitHub Copilot, using Claude Haiku 4.5. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Excuse me, Claude is back? Wild. For reference, I'm using Sonnet 5 with Claude on the desktop app. &lt;/p&gt;

&lt;p&gt;It. Is. So. Fast.&lt;/p&gt;

&lt;p&gt;It gave me a PoC project structure in 5 seconds with a button to create a workspace. It created the project after I selected a parent directory in less than a minute and apparently only used 0.2 credits, which I can clearly see on the screen.&lt;/p&gt;

&lt;p&gt;And then... it broke my heart.&lt;/p&gt;

&lt;p&gt;Once I got the project structure I started to install the dependencies and ran into all sorts of mess. I continued to push on GitHub Copilot to help sort this. First it was let's adjust the WebViewer from &lt;code&gt;9.something&lt;/code&gt; to &lt;code&gt;10.0.0&lt;/code&gt;. Then it was like how about &lt;code&gt;latest&lt;/code&gt; because this is a PoC anyway. Then it suggested I switch to &lt;code&gt;pdf.js&lt;/code&gt; because I was having so many issues with the package.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Apryse package isn't properly installed. Since we've been struggling with the package, let's use PDF.js instead—it's simpler and already works:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dear reader, &lt;em&gt;I&lt;/em&gt; was having no issues with the package. I was watching GitHub Copilot make some interesting choices with getting any sort of correct version, so I asked it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What sources are you using for Apryse? I was able to build PoCs like Claude easily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like to use AIs adversarially, so I figured I would name drop and see what happened.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You're right—I apologize. Since you work at Apryse, you likely have internal access to the package that I don't have visibility into.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the same garbage Microsoft Copilot inferred because it saw the directory file tree included my Apryse email. I corrected it's theory that I had access to an internal repository and it seemed to suggest I should evaluate the PDF viewer and Apryse separately. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What sources are you using to generate the Apryse-based code? They seem like they are using old versions of the packages. Can you give me a list of the sources you've used in this chat?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And to my horror, it told on itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You're right to call this out. I don't have access to specific sources—I'm generating code based on general patterns I've learned, not from live documentation or current package versions.&lt;/p&gt;

&lt;p&gt;For Apryse specifically, I've been making educated guesses about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package names (@pdftron/pdfjs-express)&lt;/li&gt;
&lt;li&gt;API structure (WebViewer() function)&lt;/li&gt;
&lt;li&gt;Configuration options (path: '/lib')&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is problematic because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I can't verify current versions on npm&lt;/li&gt;
&lt;li&gt;I don't have access to official Apryse docs to cross-reference&lt;/li&gt;
&lt;li&gt;The code I generated is likely outdated or incorrect&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Girl (gender neutral), what are you doing?&lt;/p&gt;

&lt;p&gt;I then clarified that the Apryse docs are public, but that GitHub Copilot didn't have access to browse the web in real-time. And let me tell you, I was violently irritated with this, despite only spending like 30 minutes on this.&lt;/p&gt;

&lt;p&gt;When AI speaks with conviction, as it so often does, it's really compelling. You accept what it's given you because you have no real reason not to... until something like this happens. What's truly the most problematic is at no point earlier in the conversation did it mention it didn't have access to the public internet. The default for all other AIs is having access to the internet!&lt;/p&gt;

&lt;p&gt;I ended up finding the configuration in my GitHub settings, adjusting the toggle to allow GitHub Copilot to search the internet, and reran the original prompt in a new chat and allowed it to make a new project. &lt;/p&gt;

&lt;p&gt;The project structure was wildly different, I ran into exactly zero package version issues, and in 10 minutes had a working Apryse-based PoC. Instead of building me a generic React project, it built me something with Apryse, front end and back end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;If you won't tell me your favorite AI, who is your favorite coworker? &lt;/p&gt;

&lt;p&gt;Since I'm using these for work, I'm going to continue to try to make Microsoft Copilot work, along with getting into the program that allows me to work with Claude. &lt;/p&gt;

&lt;p&gt;Admittedly, I'm really disappointed in the GitHub Copilot experience not being up front about it's access to the broader internet, and then not being able to guide me to the correct setting to allow it the access I assumed it already had. Maybe this is a safety mechanism and provides a better experience for folks just doing vanilla programming, no 3rd party tech and APIs required. Just tell me that's what's going on.&lt;/p&gt;

&lt;p&gt;This audit is kind of a one time thing, in the sense that I probably won't regularly use all the tools I can get my hands on, and I'll eventually spoil my setups by adding too much personalized context. Is there a concept of incognito mode in any of these tools? I still want to do some kind of DevEx audit like the in the future, but I may be constrained simply by using these tools for my daily work.&lt;/p&gt;

&lt;p&gt;Drop your tips and tricks for me in the comments about working with Microsoft Copilot! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@tinkerman?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Immo Wegmann&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/a-piece-of-cardboard-with-a-keyboard-appearing-through-it-vi1HXPw6hyw?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Admit it, you have a favorite AI (just like you have a favorite coworker)</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Thu, 10 Sep 2026 19:43:09 +0000</pubDate>
      <link>https://dev.to/missamarakay/admit-it-you-have-a-favorite-ai-just-like-you-have-a-favorite-coworker-1fa0</link>
      <guid>https://dev.to/missamarakay/admit-it-you-have-a-favorite-ai-just-like-you-have-a-favorite-coworker-1fa0</guid>
      <description>&lt;p&gt;My mom likes to quote her grandmother who would say things like "I hate yous all equally" when asked who her favorite grandchild was. I feel that, but with AI tools.&lt;/p&gt;

&lt;p&gt;If you've worked with me recently, you've probably been my favorite coworker. At least temporarily. It's an easy title to achieve, but hard to hold on to. &lt;/p&gt;

&lt;p&gt;Anyway, I just finished a little onboarding audit project (which I may elaborate on later) but for now I want to rant about AI, which didn't help me write this at all so any typo or grammatical "error" you see is an aesthetic choice.&lt;/p&gt;

&lt;p&gt;I used 3 AI tools, 4 if you count Google's AI results in a traditional search experience, and pretty much only the chat functionality. Just like everyone has a different working style, everyone probably feels some pull toward one AI experience over another, given that they have that choice and aren't mandated to use a specific one. &lt;/p&gt;

&lt;p&gt;Let's dive into Claude, Gemini, and Microsoft Copilot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude
&lt;/h2&gt;

&lt;p&gt;Admittedly, I've had the most success with Claude, even when it hallucinated a solution earlier this year when I asked if there was a way or tool to measure time to response on a community Slack thread. When I didn't recognize the tool name I asked it to cite it's sources and Claude was like "oops, I made that up." Neat.&lt;/p&gt;

&lt;p&gt;Anyway, Claude was the most seamless pair programming experience via Chat. When Claude suggested multiple files needed to be changed, the instructions to change them, and where, were quite clear, but at some point I said "can you just regenerate the project files with the changes", and it did exactly that.&lt;/p&gt;

&lt;p&gt;For the most part it stuck to publicly accessible content and didn't grab context from other chats, which is exactly what I was hoping for in this experience. This allowed me to open multiple chats, as different questions, and collect all the responses. A plain ol' vanilla install if you will - so no skills, memories, artifacts, etc. I didn't even put anything in a project. &lt;/p&gt;

&lt;p&gt;There were two situations where it didn't hallucinate, but it did need some challenges to responses it provided. &lt;/p&gt;

&lt;p&gt;For example, Claude cited NSA secure coding "best practices" and using multiple engines for doing something like redaction. I imagine I will do a future blog on this topic, specifically around redaction with Apryse, but the guidance didn't make realistic sense for an enterprise project. It suggested doing the redaction with one platform/vendor and then verifying the redaction was complete with another platform/vendor. This is maybe reasonable if my budget is unlimited, but when prompted Claude was quick to back down and say "it's not really a citable best practice, but it's my recommendation based on security best practices." &lt;/p&gt;

&lt;p&gt;I could see responses like this being a massive problem for people who struggle with pushing back. I was and still am a "why" kid. I'm always asking why and I think that skill is critical when working with AI. I also love demanding "cite your sources" so I can manually review whether they are credible sources or not, or in the case above, clearly see there was no specific source. Just vibes.&lt;/p&gt;

&lt;p&gt;I was able to do everything I needed to do on a free tier using Sonnet 5 and only ran into message limits twice over two weeks. But please keep in mind I was doing a lot of context switching and using other AIs. Your mileage may vary.&lt;/p&gt;

&lt;p&gt;Also important to note, I wasn't using Claude Code or the VS Code extension. I was just having a little chat with Claude via the desktop app to stay in control of the context and internal data sources as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gemini
&lt;/h2&gt;

&lt;p&gt;Gemini was an ok experience. Gemini has become my preferred AI for personal use (but admittedly, my personal use is very light). With my husband heavily committed to the Google ecosystem, it's easily accessible and makes sense.&lt;/p&gt;

&lt;p&gt;This was my first time doing any sort of programming and debugging with Gemini. It was clear about what errors I should see and where, it was also great about adding more debugging statements and what the expected outcome should be.&lt;/p&gt;

&lt;p&gt;It just wasn't as seamless as Claude. Where Claude gave me a full React project, Gemini only produced .JSX and .CSS files and expected me to drop them into a React project. So I manually went and found a sample code React project, got it up an running, then dropped in Gemini's files. If I wasn't starting a net new project and I could actually call myself a React developer, I might have felt like this experience was just fine. I was admittedly surprised it inferred I had an existing React project when it got the same exact prompt Claude did and really should have inferred I was starting from scratch.&lt;/p&gt;

&lt;p&gt;Gemini was a free tier experience as well. I used my work browser profile instead of my personal Google account/profile so I wasn't tapping into my family plan. This all happened in a browser tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microsoft Copilot
&lt;/h2&gt;

&lt;p&gt;If you are looking for Glean on steroids, Microsoft Copilot feels like the place to go. It was so aggressive about sourcing internally that I had to toggle off all the data sources and "Work IQ". &lt;/p&gt;

&lt;p&gt;Even then, I never really solved this issue of Microsoft Copilot grabbing or referring to context I didn't want it to have. Separate chats seemed like they were all fair game. It even inferred I was an Apryse employee by referencing the file tree and directory names of an uploaded file. I'm sure someone appreciates that, but for the purposes of this audit, I want to see what &lt;em&gt;externals&lt;/em&gt; see. It was just too smart.&lt;/p&gt;

&lt;p&gt;Microsoft Copilot also over-answered every prompt I gave it. When I asked about curriculum-based learning or academy experiences, it responded that they didn't appear to exist and then proceed to give me a rated matrix of what was available instead. When I prompted for a more terse answer, it seemed to double down, write another dissertation, and then bold the expected terse answer at the bottom. At that point I didn't bother scrolling back up to read anything because all I wanted was a short, sweet answer.&lt;/p&gt;

&lt;p&gt;This was also, by far, the worst coding experience. The initial React project it generated was riddled with old versions of packages that created annoying errors just trying to load the project. I want a paired programming experience, so when I'd take this or other issues back to the AI chat, it's like it would suffer a concussion with immediate memory loss. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't have access to that."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You don't have access... to the code you just generated and gave to me one response above this?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This looks like AI generated code."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probably because you, an AI, generated said code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If you upload the files, I will have access to them."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You want me to upload the files that you provided me... that I downloaded and made exactly no changes to. K. Cool.&lt;/p&gt;

&lt;p&gt;Microsoft Copilot was an enterprise licensed experience. I never saw anything about tokens or message limits, but getting a response was often quite slow. Maybe it's important to mention I did everything via chat vs. cowork and I was working in a browser tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Claude wins, but it wasn't really a contest.&lt;/p&gt;

&lt;p&gt;It's entirely possible I ran into some user error with all of these tools. It's also possible I'm generating opinions about what AI is best for what exercise. For this experience I just wanted quick answers without a lot of setup and fuss, and for better or worse I got that. Low investment, high output.&lt;/p&gt;

&lt;p&gt;For now, I'm shifting gears to work on other projects and will have different use cases, and will probably spend a bit more time trying to make Microsoft Copilot a more usable experience for me. I'll probably also look into Claude, Claude Code, and specifically the VS Code extension, so long as that's been blessed by my employer as an option. Otherwise, I'll be reaching out to the engineers about what they are using.&lt;/p&gt;

&lt;p&gt;Do you have a favorite AI? Or a favorite coworker? I'm here for &lt;em&gt;all&lt;/em&gt; the hot gossip. Drop a comment and let me know.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@steve_j?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Steve A Johnson&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/repeating-blue-and-silver-ai-letters-1FD-E7Ioblw?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>It's just me, slamming my hands on a keyboard, asking the AI to fix the code it generated within the same discussion it claims it has no access or context.</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Fri, 04 Sep 2026 14:41:50 +0000</pubDate>
      <link>https://dev.to/missamarakay/its-just-me-slamming-my-hands-on-a-keyboard-asking-the-ai-to-fix-the-code-it-generated-within-5em5</link>
      <guid>https://dev.to/missamarakay/its-just-me-slamming-my-hands-on-a-keyboard-asking-the-ai-to-fix-the-code-it-generated-within-5em5</guid>
      <description></description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>debugging</category>
      <category>llm</category>
    </item>
    <item>
      <title>Sibling Rivalry? How to Make Kestra Tasks Talk to Each Other</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Wed, 22 Apr 2026 16:45:45 +0000</pubDate>
      <link>https://dev.to/kestra/sibling-rivalry-how-to-make-kestra-tasks-talk-to-each-other-15m5</link>
      <guid>https://dev.to/kestra/sibling-rivalry-how-to-make-kestra-tasks-talk-to-each-other-15m5</guid>
      <description>&lt;p&gt;I'm putting together a video on sibling tasks in Kestra and thought I would build this idea out loud with you in a blog first.&lt;/p&gt;

&lt;p&gt;Let's jump in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What are sibling tasks?
&lt;/h2&gt;

&lt;p&gt;Sibling tasks are tasks that have the same parent task. For the rest of this blog, we'll refer to sibling tasks within the context of a dynamic or looping construct.&lt;/p&gt;

&lt;p&gt;So in this case, we can be more specific and say sibling tasks are the tasks defined within the &lt;code&gt;tasks&lt;/code&gt; list of a loop. If we use &lt;code&gt;ForEach&lt;/code&gt; as an example, we could have something that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my_loop&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.flow.ForEach&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alpha"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;beta"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;first_sibling&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.debug.Return&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Data&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;taskrun.value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;second_sibling&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
      &lt;span class="c1"&gt;# Accessing the sibling's output for the current iteration&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sibling&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;said:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.first_sibling[taskrun.value].value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ForEach&lt;/code&gt;, or &lt;code&gt;my_loop&lt;/code&gt;, is the parent, with the siblings being &lt;code&gt;first_sibling&lt;/code&gt; and &lt;code&gt;second_sibling&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In this example you can see our log message contains info passed from &lt;code&gt;first_sibling&lt;/code&gt; with the expression syntax. You will see this in the &lt;a href="https://go.kestra.io/qTxlru" rel="noopener noreferrer"&gt;docs&lt;/a&gt; as "sibling task lookup". Pay attention to the differences between sequential and dynamic tasks, like looping. &lt;/p&gt;

&lt;h2&gt;
  
  
  Execution &amp;amp; &lt;code&gt;TaskRun&lt;/code&gt; context
&lt;/h2&gt;

&lt;p&gt;You may be familiar with the concept of context or scope and I think this is where things can start to get confusing.&lt;/p&gt;

&lt;p&gt;A task run is a single execution of an individual task within a larger workflow execution. When you are within a &lt;code&gt;ForEach&lt;/code&gt;'s task list, you'll want to use &lt;code&gt;taskrun.value&lt;/code&gt; to get the value associated with that run or iteration.&lt;/p&gt;

&lt;p&gt;This might be a bit different to how you've done looping with programming languages where you are scoped within the brackets of the loop. You don't need to think about iterations, just the work happening within the loop. &lt;/p&gt;

&lt;p&gt;Think of it like a "You Are Here" marker on a map. If you were hiking on a trail and came across a trail map with no marker to tell you where you are, it's not very helpful. You know you are on a trail and you could probably make a guess of where you are based on landmarks or time spent on the trail, but you could also be really wrong. And then get really lost.&lt;/p&gt;

&lt;p&gt;Bringing it back to programming and workflows, using a key to indicate what run or iteration becomes hugely important when you are running tasks concurrently. This means the context needs a hint at what iteration you are interested in. I know I'm looking for data in the loop, but which run? &lt;/p&gt;

&lt;h2&gt;
  
  
  Outputs
&lt;/h2&gt;

&lt;p&gt;Outputs are how you pass data between tasks or flows. Standard tasks usually reference outputs via &lt;code&gt;{{ outputs.task_id.value }}&lt;/code&gt;. This gives you the value of a specific task's output.  &lt;/p&gt;

&lt;p&gt;In this case, we want to pass data between sibling tasks, which may look something like this &lt;code&gt;{{ outputs.first_sibling[taskrun.value].value }}&lt;/code&gt;. This gives you the values of a specific run or iteration from the &lt;code&gt;first_sibling&lt;/code&gt; task's output. This is very specific and helps prevent any conflict with concurrency or tasks firing in parallel.&lt;/p&gt;

&lt;p&gt;We can't assume &lt;code&gt;ForEach&lt;/code&gt; child tasks will run in parallel unless we set loop concurrency or use a parallel task.&lt;/p&gt;

&lt;p&gt;I highly recommend reading our &lt;a href="https://go.kestra.io/gYXgq5" rel="noopener noreferrer"&gt;best practices page&lt;/a&gt; on this topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outputs vs. execution &amp;amp; TaskRun context
&lt;/h2&gt;

&lt;p&gt;But let's say we want to access data outside of the loop. We can do that too, modifying our example from above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my_loop&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.flow.ForEach&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alpha"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;beta"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;first_sibling&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.debug.Return&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Data&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;taskrun.value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;second_sibling&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
      &lt;span class="c1"&gt;# Accessing the sibling's output for the current iteration&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sibling&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;said:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.first_sibling[taskrun.value].value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outside&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
  &lt;span class="c1"&gt;# Accessing the data for the `alpha` run specifically&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.first_sibling['alpha'].value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would give us the "alpha" iteration's output from the &lt;code&gt;first_sibling&lt;/code&gt; task as a value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it gets confusing
&lt;/h2&gt;

&lt;p&gt;This tends to get confusing when you start using a mix of outputs and &lt;code&gt;taskRun&lt;/code&gt;. When your output exists outside of the loop, you use the standard syntax. Inside the loop? You need to give Kestra the key (or value) associated with the particular iteration. &lt;/p&gt;

&lt;p&gt;Additionally, your error messages can seem non-intuitive. You can will typically get an error where the value isn't found when you forget to use a key.&lt;/p&gt;

&lt;p&gt;So let's look again at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outside&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.first_sibling['alpha'].value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt; &lt;span class="c1"&gt;# correct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if we ran this with the key, the value of the iteration we want to capture, we'll get an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outside&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.first_sibling.value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt; &lt;span class="c1"&gt;# will error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;Unable to find `value` used in the expression `{{ outputs.first_sibling.value }}` at line &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to use double quotes
&lt;/h3&gt;

&lt;p&gt;Double quotes around your expressions give a clear indicator that this value is a string. Without them, you may get that unintuitive error that the value in the expression cannot be found.&lt;/p&gt;

&lt;p&gt;When I'm debugging my workflows, I usually try to make sure I have a key for my iteration and I've wrapped my expression in double quotes before I do any more extensive investigation. That usually solves it for me.&lt;/p&gt;

&lt;p&gt;This should show up as a linting warning with a nice yellow squiggle, but it depends on the task properties and types you are working with.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to use &lt;code&gt;ForEach&lt;/code&gt; and &lt;code&gt;ForEachItem&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A bigger topic is the differences between &lt;code&gt;ForEach&lt;/code&gt; and &lt;code&gt;ForEachItem&lt;/code&gt;, which we have a great &lt;a href="https://go.kestra.io/GQ2cTW" rel="noopener noreferrer"&gt;best practices page&lt;/a&gt; on.&lt;/p&gt;

&lt;p&gt;The TL;DR is use &lt;code&gt;ForEachItem&lt;/code&gt; when you want subflows and you are doing a lot of work on a lot of things. &lt;/p&gt;

&lt;p&gt;Let me know if in the comments if you want a blog or video (or both!) on this topic. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;So that covers sibling tasks and outputs and expressions, oh my! Hopefully this adds a little more supplemental details to our docs on this topic. &lt;/p&gt;

&lt;p&gt;As always, let me know if there is something you want me to explain in a little more detail! I'll get a video related to this topic out next week too. &lt;/p&gt;

</description>
      <category>kestra</category>
      <category>orchestration</category>
      <category>automation</category>
    </item>
    <item>
      <title>What brings you by a conference booth?</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Thu, 16 Apr 2026 14:39:18 +0000</pubDate>
      <link>https://dev.to/missamarakay/what-brings-you-by-a-conference-booth-43e3</link>
      <guid>https://dev.to/missamarakay/what-brings-you-by-a-conference-booth-43e3</guid>
      <description>&lt;p&gt;I'm thinking about in-person events more and more these days, so I'm curious - what brings you by a conference booth? &lt;/p&gt;

&lt;p&gt;What's a good experience or design you've seen? Or when do you avoid a booth (or booths!) entirely?&lt;/p&gt;

&lt;p&gt;LMK 😊&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>CVEs are vulnerabilities(!!!) and part 2 of my Notion automation</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Tue, 14 Apr 2026 20:41:27 +0000</pubDate>
      <link>https://dev.to/missamarakay/cves-are-vulnerabilities-and-part-2-of-my-notion-automation-439o</link>
      <guid>https://dev.to/missamarakay/cves-are-vulnerabilities-and-part-2-of-my-notion-automation-439o</guid>
      <description>&lt;p&gt;&lt;em&gt;Read part 1 first over &lt;a href="https://dev.to/missamarakay/building-a-self-triaging-cve-checker-with-gemini-kestra-and-notion-4dek"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Last week I learned that there are people in tech who don't know what a CVE is. This shocked me to my core! I'm not talking about people not knowing the acronym, because there are too many of those, I'm talking about not realizing CVEs are vulnerabilities. &lt;/p&gt;

&lt;p&gt;Starting my career in a large Enterprise IT organization, I lived through two significant pushes - code scanning and accessibility. &lt;/p&gt;

&lt;p&gt;Code scanning was a response to "upskilling" the organization in security-minded coding practices and with it came awareness of vulnerabilities.&lt;/p&gt;

&lt;p&gt;And shortly after that came anxiety.&lt;/p&gt;

&lt;p&gt;Anxiety that you left your source code vulnerable or that you chose a library that was vulnerable. &lt;/p&gt;

&lt;p&gt;Maybe that's why I'm not an enterprise developer anymore...&lt;/p&gt;

&lt;p&gt;Anyway, I finished my CVE tracker. My vulnerability tracker, if you will. I even made you a video! Just like I promised!&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/eUo9Q5aFRkU" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I was able to use both the &lt;a href="https://kestra.io/plugins/plugin-notion" rel="noopener noreferrer"&gt;Notion page and database plugins&lt;/a&gt;, including passing the right data type to use a checkbox. Huge shoutout to the plugin team, they rock!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7l4e215try4dr6y5e4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7l4e215try4dr6y5e4i.png" alt=" " width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to call out a few places you need to pay attention to with the Notion plugins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use plugin defaults
&lt;/h2&gt;

&lt;p&gt;If you plan to do multiple tasks with the Notion plugins, particularly multiple tasks with the Notion database plugin, for example, you'll need to reuse some information, like the &lt;code&gt;databaseId&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I like to think I future-proofed this a bit because I only did 3 tasks across the two plugins. Still looks cleaner when you read the entire workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;pluginDefaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.notion&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;apiToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('NOTION_SECRET')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
      &lt;span class="na"&gt;databaseId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('NOTION_CVE_DB')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Passing content back to Notion is a little unintuitive
&lt;/h2&gt;

&lt;p&gt;I ended up having the Notion API docs open because some of the database types took me by surprise.&lt;/p&gt;

&lt;p&gt;For example, a database can have a rich text field. In reality, I really just wanted this to be a string. Sometimes it's super simple like the CVE ID string, other times it's the action plan. So figuring out what I need to pass back to the API via the plugin was a bit awkward at first, because who would guess the rich text field would want an &lt;em&gt;array&lt;/em&gt; of objects...? Not me.&lt;/p&gt;

&lt;p&gt;Other types are much more straightforward like the select (priority) and the checkbox (mitigate now).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#sorry for the weird indents...&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;send_to_notion&lt;/span&gt;
            &lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.notion.database.CreateItem&lt;/span&gt;
            &lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;json(parent.taskrun.value).vulnerabilityName&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
            &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;rich_text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
                  &lt;span class="pi"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                      &lt;span class="pi"&gt;{&lt;/span&gt;
                        &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;json(parent.taskrun.value).cveID&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
                      &lt;span class="pi"&gt;}&lt;/span&gt;
                  &lt;span class="pi"&gt;}&lt;/span&gt;
                &lt;span class="pi"&gt;]&lt;/span&gt;
              &lt;span class="na"&gt;Priority&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.ask_ai[parent.taskrun.value].predictions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;jq('.priority')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
              &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mitigate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now?"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
               &lt;span class="na"&gt;checkbox&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.ask_ai[parent.taskrun.value].predictions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;jq('.mitigate_now')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
              &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Action&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plan"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;rich_text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
                  &lt;span class="pi"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                      &lt;span class="pi"&gt;{&lt;/span&gt;
                        &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outputs.ask_ai[parent.taskrun.value].predictions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;jq('.action_plan')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
                      &lt;span class="pi"&gt;}&lt;/span&gt;
                  &lt;span class="pi"&gt;}&lt;/span&gt;
                &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Added an SLA
&lt;/h2&gt;

&lt;p&gt;In kind of the perfect storm of situations, I did a webinar last week where we talked about "hidden" features, one of them being the &lt;a href="https://go.kestra.io/MpCd7H" rel="noopener noreferrer"&gt;workflow SLA&lt;/a&gt;. I ended up adding one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;sla&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;maxDuration&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MAX_DURATION&lt;/span&gt;
    &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PT1H&lt;/span&gt;
    &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CANCEL&lt;/span&gt; &lt;span class="c1"&gt;#CANCEL, FAIL, NONE&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;sla&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miss&lt;/span&gt;
      &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;durationExceeded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This particular SLA will cancel the execution when it runs for over an hour. I actually exceeded this before my webinar without trying, which was cool because I had a nice example to share. &lt;/p&gt;

&lt;p&gt;Notice I left a comment in the behavior property - you can set the behavior to cancel, fail, or do nothing (none). &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;So that completes this little demo. I mention this in the video, but internally at Kestra we use Notion for our knowledge base, so the idea of having a CVE Tracker table within Notion makes a lot of sense for us. We can track the associated work, assign a reviewer, and have people view the page if they are interested in the progress. &lt;/p&gt;

&lt;p&gt;I'm curious if anyone else out there is using Notion. How are you using it? How would you automate or orchestrate something around your Notion use? &lt;/p&gt;

&lt;p&gt;And before I truly sign off, on my last run we hit 1568 CVEs. So I could definitely look at improving the performance here with a little refactor to &lt;em&gt;only&lt;/em&gt; look at the newest ones every pull.&lt;/p&gt;

</description>
      <category>orchestration</category>
      <category>automation</category>
      <category>security</category>
    </item>
    <item>
      <title>Building a Self-Triaging CVE Checker with Gemini, Kestra, and Notion</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Fri, 03 Apr 2026 18:46:20 +0000</pubDate>
      <link>https://dev.to/missamarakay/building-a-self-triaging-cve-checker-with-gemini-kestra-and-notion-4dek</link>
      <guid>https://dev.to/missamarakay/building-a-self-triaging-cve-checker-with-gemini-kestra-and-notion-4dek</guid>
      <description>&lt;p&gt;I built a CVE checker for a nice enterprise-y use case, and of course, it's getting bigger and bigger as I go "ooooh, what if I add this?!" So this is me taking a break and telling you what I've done so far because this was the original stopping point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;I needed some kind of data to populate a Notion database (basically a table) so I could do something interesting with our &lt;a href="https://go.kestra.io/bEUrbf" rel="noopener noreferrer"&gt;Notion + Kestra plugins&lt;/a&gt;. Bonus points if I could sprinkle in some AI augmentation. Extra bonus points if I could make it a realistic enterprise example. Something that really resonates with the enterprise crowd.&lt;/p&gt;

&lt;p&gt;And immediately I was like - CVEs! &lt;/p&gt;

&lt;h3&gt;
  
  
  The distraction
&lt;/h3&gt;

&lt;p&gt;Side note, I spent far too long last week discovering that things may look like and act like Notion Pages, but a Notion Database is not a Notion Page. So if you give the API a Database id when it wants a Page id, it tells you it doesn't exist. Because a database is not a page. Hence, we have a Kestra plugin for Pages and a separate one for Databases now!&lt;/p&gt;

&lt;p&gt;The Notion API makes you use UUIDs, but the value you need is presented in the URL if you are looking at Notion in a browser... but you need to turn that into a UUID. So my search history looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgbv0lx46m005brnlq5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgbv0lx46m005brnlq5m.png" alt="A Google Search bar and AI summary turning a string of characters into a UUID format" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also use Google Search to do calculations because I could not be bothered to open the calculator app when I'm already in a browser. Follow me for more tips on what Google Search can do. 😂&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiukkyaoze64fbmvqqsgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiukkyaoze64fbmvqqsgi.png" alt="The Kestra flow code editor and topology panels open to show the completed (for now) demo" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I needed a list of CVEs, so I went out to CISA and found their &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;Known Exploited Vulnerabilities Catalog&lt;/a&gt;. They make this available in a few formats, so I found it in &lt;a href="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json" rel="noopener noreferrer"&gt;JSON&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The objects are pretty clean and tidy and look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cveID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CVE-2026-33017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vendorProject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Langflow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"product"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Langflow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vulnerabilityName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Langflow Code Injection Vulnerability"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dateAdded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-25"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shortDescription"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Langflow contains a code injection vulnerability that could allow building public flows without requiring authentication."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"requiredAction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dueDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-08"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"knownRansomwareCampaignUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;github.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;langflow-ai&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;langflow&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;security&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;advisories&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;GHSA-vwmf-pq79-vjvx ; https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;nvd.nist.gov&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;vuln&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;detail&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;CVE-2026-33017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cwes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"CWE-94"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"CWE-95"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"CWE-306"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CVEs are kind of notorious for being hard to understand. They can pop up randomly and the anxiety that comes with trying to decide if your codebase is impacted, plus how fast you need to mitigate them, can make things harder than necessary. So I wanted to augment this a bit and sprinkle in some AI to help. I want Gemini to help me set the priority and action plan and hopefully make it a little easier for a human to parse than the CVE itself.&lt;/p&gt;

&lt;p&gt;I want to pass &lt;em&gt;new&lt;/em&gt; vulnerabilities to AI because, as of writing this, the list is &lt;strong&gt;1557 CVEs&lt;/strong&gt; long and I want to be conscious of token use. I also think it's more realistic for my demo to have a smallish subset of CVEs to triage. &lt;/p&gt;

&lt;p&gt;Once I have this, I want to send it to a Notion Database, where I can have a nice little visual table to assign a human reviewer and create a Notion Page on the specific CVE to capture any implementation details or other notes the human wants to provide for more context on how this applies (or doesn't apply) to us. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329grbjguct486hkf97e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329grbjguct486hkf97e.png" alt="A screenshot of the Notion Database for CVE tracking with 4 items" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More on the design
&lt;/h2&gt;

&lt;p&gt;I should start by saying, as always, I'm not looking to make highly performant, production-ready demos. There are times I want to do something less than ideal to show particular aspects or features of the product and workflow mechanics. The things I make should spark a conversation or ideation. Besides, you know your use case better than I do.&lt;/p&gt;

&lt;p&gt;Now that I got the disclaimer out of the way, let's talk about the design of this demo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Store individual CVE IDs in KV Store
&lt;/h3&gt;

&lt;p&gt;I wanted to store the known CVE IDs in a way that was searchable within Kestra, and to do that I used the &lt;a href="https://go.kestra.io/THnUJV" rel="noopener noreferrer"&gt;KV Store&lt;/a&gt;. The keys map to the CVE IDs and the values are the names. The CVE IDs will always be a specific format, but the names could be quite lengthy. However, I could see a case where I need to reference both in my demo.&lt;/p&gt;

&lt;p&gt;This searchability within Kestra gives an admin a fast way to reference whether this is a known CVE in the system since the table in Notion will only show &lt;em&gt;new&lt;/em&gt; known CVEs. &lt;/p&gt;

&lt;h3&gt;
  
  
  Iterate through the JSON
&lt;/h3&gt;

&lt;p&gt;Since I have this running during off hours, I don't really care how long it takes. With 1500+ CVEs to iterate through, this takes about 20-30 minutes with the concurrency limit set to run some tasks in parallel (&lt;code&gt;5&lt;/code&gt;). Without setting the concurrency limit and just letting this default to running everything sequentially, it takes over an hour. Again, running off hours, I could easily tolerate this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;I'm always like &lt;strong&gt;HOW DO I MAKE THIS EVEN BIGGER&lt;/strong&gt;. What more can I pack into this demo?&lt;/p&gt;

&lt;h3&gt;
  
  
  Could I just iterate over the top of the JSON?
&lt;/h3&gt;

&lt;p&gt;Rethinking how I iterate over the JSON. CVEs don't get reported every day, and sometimes multiple get reported in a single day. I could probably be smarter with the iteration and only "read" until I hit a known CVE in my system and then stop since CVEs are added to the top of the JSON response.&lt;/p&gt;

&lt;p&gt;However, if I wanted to build a really robust example and look for &lt;em&gt;any&lt;/em&gt; edits or updates to the CVE information (like whether there is a new known ransomware campaign) I would still need to iterate through all of them.&lt;/p&gt;

&lt;p&gt;This assumes that the behavior I'm seeing, where the CVEs are added to the top of the JSON, is the typical practice. Since I've only been working with this list for ~4 days, this seems typical. &lt;/p&gt;

&lt;p&gt;How would you approach this?&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-populate Notion pages with more CVE info
&lt;/h3&gt;

&lt;p&gt;I want to pre-populate the page with more info from the CVE. When I add a new item to the database, I get the page id returned. I could then take this page id and send over some content with the rest of the info in the JSON. In the execution outputs, I actually have all that info returned in the Database &lt;code&gt;CreateItem&lt;/code&gt; task, so this would be quite trivial. They even give me the page ID as a UUID!!!!&lt;/p&gt;

&lt;h3&gt;
  
  
  Oops, found a bug
&lt;/h3&gt;

&lt;p&gt;I wanted to add a checkbox about whether it should be mitigated now. To me, this is different than priority, but more of an urgency indicator. There's a bug with the Notion Database plugin where I couldn't pass in a boolean, so I removed the checkbox for now. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;If you want to view or use &lt;a href="https://github.com/akeller/kestra-demos/blob/main/cve_checker.yaml" rel="noopener noreferrer"&gt;this example&lt;/a&gt; you can find it over on GitHub. I do not recommend running it the first time with the AI and Notion tasks enabled because you'll get &lt;strong&gt;1557+ CVEs&lt;/strong&gt; run through Gemini and added to your Notion database. Comment those out for the first run.&lt;/p&gt;

&lt;p&gt;In fact, as I was building this demo the last ~4 days, the CVEs trickled in at a near perfect rate for me to see 1-3 pop into the table, but often I would have to delete a KV item manually to ensure I could get something to populate in my table. &lt;/p&gt;

&lt;p&gt;If you use it as inspiration, let me know what you are building, or what you want to build! Keen eyes will notice I used Kestra EE, but you could definitely build this with Kestra OSS too with a few tweaks for things like secret management. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>orchestration</category>
      <category>security</category>
    </item>
    <item>
      <title>Reflecting on "dead" communities, engagement, and AI</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Tue, 31 Mar 2026 18:04:46 +0000</pubDate>
      <link>https://dev.to/missamarakay/reflecting-on-dead-communities-engagement-and-ai-19hi</link>
      <guid>https://dev.to/missamarakay/reflecting-on-dead-communities-engagement-and-ai-19hi</guid>
      <description>&lt;p&gt;&lt;em&gt;Admittedly this is a bit ranty, and if that's not your jam, feel free to skip.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I stopped scrolling most social media feeds when the slop arrived. First it came in the form of images, big awkward hero images that were psychedelic or had too many arms and fingers. Then it shifted to listicle after listicle. Then the articles that inserted a new line after every... single... sentence.&lt;/p&gt;

&lt;p&gt;I was over it. &lt;/p&gt;

&lt;p&gt;The personal voice and opinions were gone. The images were uncomfortably odd for my brain to process. The attention grabbing tactics were at an all time high and it just wasn't doing it for me anymore. &lt;/p&gt;

&lt;p&gt;So I stopped scrolling. The community that existed on those platforms were dead to me.&lt;/p&gt;

&lt;p&gt;This means I missed things like your promotion or new job or even some significant tech news. Eventually the important things did find me, but I never found myself &lt;em&gt;missing&lt;/em&gt; scrolling. I took that energy to engage somewhere else.&lt;/p&gt;

&lt;p&gt;Fast forward to people saying "this community is dead" or "that community has an engagement problem". The "community" has likely been taken over by garbage that doesn't foster engagement, so the people left. Myself included. Communities are living, breathing organisms and when you fill them with trash, they simply cannot thrive. &lt;/p&gt;

&lt;p&gt;This isn't a post to bash on the admins or the moderators, if they even exist on a particular platform, because that's a hard job, and where do you draw the line in this AI-enabled world? You need content, but you also need engaging content. You need engaged users, but you may need to re-engage users who left. Do we even have the tools and understanding to manage this? Do these platforms have community managers or teams evaluating this?&lt;/p&gt;

&lt;p&gt;Now more than ever people are looking for community, on and offline. They crave it for a variety of reasons, but a sense of belonging, trust, and safety remains. They want to be part of something that connects them to other people in a positive way. People will cultivate community spaces when they feel empowered, dare I say emboldened, to do so. Active and engaged participation is the goal, not casual drive-by headline reading. You want people excited and enthusiastic to show up. And show up regularly.&lt;/p&gt;

&lt;p&gt;So why mention this? Why post this? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Because I love to complain. But mostly if I'm complaining about something, it's because I'm passionate about it. I strongly believe active participants in communities encourage others to do the same - be active participants.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because I think we are over indexing on "communities are dead" and blaming AI. Have you considered that your AI-generated content isn't engaging? Have you considered comments are more important than views, and provoking a discussion is maybe more meaningful? Have you considered you might be the problem, with or without AI? &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2026 is apparently the year where I'm just going to say "we have to live in community" over and over again until I hear people say it back to me. But it's true! If you want an engaged community, you need to lead by example and cultivate the environment you are looking for. &lt;/p&gt;

&lt;p&gt;Does that mean I'm suggesting you can't use AI in your blogs? No. But it does mean you should evaluate your blogs for engagement, AI or otherwise. Would you read it? Would you comment on it if someone else wrote it? &lt;/p&gt;

&lt;p&gt;Are your actions or participation a value-add? Because we can't put admins, moderators, and community managers solely responsible for supporting healthy communities. There needs to be some level of personal accountability.&lt;/p&gt;

&lt;p&gt;And maybe it's more obvious in offline spaces. You won't attend another meetup or event where you felt unsafe or uncomfortable. So if a weird AI hero image made you uncomfortable, why would you read the content underneath? Are you seeing the connection here?&lt;/p&gt;

&lt;p&gt;So I'm really interested in challenging this idea that a particular community is dead. Is it dead? Did you or do you positively or negatively contribute to it? And what does it mean to you if it's gone forever?&lt;/p&gt;

&lt;p&gt;How important is a community to you? And how actively will you participate going forward?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@mauromora?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;mauro  mora&lt;/a&gt;&lt;/em&gt; on &lt;a href="https://unsplash.com/photos/timelapse-photo-of-people-passing-the-street-31-pOduwZGE?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>community</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Are you paying attention to your token use?</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Mon, 23 Mar 2026 13:45:08 +0000</pubDate>
      <link>https://dev.to/missamarakay/are-you-paying-attention-to-your-token-use-5h5n</link>
      <guid>https://dev.to/missamarakay/are-you-paying-attention-to-your-token-use-5h5n</guid>
      <description>&lt;p&gt;Can I get some folks in the comments talking about how closely they monitor their token usage? &lt;/p&gt;

&lt;p&gt;Or if you don't, do you work at a company that provides you unlimited tokens? To specific tools?&lt;/p&gt;

&lt;p&gt;I'm curious to see where people fall on this spectrum.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@cameramandan83?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Dan Dennis&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/brown-round-coins-on-brown-wooden-surface-pZ56pVKd_6c?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What's in a flow?</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Tue, 17 Mar 2026 16:15:27 +0000</pubDate>
      <link>https://dev.to/missamarakay/whats-in-a-flow-532l</link>
      <guid>https://dev.to/missamarakay/whats-in-a-flow-532l</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ivg5tDgdysA" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can orchestrate anything! And therein lies the problem, can you even imagine what your flow could look like? Where do you start? And what components do you include? &lt;/p&gt;

&lt;p&gt;We have a lot of amazing &lt;a href="https://go.kestra.io/GzXbil" rel="noopener noreferrer"&gt;video content on Kestra&lt;/a&gt; where you've probably heard us mention how flows look and what they contain.&lt;/p&gt;

&lt;p&gt;When you are just getting started, it might be hard to really &lt;em&gt;see&lt;/em&gt; what we mean when we say something like "everything has an &lt;code&gt;id&lt;/code&gt; and a &lt;code&gt;type&lt;/code&gt;", particularly when you are looking at the following Hello World boilerplate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;buffalo_875352&lt;/span&gt;
&lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;company.team&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello World! 🚀&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like sure, the &lt;em&gt;one&lt;/em&gt; &lt;a href="https://go.kestra.io/aDKXf3" rel="noopener noreferrer"&gt;runnable task&lt;/a&gt; you can see does, indeed, have an &lt;code&gt;id&lt;/code&gt; and a &lt;code&gt;type&lt;/code&gt;. But is this really important to cover? And why? It's just not really convincing. At least not yet!&lt;/p&gt;

&lt;p&gt;So let's talk through some increasingly complex flows, what components they contain, and get you more familiar with what your next workflow with Kestra could look like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expression syntax &lt;code&gt;{{ }}&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let's increase the complexity from boiler plate and check out my &lt;a href="https://go.kestra.io/rjkn5b" rel="noopener noreferrer"&gt;log_off_flow&lt;/a&gt; and talk about expressions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.kestra.io/EwZ705" rel="noopener noreferrer"&gt;Expression syntax&lt;/a&gt; is critical to passing around information, making flows more dynamic with inputs, and even referencing a particular iteration during something like a &lt;code&gt;ForEach&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.kestra.io/THnUJV" rel="noopener noreferrer"&gt;KV Store&lt;/a&gt; values are pretty straight forward - &lt;code&gt;{{ kv('issues_today') }}&lt;/code&gt;. This simply references the value with the key &lt;code&gt;issues_today&lt;/code&gt;. It's similar for secrets. &lt;/p&gt;

&lt;p&gt;Outputs might be a little more complicated, depending on the type of output - &lt;code&gt;{{ outputs.get_issues.body }}&lt;/code&gt;. This would get the output of the &lt;code&gt;get_issues&lt;/code&gt; task, and specifically the response body of the API request. &lt;/p&gt;

&lt;p&gt;You can also get into some complex filtering and formatting with your expressions - &lt;code&gt;{{ now() | dateAdd(-5, 'DAYS') | date(\"yyyy-MM-dd'T'07:00:00-06:00\") }}&lt;/code&gt;. This is how you would get todays date, but actually 5 days ago and format it in a certain way. &lt;/p&gt;

&lt;h2&gt;
  
  
  Everything really does have an &lt;code&gt;id&lt;/code&gt; and a &lt;code&gt;type&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Once you hit a certain level of complexity in your workflows, you start nesting tasks. This could be due to flowable tasks where you want to do some sort of branching like parallelism in this snippet from the &lt;code&gt;airbyte-sync-parallel-with-dbt&lt;/code&gt; blueprint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data_ingestion&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.flow.Parallel&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;salesforce&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ab&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google_analytics&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12cd&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;facebook_ads&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ef&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether it's a &lt;a href="https://go.kestra.io/ccz5B4" rel="noopener noreferrer"&gt;flowable&lt;/a&gt; or runnable task, it's got (say it with me now): an &lt;code&gt;id&lt;/code&gt; and a &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugin Defaults really do clean up your flow readability
&lt;/h2&gt;

&lt;p&gt;Let's look at that same snippet from the &lt;code&gt;airbyte-sync-parallel-with-dbt&lt;/code&gt; blueprint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data_ingestion&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.flow.Parallel&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;salesforce&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ab&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google_analytics&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12cd&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;facebook_ads&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ef&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may not realize it, but this set of 3 tasks is using &lt;a href="https://go.kestra.io/yNL9A7" rel="noopener noreferrer"&gt;Plugin Defaults&lt;/a&gt; to cover some additional properties, which you can find further down the flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pluginDefaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://host.docker.internal:8000/&lt;/span&gt;
      &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_USERNAME')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_PASSWORD')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without them, that snippet would look more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data_ingestion&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.flow.Parallel&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;salesforce&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ab&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://host.docker.internal:8000/&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_USERNAME')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_PASSWORD')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google_analytics&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12cd&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://host.docker.internal:8000/&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_USERNAME')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_PASSWORD')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;facebook_ads&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.airbyte.connections.Sync&lt;/span&gt;
        &lt;span class="na"&gt;connectionId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e3b1ce92-547c-436f-b1e8-23b6936c12ef&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://host.docker.internal:8000/&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_USERNAME')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret('AIRBYTE_PASSWORD')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's the exact same info x3. It's harder to read and if we needed to make an update to say, the URL, we'd be stuck doing it x3. Not great for maintainability, particularly those of us who typo from time-to-time. &lt;/p&gt;

&lt;p&gt;And nothing is stopping you from using Plugin Defaults when you only use the plugin once. Maybe just pulling those values away from the rest of the plugin properties makes it easier to read and modify. Consider adding comments and group those properties to indicate those &lt;em&gt;could&lt;/em&gt; be modified in the future, but don't touch the rest. &lt;/p&gt;

&lt;h2&gt;
  
  
  Order doesn't matter, mostly
&lt;/h2&gt;

&lt;p&gt;I like my &lt;a href="https://go.kestra.io/XWhPvc" rel="noopener noreferrer"&gt;triggers&lt;/a&gt; at the top of my flow code, by default you may see them toward the bottom. Your topology will show them either at the top or on the left side, depending on how you chose to orient your diagram. Placing them at the top of your flow code makes it easier to read and quickly grasp how this flow could start, but if you have the topology panel open, you could quickly reference that just as easily.&lt;/p&gt;

&lt;p&gt;However, your task order &lt;em&gt;can&lt;/em&gt; matter, particularly if you want to pass outputs from one task to the next. &lt;/p&gt;

&lt;p&gt;You may also want to group tasks in such a way that you contain them to a &lt;a href="https://go.kestra.io/bqq7tX" rel="noopener noreferrer"&gt;working directory&lt;/a&gt;. This is particularly important for tasks that clone repos and/or you want to share those files across scripts.&lt;/p&gt;

&lt;p&gt;You can decide what order makes sense to you. &lt;/p&gt;

&lt;h2&gt;
  
  
  Meaningful, short &lt;code&gt;id&lt;/code&gt;s make your topology a better reference
&lt;/h2&gt;

&lt;p&gt;Again, when you are looking at a minimal flow, meaningful &lt;code&gt;id&lt;/code&gt;s don't really click.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2wf9nyxd1r5xwr99eqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2wf9nyxd1r5xwr99eqw.png" alt="Flow code and topology view in Kestra for the Hello World boilerplate with a single task with id " width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's clear, you don't have to zoom in or move around, and you can see the log icon super clearly. &lt;/p&gt;

&lt;p&gt;But then you do something more interesting and it looks more like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hegwwxaey1snoo00bhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hegwwxaey1snoo00bhp.png" alt=" " width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's an eye chart. Let me zoom in a little and be less dramatic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti2waftoh68lynqt8oou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti2waftoh68lynqt8oou.png" alt=" " width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The longer the ids, the harder they are to really grasp what's happening in the topology. If you prefer to grasp your flow in the flow code directly, this may be less of a problem for you. But keep this in mind if you have project stakeholders who do rely on the topology and try to give them the best experience you can.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errors
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://go.kestra.io/a2xByg" rel="noopener noreferrer"&gt;Errors&lt;/a&gt; can be handled at the flow-level or task-level with the &lt;code&gt;errors&lt;/code&gt; property (which we sometimes refer to as the errors block). Things happen and we want them to fail gracefully or notify the right people or systems to ensure it's handled as gracefully as possible. &lt;/p&gt;

&lt;p&gt;That would look something like this for a flow-level error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;errors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rollout_failure_diagnostics&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;io.kestra.plugin.core.log.Log&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Rollout failed for tenant={{ inputs.tenant_id }}.&lt;/span&gt;
      &lt;span class="s"&gt;execution={{ execution.id }}.&lt;/span&gt;
      &lt;span class="s"&gt;last_error={{ errorLogs()[0]['message'] }}.&lt;/span&gt;
      &lt;span class="s"&gt;Review the latest [PRE]/[PROBE]/[POST] logs for the failing application.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll probably want to reference what input, &lt;code&gt;{{ inputs.x }}&lt;/code&gt;, may have contributed to the failure along with the execution id, &lt;code&gt;{{ execution.id }}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And if you didn't spot it, the errors property does, in fact, have an &lt;code&gt;id&lt;/code&gt; and a &lt;code&gt;type&lt;/code&gt;! &lt;/p&gt;

&lt;h2&gt;
  
  
  Flows as Blueprints
&lt;/h2&gt;

&lt;p&gt;All the flows covered in this blog are available as &lt;a href="https://go.kestra.io/C5LB87" rel="noopener noreferrer"&gt;blueprints&lt;/a&gt;, with the exception of the boilerplate that's included every time you create a new flow from scratch. You can find the blueprints below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;log_off_flow (available in two options: Notion or Confluence)

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://go.kestra.io/rjkn5b" rel="noopener noreferrer"&gt;With Notion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.kestra.io/TARr7a" rel="noopener noreferrer"&gt;With Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.kestra.io/UaFWSj" rel="noopener noreferrer"&gt;airbyte-sync-parallel-with-dbt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.kestra.io/X1YzmY" rel="noopener noreferrer"&gt;argocd-single-tenant-wave-rollout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also find them in the Blueprints menu directly in the Kestra UI, where you can copy or click the "Use" button and use it yourself. &lt;/p&gt;




&lt;p&gt;I hope you enjoyed this walkthrough of different flow components and flows with increasing complexity. I added tons of links so you can go a little deeper on certain topics as you see fit. &lt;/p&gt;

&lt;p&gt;Let me know what you want to see next with Kestra in the comments or come join our community! &lt;/p&gt;

</description>
      <category>automation</category>
      <category>beginners</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Workshopping my "Anatomy of a Kestra Flow" video idea</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Tue, 10 Mar 2026 18:21:34 +0000</pubDate>
      <link>https://dev.to/missamarakay/workshopping-my-anatomy-of-a-kestra-flow-video-idea-d8h</link>
      <guid>https://dev.to/missamarakay/workshopping-my-anatomy-of-a-kestra-flow-video-idea-d8h</guid>
      <description>&lt;p&gt;I pulled together a quick video where I step through 4 different workflows and kind of talk through some ideas I had for more of a polished video. Let me know what you'd like me to focus on or where I should go into more details!&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/t7FBaDudx7c" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>automation</category>
      <category>discuss</category>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>What should I do and learn in 2026?</title>
      <dc:creator>Amara Graham</dc:creator>
      <pubDate>Mon, 02 Mar 2026 19:31:11 +0000</pubDate>
      <link>https://dev.to/missamarakay/what-should-i-do-and-learn-in-2026-4enc</link>
      <guid>https://dev.to/missamarakay/what-should-i-do-and-learn-in-2026-4enc</guid>
      <description>&lt;p&gt;I blinked and it's March. That's not entirely true, January was 100 years long, then February showed up, and at least here in Central Texas, that meant it was harshly cold for like 48 hours and now it's summer. "That's false Spring!" No... we don't have Spring here. &lt;/p&gt;

&lt;p&gt;Anyway, &lt;strong&gt;it's March&lt;/strong&gt; and you might be asking yourself what you should actually be doing this year now that the year is rolling onward. You may have yearly or quarterly goals or metrics, but what are your personal development goals? And do you already feel behind?&lt;/p&gt;

&lt;p&gt;You may be asking yourself what you want to actually &lt;em&gt;do&lt;/em&gt; this year. What do you want to learn? What skills do you want to level up? Never fear, let me provide you with my opinionated list of some of the tactics I recommend for navigating this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use AI and have opinions about popular AI tools
&lt;/h2&gt;

&lt;p&gt;I want to be very clear that I don't think AI is appropriate &lt;em&gt;everywhere&lt;/em&gt;, but I do think if you are in tech you need to have some kind of personal narrative around AI, particularly related to your role. Where you use it, why, and how.&lt;/p&gt;

&lt;p&gt;Someone recently asked if I would let AI write blogs for me, and the answer is &lt;strong&gt;no&lt;/strong&gt;, I barely let any tools spell and grammar check my blogs. I'm sure you can tell. Voice and style aside, which I'm aware an AI can "learn", I find writing very cathartic and if someone else reads and enjoys it, that's a bonus. I have no reason to give that up, but also, where am I going to put this chaotic, GIF-filled corporate rage? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3eTN6OHdxeDVpdDI0MmpzZWprenBvODI1ZDlld3M3eWl3MDE5d2F1MiZlcD12MV9naWZzX3NlYXJjaCZjdD1n/8YEeD1WB5FeyAiONoe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3eTN6OHdxeDVpdDI0MmpzZWprenBvODI1ZDlld3M3eWl3MDE5d2F1MiZlcD12MV9naWZzX3NlYXJjaCZjdD1n/8YEeD1WB5FeyAiONoe/giphy.gif" alt="Schitt's Creek's Alexis going " width="427" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I digress. &lt;/p&gt;

&lt;h3&gt;
  
  
  Claude for summarizing, brainstorming, and ideation
&lt;/h3&gt;

&lt;p&gt;I use Claude for summarizing written content for things like video scripts. My prompts are dead simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Turn this blog into a 2-3 minute video script.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude and I also like to collaborate on talk ideas, titles, and descriptions. This gives me a great base to either edit on my own, entirely rework, or read exactly once and close Claude's window. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make this talk title something people would actually go to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also like asking for summaries on specific docs pages because I want to see a TL;DR that matches my understanding. This leads into the next use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docs AI for search and knowledge checks
&lt;/h3&gt;

&lt;p&gt;I use built-in docs AI for enhanced search and knowledge checks, almost like quizzes in academy courses. Those implementations will heavily depend on the model, but many are good about citing their sources if I feel like I need to fact check.&lt;/p&gt;

&lt;p&gt;If there is both a search and a docs AI, I like to see what results come up when I search or ask a question with similar terms. This is helpful to see and work to improve the UX and "findability" within docs. If search and docs AI are generating different results, or worse, they are not finding what they should, you need to spend some time to fix it before your users get stuck.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copilots
&lt;/h3&gt;

&lt;p&gt;I'm mostly only working on small code bases and demos these days, so I can use Kestra's Copilot or Visual Studio Code's Copilot, something specific to a single file or repo, and this works really well for me. I know some people have other AI agents deep in their organization's tooling, but I don't really need that right now. &lt;/p&gt;

&lt;p&gt;All of this comes back to my experience with AI and my opinions I've developed around it. These options may not work for you, but I would strongly encourage you to develop your own experience and opinions, particularly because it will come up in my next "skill": interviewing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never stop interviewing
&lt;/h2&gt;

&lt;p&gt;This one hurts to type because interviewing is hard, even in the most pleasant interview cycles and job markets. It can evoke a lot of negative feelings and, depending on who you talk to about it, might make it seem like you &lt;em&gt;are&lt;/em&gt; looking for your next opportunity. How you feel after that interview, whether you are truly job seeking or not, can be largely dependent on the interviewer. &lt;/p&gt;

&lt;p&gt;The idea with this one is you "never stop interviewing" so you never lose the skills to interview. You are able to talk about your experience, skills, delivery, and value outside of a yearly or bi-yearly performance review to someone who knows nothing other than maybe what you put on the application and in your resume. &lt;/p&gt;

&lt;p&gt;I heard this one very early on in my career from someone quite senior, and then I heard it reinforced by people in other areas of the org chart. They were clear that they weren't necessarily looking for another position, but they wanted to know what was out there and they wanted to keep these interview skills honed.&lt;/p&gt;

&lt;p&gt;It's also a great reality check to see if you need to do a hard pivot of some kind. Sometimes titles change or roles evolve and you need to be flexible enough to adjust. Interviewing helps you understand what people outside of your current organization are looking for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep your resume updated
&lt;/h2&gt;

&lt;p&gt;I like to visit my resume at least twice a year, typically aligned either with a performance review or the end of the year. What you are trying to avoid is a situation where you &lt;em&gt;need&lt;/em&gt; an updated resume immediately, and you can't possibly figure out how to summarize your role on the fly. &lt;/p&gt;

&lt;p&gt;If you can get really good at having a refined, ready-to-go resume, you should be really good at communicating your role, experience, skills, delivery, value, etc. and interviewing (and performance reviews!) become easier too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find your community, online and offline
&lt;/h2&gt;

&lt;p&gt;I started going to bookstore events last year. I had started reading romance novels for the predictability and comfort that comes with a happily ever after (HEA) or happy for now (HFN). And at some point I realized one of my favorite authors was local and I could actually go see her. And surround myself with people who also thought she and her books were pretty cool too. Not only do these events immediately feel like safe spaces, they remind me that even though I've spent an entire career working mostly with men, there are communities that are almost entirely not-men out there too. &lt;/p&gt;

&lt;p&gt;And it's all about finding balance. Like balancing a stack of books on the way to the cash register when you just came for one. Oopsies!&lt;/p&gt;

&lt;p&gt;More and more community spaces and groups seem to be seeing a post-pandemic-shutdown renaissance. I don't know exactly what's driving that, but I know I'm finding more energy to even get out to tech meetups again. Maybe people are craving those connections again? This makes it a great time to join and explore communities with others doing the exact same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Geek out on something
&lt;/h2&gt;

&lt;p&gt;I like birds. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2ypohwr04ndawdy71x3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2ypohwr04ndawdy71x3.gif" alt="Zombie kid saying " width="499" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not new, this is a life long... hobby...? Birds + AI are apparently a thing this year, with CES summoning AI-powered bird identifying tools. So I acquired some new tech and apps to live my best bird nerd life this year. &lt;/p&gt;

&lt;p&gt;Birds aren't your thing? Find something to go deep into. I'm also big into nail polish and stained glass (copper foil &amp;amp; lead came). Those aren't even close to tech adjacent, but they give me an opportunity to "touch grass" away from a computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what's the plan?
&lt;/h2&gt;

&lt;p&gt;Maybe this wasn't quite the list you were expecting, but I hope it gets you thinking. What is on your list for doing and learning this year? Have you started? There is still so much year left.&lt;/p&gt;

</description>
      <category>career</category>
      <category>learning</category>
      <category>motivation</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
