<?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: Oatnil</title>
    <description>The latest articles on DEV Community by Oatnil (@oatnil).</description>
    <link>https://dev.to/oatnil</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%2F3901364%2F169a5621-3dec-4111-904e-f8be3a4db579.jpeg</url>
      <title>DEV Community: Oatnil</title>
      <link>https://dev.to/oatnil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oatnil"/>
    <language>en</language>
    <item>
      <title>Claude Plans, Codex Executes</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Sun, 19 Jul 2026 09:26:00 +0000</pubDate>
      <link>https://dev.to/oatnil/claude-plans-codex-executes-3mm1</link>
      <guid>https://dev.to/oatnil/claude-plans-codex-executes-3mm1</guid>
      <description>&lt;p&gt;Plenty of developers already work this way: hash out the approach in Claude Code, then copy the conclusion into Codex to implement. The reason is practical, too — you're paying for both subscriptions anyway. Claude is great at planning; letting Codex do the heavy lifting doesn't burn your Claude quota. Both subscriptions earn their keep. The only problem: the "copy-paste" role in the middle is &lt;em&gt;you&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In UnDercontrol, this pipeline works out of the box&lt;/strong&gt;: Claude plans, Codex executes, and the task system is the whiteboard they share — you only step in to review at the key points.&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%2F4gvbbcja2hg8uawfkxaa.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%2F4gvbbcja2hg8uawfkxaa.png" alt="Claude plans, Codex executes — tasks are the shared whiteboard between your AI agents" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Five steps to a working pipeline
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure two agents.&lt;/strong&gt; Claude Code, Codex, and OpenCode are built-in Agent CLI templates — just pick one (any custom command works too). Give the planner Claude Code and the executor Codex. Don't feel like configuring? Even this step can be outsourced — there's a built-in &lt;strong&gt;Agent Creator&lt;/strong&gt;: @mention it, describe the combo you want, and it sets the agents up for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toss the requirement to the planner.&lt;/strong&gt; A rough task is fine — just @planner it. The daemon spins up a Claude Code session on your dev machine: it reads the description, clarifies the requirement, and splits it into subtasks with acceptance criteria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The planner delegates to the executor.&lt;/strong&gt; It @executor-mentions each subtask — an agent-to-agent @mention automatically launches a new workspace session for the other agent, and the delegation chain preserves your access scope.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex executes.&lt;/strong&gt; Each session picks up one subtask: writes code, runs tests, commits, notes progress back on the task, and marks it &lt;code&gt;pending&lt;/code&gt; when done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You step in at exactly two points.&lt;/strong&gt; Approve the plan; review the output.&lt;/li&gt;
&lt;/ol&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%2Fzwufhogqm86me9bbfqo8.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%2Fzwufhogqm86me9bbfqo8.png" alt="From a rough idea to reviewed commits — one pipeline" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole collaboration happens on the task itself — the description is the spec, comments are the conversation, notes are the progress log. Here's a real task detail: the planner's acceptance criteria on the left, the three-way comment thread on the right:&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%2Fesg7jfgmiqbg51nukhsm.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%2Fesg7jfgmiqbg51nukhsm.png" alt="Task detail — the planner writes the spec, the executor reports commits, everything on the record" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Form a squad: Agent Teams
&lt;/h3&gt;

&lt;p&gt;Don't want to conduct two agents by hand every time? Organize them into a &lt;strong&gt;Team&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A Team has one &lt;strong&gt;lead&lt;/strong&gt; and any number of &lt;strong&gt;members&lt;/strong&gt;, and each member carries a delegation hint — "what kind of work routes here." When the lead's session starts, its roster is injected into the prompt automatically — &lt;strong&gt;the lead is born knowing who reports to it, what each specialist is good at, and how to delegate&lt;/strong&gt;.&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%2Fmb81iz7kahyirmj9jzki.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%2Fmb81iz7kahyirmj9jzki.png" alt="Agent Teams — a lead plus members with delegation hints, roster auto-injected into the lead's session" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Claude plans, Codex executes" becomes a one-liner: @mention the dev-team's lead and it arranges the rest. Teams also nest — a member can itself lead another Team, so hierarchy grows naturally while each agent only ever needs to know its direct reports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch everything live
&lt;/h3&gt;

&lt;p&gt;Open a board for the big picture: how much got planned, what's executing, what's waiting for review — one glance. Every agent session's terminal output also streams back to the web in real time — on your laptop, or your phone.&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%2F58juox1ul0482cnrenfs.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%2F58juox1ul0482cnrenfs.png" alt="The AI team delivery board — Planning / Executing / Pending Review / Done" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Typical scenarios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Queue work before bed, review after breakfast.&lt;/strong&gt; Drop three feature requests on the planner at night; wake up to split subtasks and several &lt;code&gt;pending&lt;/code&gt; implementations, each with its own commits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slice a big refactor.&lt;/strong&gt; Claude writes the migration plan and cuts it into 20 small tasks; Codex executes them one by one — roll back exactly the step that goes wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A bug-triage pipeline.&lt;/strong&gt; The planner reproduces, localizes, and writes up the root cause before delegating the fix — the executor gets "what to change, why, and how to verify," not "there's a bug, fix it."&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The combo is yours to choose
&lt;/h3&gt;

&lt;p&gt;Claude + Codex is just one pairing. UnDercontrol is not tied to any AI tool — Claude Code, Codex, OpenCode, or any terminal-based agent can be a lead or a member. Roles are defined by prompts and skills; tools by Agent CLI configuration. Whatever subscriptions you hold and whatever each model is best at, the orchestration is in your hands.&lt;/p&gt;

&lt;p&gt;One more thing: the progress agents write back lives in the same Markdown system as everything you write by hand — tasks, notes, comments, even finance records share one editing experience.&lt;/p&gt;




&lt;p&gt;Want to try it? &lt;a href="https://oatnil.com/docs/download" rel="noopener noreferrer"&gt;Download UnDercontrol&lt;/a&gt;, start the daemon, create a Team, and @mention the lead on your first task.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>agents</category>
    </item>
    <item>
      <title>Virtual Path: Where Tasks Settle into Knowledge and Docs</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Sat, 18 Jul 2026 03:04:01 +0000</pubDate>
      <link>https://dev.to/oatnil/virtual-path-where-tasks-settle-into-knowledge-and-docs-2em2</link>
      <guid>https://dev.to/oatnil/virtual-path-where-tasks-settle-into-knowledge-and-docs-2em2</guid>
      <description>&lt;p&gt;I've watched too many tasks die the moment they hit "Done." The card gets archived and nobody ever opens it again — why we designed it that way, what pitfalls we hit, how it was verified, all buried inside. Two months later someone asks, and you retell it from memory.&lt;/p&gt;

&lt;p&gt;Building UnDercontrol, I've held onto one conviction: a task shouldn't be disposable. Its body is already a Markdown document, its Notes record how it evolved step by step, and the comments keep the arguments from back then. Throwing all of that away when the work is done is just wasteful.&lt;/p&gt;

&lt;p&gt;That's why Virtual Path exists.&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%2Fcabb7z4tzetnmmugt16m.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%2Fcabb7z4tzetnmmugt16m.png" alt="A task's endpoint isn't Done — it's a place in your knowledge tree" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Give a task a place
&lt;/h3&gt;

&lt;p&gt;The idea is simple: every task, every uploaded file, even every Skill can carry a virtual path like &lt;code&gt;/engineering/backend/&lt;/code&gt;. Everything with a path forms one tree — the Explorer. It looks like a file manager, but there are no real directories underneath. Wherever a path exists, a "folder" exists; delete the contents and the folder disappears on its own. You never have to maintain a pile of empty directories.&lt;/p&gt;

&lt;p&gt;When a task is done and worth keeping, drag it into &lt;code&gt;/decisions/&lt;/code&gt; or &lt;code&gt;/engineering/&lt;/code&gt; — it turns from a finished card into a document in your knowledge base. No copy-pasting into another note app; the Notes and comments stay attached.&lt;/p&gt;

&lt;p&gt;And the ones not worth keeping? Leave them. Unfiled tasks sit at the tree root and in the "Unfiled" area, never mixing into the folders you've organized. The tree is curated, not accumulated — you decide what earns a place.&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%2F5pqrnfodiwdm5x8k0gpr.jpg" 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%2F5pqrnfodiwdm5x8k0gpr.jpg" alt="Explorer tree + task as document: the knowledge tree on the left, a settled architecture doc on the right" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diagrams, screenshots, whiteboard photos can live at the same path too, so a topic's text and assets sit side by side — no more digging through a cloud drive for "that one image."&lt;/p&gt;

&lt;p&gt;By the way, this isn't just about tasks. Every writing surface in UnDercontrol — tasks, notes, expense records, account memos — shares the same Markdown editor, so any content can settle down the same way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Many tasks, one document
&lt;/h3&gt;

&lt;p&gt;The more common case is this: a topic wraps up after seven or eight tasks, each holding a few scattered findings, none of them usable as a document on its own.&lt;/p&gt;

&lt;p&gt;These days I hand that job to an agent. Claude Code, Codex, OpenCode — any terminal agent can read through the batch via the ud CLI, distill it into one new document, and file it into the right folder of the tree. The original tasks stay untouched, kept as raw material you can always trace back to. What the knowledge base keeps is the distilled conclusion, not a pile of process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sync it local — offline, and yours
&lt;/h3&gt;

&lt;p&gt;Knowledge living on a server is only step one. My own habit: documents must be able to land on my own disk, editable with whatever editor I like.&lt;/p&gt;

&lt;p&gt;The ud CLI syncs git-style (I wrote about the basics before: &lt;a href="https://oatnil.com/blog/2026/07/07/ud-pull-push/" rel="noopener noreferrer"&gt;Manage Your Tasks Like git: ud pull / push&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ud init /Knowledge/   &lt;span class="c"&gt;# bind the current folder to a virtual path&lt;/span&gt;
ud pull               &lt;span class="c"&gt;# tasks become local .md files&lt;/span&gt;
ud push               &lt;span class="c"&gt;# local edits go back to the server&lt;/span&gt;
ud status             &lt;span class="c"&gt;# see what differs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default vault layout is Obsidian-native:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyVault/
├─ engineering/backend/
│  └─ SSE reconnect backoff.md     ← one .md = one task
├─ notes/SSE reconnect backoff/    ← the task's Notes, grouped per task
│  └─ soak test results.md
├─ attachments/diagram.png         ← resources (--fetch-attachments)
└─ .udignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a pull, this is a fully offline local knowledge base. Plain Markdown on your disk — readable and editable without a connection, works fine on a plane, one &lt;code&gt;ud push&lt;/code&gt; after landing. The data is yours. Both copies.&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%2Fvqxzz153j4hh7vx49t0h.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%2Fvqxzz153j4hh7vx49t0h.png" alt="vault sync: the virtual path tree on the server ⇄ a local Obsidian vault" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of care went into the details; a few worth mentioning: ud writes exactly one &lt;code&gt;ud-id&lt;/code&gt; line into the frontmatter and leaves the rest untouched; rename a file locally and the task title follows after a push; &lt;code&gt;[[wikilinks]]&lt;/code&gt; written in Obsidian get translated into ud's &lt;code&gt;task://&lt;/code&gt; links on push and back again on pull, so clicking works on both sides; files you don't want synced go into &lt;code&gt;.udignore&lt;/code&gt;, gitignore syntax; conflicts are handled git-style — items changed on both sides get flagged and skipped by default, never silently overwritten. And moving over from the older folder structure is a single &lt;code&gt;ud migrate-layout&lt;/code&gt; away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let an agent tidy your tree
&lt;/h3&gt;

&lt;p&gt;Every knowledge base gets messy over time. Folders grow deeper, names drift, stale docs mix with fresh ones — mine too.&lt;/p&gt;

&lt;p&gt;But tidying is exactly the kind of bulk work agents are best at. The vault is just a local folder: after &lt;code&gt;ud pull&lt;/code&gt;, let an agent read the whole tree — restructure folders, merge duplicates, unify naming, move the stale stuff into an archive. All it does is ordinary file operations; you review the diff with git or &lt;code&gt;ud status&lt;/code&gt;, then &lt;code&gt;ud push&lt;/code&gt; when satisfied. The Explorer on the web immediately shows the tidied shape.&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%2Fn15h0oygochrihcpg7ax.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%2Fn15h0oygochrihcpg7ax.png" alt="Layered model: the content layer is your vault, the collaboration layer is ud's overlay" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What makes it safe to let an agent loose here is the clean layering: the vault layer is content — plain text, git-able, anyone can edit it; status, boards, comments, and the Notes timeline are ud's collaboration metadata sitting on top, the way PR comments never get written into the git tree. The agent touches the content layer; the collaboration history loses nothing.&lt;/p&gt;

&lt;p&gt;And a tidied tree isn't locked to one machine. Web, desktop, and mobile all see the same tree: skim an ADR on your phone during the commute, edit properly on the web at your desk, hand batch work to the CLI and agents in the terminal. Organize once, use it anywhere.&lt;/p&gt;




&lt;p&gt;A task's endpoint shouldn't be "Done." Give the things worth keeping a place in your knowledge tree — one drag, one command, or hand it to your agent.&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>productivity</category>
      <category>obsidian</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Growing with UnDercontrol: Time Compounds, and So Does Knowledge</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Fri, 17 Jul 2026 05:06:57 +0000</pubDate>
      <link>https://dev.to/oatnil/growing-with-undercontrol-time-compounds-and-so-does-knowledge-4ac2</link>
      <guid>https://dev.to/oatnil/growing-with-undercontrol-time-compounds-and-so-does-knowledge-4ac2</guid>
      <description>&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%2Fs1wthjmhfn67gy2quyd3.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%2Fs1wthjmhfn67gy2quyd3.png" alt="The compounding curve of knowledge" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I studied architecture. Then I switched careers and became a programmer. Later I left everything familiar behind and moved to Singapore, where I now work as a fullstack / DevOps engineer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Career switchers know what "accumulation" really means
&lt;/h3&gt;

&lt;p&gt;Switching careers means starting from zero: no four years of CS coursework to lean on — every concept had to be chewed through on my own. That's when I picked up a habit: write down every pitfall I hit, every concept that finally clicked, every config I got working. Not out of diligence — out of fear. If I didn't write it down today, I'd pay for it again tomorrow.&lt;/p&gt;

&lt;p&gt;Looking back, that habit is the highest-return investment I've ever made. It carried me through the career switch, through job changes, through moving countries, and eventually through building my own product. Knowledge, like money, compounds — but only if you have an account for it to grow in.&lt;/p&gt;

&lt;p&gt;Over the years, my "account" changed three times: Joplin → Obsidian → UnDercontrol. Each migration wasn't chasing something shiny — it was my understanding of &lt;em&gt;how knowledge should work&lt;/em&gt; leveling up.&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%2Fl9wi5ie7fx4v7i5l0cq6.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%2Fl9wi5ie7fx4v7i5l0cq6.png" alt="Two journeys, one habit" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Joplin era: get things written down (Collect)
&lt;/h3&gt;

&lt;p&gt;My first stop was Joplin. Open source, free, Markdown, encrypted sync — for someone just getting serious about notes, it solved the most important problem: &lt;strong&gt;making "write it down" actually happen&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My early study notes, interview prep, and debugging logs from the career-switch years all piled up there.&lt;/p&gt;

&lt;p&gt;But over time, the notes felt like drawers: easy to put things in, but every note lived in isolation. The notes themselves sat inside the app's database; finding things meant folders and keyword search; there were no real connections between notes. The knowledge was stored — but it just lay there. It didn't appreciate.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Obsidian era: connect the knowledge (Connect)
&lt;/h3&gt;

&lt;p&gt;So I moved to Obsidian: plain local Markdown files, bidirectional links, a knowledge graph, a rich plugin ecosystem.&lt;/p&gt;

&lt;p&gt;This was a genuine upgrade. For the first time, my notes went from "a pile of files" to "a network" — writing something new naturally pulled old notes in. My vault passed a thousand notes in this era, and I could feel the accumulated weight supporting me in retrospectives, in writing, in technical decisions.&lt;/p&gt;

&lt;p&gt;The career switch and the move abroad — the two biggest jumps of my life — were both backed by the same body of notes. That was the first time "the compound interest of knowledge" stopped being a platitude for me.&lt;/p&gt;

&lt;p&gt;But the deeper the accumulation, the more visible the cracks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;My knowledge was locked in a local folder.&lt;/strong&gt; The classic scene: debugging a nasty issue at the office, I suddenly remember — I've hit this exact pit before, and the fix is written up in detail... in Obsidian, on my computer at home. End of story. I can't sync my entire vault onto every machine I touch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The graph is a beautiful lie.&lt;/strong&gt; Mention &lt;code&gt;[[some concept]]&lt;/code&gt; anywhere in a note and it enters the graph. A throwaway reference and a carefully built relationship get equal-weight edges. The more nodes, the prettier the graph — and the less it actually tells you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attachments scattered everywhere.&lt;/strong&gt; Architecture diagrams, flowcharts, PDFs spread across assets folders; move a folder and the links break.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every sync option hurts somewhere.&lt;/strong&gt; Paid sync still needs a client installed; Syncthing can't go on a work machine; Git sync is technically possible and experientially miserable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I needed was simple: &lt;strong&gt;a web page. Log in, full editing, knowledge available anywhere.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  UnDercontrol: make knowledge callable (Compound)
&lt;/h3&gt;

&lt;p&gt;No tool on the market was shaped quite like what I wanted, so I decided to build one. It's also an experiment: how far can one person, plus AI, take a product?&lt;/p&gt;

&lt;p&gt;UnDercontrol is my answer to every crack from the first two eras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Available anywhere&lt;/strong&gt;: log in from any browser; plus a CLI and a desktop app, with &lt;code&gt;ud pull / ud push&lt;/code&gt; syncing tasks to local Markdown files bidirectionally — the convenience of the web &lt;em&gt;and&lt;/em&gt; the reassurance of local files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Links I build explicitly&lt;/strong&gt;: only deliberately created relationships (peer / parent-child) enter the knowledge graph. Every edge means something. High signal, low noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized resources&lt;/strong&gt;: images, PDFs, and attachments stay attached to their context, but you can browse, search, and reuse them all in one unified library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not just tasks&lt;/strong&gt;: UnDercontrol's Markdown editor is shared across every text surface — tasks, notes, finance records, documents, all the same editing experience. A task can be a document, a decision record, a blog draft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-native&lt;/strong&gt;: the knowledge base is open to AI. Claude Code, Codex, OpenCode, or any terminal-based agent can read and write the same knowledge through the CLI. In fact, the post you're reading right now was written by an AI agent inside an UnDercontrol task, drawing on my past notes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the third stage of compounding: knowledge is no longer just &lt;em&gt;stored&lt;/em&gt; or &lt;em&gt;connected&lt;/em&gt; — it can be &lt;strong&gt;called&lt;/strong&gt;. By future me, and by the AI working on my behalf.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time compounds into strength
&lt;/h3&gt;

&lt;p&gt;From architectural drawings to code, from China to Singapore, from Joplin to Obsidian to building my own tool — the career changed, the city changed, the software changed. The habit didn't: &lt;strong&gt;write down what you figured out today&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The essence of compounding isn't the rate of return. It's not stopping. The point of a tool is to make "not stopping" easy enough.&lt;/p&gt;

&lt;p&gt;For me, UnDercontrol is both a product and the container for that habit. I use it every day to manage my tasks, notes, and finances — and to manage the building of UnDercontrol itself. I grow with it, and it remembers everything that time has laid down.&lt;/p&gt;

&lt;p&gt;If you've migrated through Joplin, Obsidian, and a dozen other tools — if you also believe knowledge compounds — come try &lt;a href="https://oatnil.com" rel="noopener noreferrer"&gt;UnDercontrol&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>markdown</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Why Your Board Won't Show What You Actually Care About</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Thu, 16 Jul 2026 09:50:57 +0000</pubDate>
      <link>https://dev.to/oatnil/why-your-board-wont-show-what-you-actually-care-about-6g9</link>
      <guid>https://dev.to/oatnil/why-your-board-wont-show-what-you-actually-care-about-6g9</guid>
      <description>&lt;p&gt;Monday morning, you open the board. What you want to know is what's about to blow up: what's already overdue, what's due this week. The board only tells you what's In Progress.&lt;/p&gt;

&lt;p&gt;There's a lot it won't show you. You want to see work by client, by sprint, by document type — there's no option for that. You want to pull the unassigned tasks into their own column — also no. You want one column watching overdue items, one watching this week's urgent ones, one just holding whatever was touched most recently, all mixed together — can't do it. The only things you can really change are the column names and their order.&lt;/p&gt;

&lt;p&gt;So the board shows you the tool's idea of your work, not yours. The dimensions you care about, it can't hold a single one.&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%2F2mrno1t53ebcfevu691e.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%2F2mrno1t53ebcfevu691e.png" alt="On the left, the three-column board every tool hands you, which can't hold the dimensions you care about; on the right, the board you described in one sentence and an agent built to fit" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why most tools work this way
&lt;/h3&gt;

&lt;p&gt;This isn't one tool's problem. Switch to another and you'll probably still get Todo, In Progress, Done. Most tools look alike because they share an assumption underneath: &lt;strong&gt;a column isn't something you define — it is the status enum, hardwired.&lt;/strong&gt; What you drag a card into is an enum value, not a viewpoint you decide.&lt;/p&gt;

&lt;p&gt;Tools have a reason for this. Flexibility usually costs you tuition. A tool that lets a column be anything tends to hand you a query language, a docs site, and a weekend along with it. Most people don't want to pay that, which is fair, so the tool decides for you: three columns, don't overthink it.&lt;/p&gt;

&lt;p&gt;UnDercontrol takes a different route. It's a task and knowledge management tool where the day-to-day operations can be handled by an AI agent in your terminal and a command line. On a board, that means a column is no longer equal to a status — it's a condition: what kind of task belongs here. Status is just one condition among many, with no special standing. You can split by due date, by person, by tag, by your own custom field, because to the system these are all the same thing.&lt;/p&gt;

&lt;p&gt;As for that tuition, we'll get to how it's waived.&lt;/p&gt;

&lt;h3&gt;
  
  
  Even the out-of-the-box board isn't only statuses
&lt;/h3&gt;

&lt;p&gt;That sounds like a promise until you see it. Create a new board and two of the six default columns aren't statuses at all:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;What it holds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;To Do&lt;/td&gt;
&lt;td&gt;Todo tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In Progress&lt;/td&gt;
&lt;td&gt;In-progress tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Done&lt;/td&gt;
&lt;td&gt;Done tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive&lt;/td&gt;
&lt;td&gt;Archived tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recent Created&lt;/td&gt;
&lt;td&gt;The most recently created, whatever the status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recent Updated&lt;/td&gt;
&lt;td&gt;The most recently touched, whatever the status&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last two have no filter at all — they just sort by time, newest first. They don't belong to any status. They're a viewpoint.&lt;/p&gt;

&lt;p&gt;In a tool where a column equals a status, columns like those are hard to express. Here they're unremarkable, part of the default setup.&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%2Fpub-35d77f83ee8a41798bb4b2e1831ac70a.r2.dev%2Ffeatures%2Fblog%2Fkanban-boards%2Fdefault-board.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%2Fpub-35d77f83ee8a41798bb4b2e1831ac70a.r2.dev%2Ffeatures%2Fblog%2Fkanban-boards%2Fdefault-board.png" alt="The six default columns; the rightmost two, Recent Created and Recent Updated, sort only by time and belong to no status" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  So what about the tuition?
&lt;/h3&gt;

&lt;p&gt;If it's this flexible, doesn't that mean I have to learn a syntax before I can assemble the board I want?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No. You just say what you want.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You: build me a board that tracks deadlines — overdue, this week, next week, and no deadline set. Four columns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it. Claude Code, Codex, OpenCode, or any agent running in your terminal takes it from there. What the fields are called, how the conditions are written, what the YAML looks like, which commands to run — all of that is its job.&lt;/p&gt;

&lt;p&gt;The query language does exist, and it's complete, but it isn't your homework. It's the agent's working language. You hire someone to renovate; you don't need to lay the bricks yourself.&lt;/p&gt;

&lt;p&gt;If you're curious, here's what it wrote for you, without you typing a character:&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;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Board&lt;/span&gt;
&lt;span class="na"&gt;spec&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="s"&gt;Deadline Radar&lt;/span&gt;
  &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&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="s"&gt;Overdue&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deadline&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AND&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;status&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;'done'"&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="s"&gt;This Week&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deadline&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BETWEEN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AND&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;+7d"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice if you can read it, and it makes no difference to your use if you can't. That's the point.&lt;/p&gt;

&lt;h4&gt;
  
  
  And you don't have to teach the agent either
&lt;/h4&gt;

&lt;p&gt;Normally, to get an agent to use some tool, you first write it a manual: how to call it, what the fields are named, what the format is. You teach it once, the tool ships an update, the manual goes stale, and the agent starts making things up.&lt;/p&gt;

&lt;p&gt;UnDercontrol's command line ships with a recipe catalog. The agent doesn't read source and you don't feed it docs — it asks &lt;code&gt;ud cook board&lt;/code&gt; and the tool tells it how to build a board, complete with a runnable example. Its whole learning step is one command. The tool knows how to use itself, so you neither learn it nor teach it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Drag a card in, and the board makes it true
&lt;/h3&gt;

&lt;p&gt;There's another half to the flexibility: how these columns respond to a drag is something no one has to configure.&lt;/p&gt;

&lt;p&gt;The logic is plain. A column says it holds in-progress tasks. Drop a card into it, and the only reasonable meaning is to make that true, so the status flips to in-progress on its own. Another column says it holds cards tagged blog; drop one in and the tag is added, drag it out and the tag comes off.&lt;/p&gt;

&lt;p&gt;You only said what each column holds; how to do it, the system works out itself. There's a quiet benefit to that: a column's description and its behavior can't drift apart, because the second is derived from the first — there's no second copy of the config to go wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  It knows when not to act
&lt;/h3&gt;

&lt;p&gt;Say a column is for what's already overdue. You drop a card into it — should the system change the deadline to yesterday?&lt;/p&gt;

&lt;p&gt;That's a guess. It's probably not what you meant; you may have just dropped it in the wrong place. So it does nothing. Any condition that can't be satisfied by one honest write — time ranges, sorting, fuzzy matching — generates no action at all. Those columns become views you look at, and you can't break them by dragging.&lt;/p&gt;

&lt;p&gt;Here's the real output, a four-column deadline radar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Columns:
    1. Overdue
       query: deadline &amp;lt; now AND status != 'done'
    2. This Week
       query: deadline BETWEEN now AND +7d
    3. Recently Touched
       query: ORDER BY updated_at DESC
    4. Urgent
       query: tags CONTAINS 'urgent'
       on enter: ADD tags 'urgent'  (auto)
       on exit: REMOVE tags 'urgent'  (auto)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first three — overdue, this week, recently touched — have no actions at all; they're read-only views. The fourth, Urgent, is defined by a tag, which one write can satisfy, so dropping a card in adds the tag and dragging it out removes it, all marked &lt;code&gt;(auto)&lt;/code&gt;, none of it configured by hand.&lt;/p&gt;

&lt;p&gt;The system won't invent a write it can't account for. That restraint isn't a shortfall in capability; it's exactly what lets "a column can be anything" be handed to you safely.&lt;/p&gt;

&lt;h3&gt;
  
  
  You see the real thing before it exists
&lt;/h3&gt;

&lt;p&gt;Handing board-building to an agent, the natural worry is what happens if it gets it wrong and makes a mess of your workspace.&lt;/p&gt;

&lt;p&gt;It won't, because there's a gate in the middle. The agent runs a preview first: the system renders the board exactly as it would be created — what each column holds, what a drag would do, all laid out — and then stores nothing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dry run — board would be created (nothing persisted):
  Name:  Blog Pipeline
  Type:  shared  (a group "Board: Blog Pipeline" would be created for sharing)
  Default tags: blog
  Columns:
    1. Idea
       query: status = 'todo' AND tags CONTAINS 'blog'
       on enter: SET status = 'todo'  (auto)
       on enter: ADD tags 'blog'  (auto)
       on exit: REMOVE tags 'blog'  (auto)
    2. Drafting
       query: status = 'in-progress' AND tags CONTAINS 'blog'
       on enter: SET status = 'in-progress'  (auto)
       ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;nothing persisted&lt;/code&gt;. At this point nothing has happened yet.&lt;/p&gt;

&lt;p&gt;So the whole thing becomes: you describe it, the agent previews it, you look at the real result, and if it's off you say change the review column to pending, it previews again, you nod, it lands.&lt;/p&gt;

&lt;p&gt;The key is that &lt;strong&gt;you're reviewing the system's output, not the agent's account of its plan&lt;/strong&gt;. The agent can say the wrong thing, but it can't fake this step's output. So the trust here isn't built on the agent never being wrong — it's that being wrong is fine, because you see it first.&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%2Fwp9bmhvzjgqdcgc65z7b.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%2Fwp9bmhvzjgqdcgc65z7b.png" alt="The deadline radar board an agent built — overdue, this week, and next week grouped by time window, cards showing due dates and assignees" width="800" height="811"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where this shows up
&lt;/h3&gt;

&lt;p&gt;Enough mechanism. Here's where it actually lives.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Monday-morning deadline radar
&lt;/h4&gt;

&lt;p&gt;You've got seven or eight things going at once, and on Monday morning there's only one thing you want to know: what's about to blow up.&lt;/p&gt;

&lt;p&gt;Tell an agent to build a board that tracks deadlines — overdue, this week, next week, no deadline set — and the four columns are there. Every Monday after that, whether the overdue column has anything in it is a glance.&lt;/p&gt;

&lt;p&gt;This board has a reassuring property too: those columns are computed from time, so you can't break them. If you fumble a card into Overdue, the system won't take it upon itself to change your deadline to yesterday — it does nothing. Columns like these are made to be looked at.&lt;/p&gt;

&lt;h4&gt;
  
  
  A team workload view
&lt;/h4&gt;

&lt;p&gt;Anyone running a team has had the question: who's buried, and who's actually free?&lt;/p&gt;

&lt;p&gt;A board with one column per teammate answers it, with a last column for the unassigned. Open it at standup and whose column is stacked, which work is still hanging, you can see without asking.&lt;/p&gt;

&lt;p&gt;A board like this is for looking. It flattens work scattered everywhere onto one screen. When you actually need to change who does what, you go back to the task itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  A content pipeline
&lt;/h4&gt;

&lt;p&gt;Blogging, videos, announcements — underneath they're the same pipeline: idea, drafting, review, published.&lt;/p&gt;

&lt;p&gt;This is a board you drag on. Move a card from Drafting to Review and the status follows, the tag is added, because each column has stated what it holds and the system derives the rest. You just drag; it makes what you said come true.&lt;/p&gt;

&lt;h4&gt;
  
  
  The plan changed, so say one more sentence
&lt;/h4&gt;

&lt;p&gt;Two weeks in, you notice there's no home for archived items. Tell an agent to add an archived column; it takes the board's full current state, previews the change for you, and only lands it once you nod.&lt;/p&gt;

&lt;p&gt;In another tool, changing a board means clicking through it again. Here it's a sentence, and getting it wrong doesn't matter, because you saw it before it took effect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Once it's built, it's still yours
&lt;/h3&gt;

&lt;p&gt;That "add an archived column" works because the board isn't a trail left by clicks — it's something you can lift out whole.&lt;/p&gt;

&lt;p&gt;Export it, edit it, put it back — all fine. That's also why the agent never has to guess when it changes the board: it gets the full current state, not a reconstruction from the UI.&lt;/p&gt;

&lt;p&gt;A side benefit: the board can go into git, be handed to a colleague, be copied to another project. It's an asset of yours, not config locked inside some screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your board, your design, none of the homework
&lt;/h3&gt;

&lt;p&gt;Boards all look alike because the tool made the trade-off for you: simple but dumb, or powerful but you have to learn it.&lt;/p&gt;

&lt;p&gt;UnDercontrol's answer is that you decide what you want, the agent handles how, and the system keeps it from doing the wrong thing.&lt;/p&gt;

&lt;p&gt;So the four-column deadline radar, the by-person team view, the board sliced along your own business dimension — none of these are features someone designed ahead of time. They're just the result of a sentence you said.&lt;/p&gt;

&lt;p&gt;If you want to try it, describe the board you want to your agent. It knows what to do from there.&lt;/p&gt;

</description>
      <category>kanban</category>
      <category>productivity</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>AI Doesn't Just Work Inside UnDercontrol — It Runs UnDercontrol Itself</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Tue, 14 Jul 2026 11:24:55 +0000</pubDate>
      <link>https://dev.to/oatnil/ai-doesnt-just-work-inside-undercontrol-it-runs-undercontrol-itself-5e8m</link>
      <guid>https://dev.to/oatnil/ai-doesnt-just-work-inside-undercontrol-it-runs-undercontrol-itself-5e8m</guid>
      <description>&lt;p&gt;The "agent workbench" idea is heating up. More and more people agree: an AI agent should act like a teammate — pick up tasks, report progress, leave durable output — not just answer questions in a chat box.&lt;/p&gt;

&lt;p&gt;But there's a further question that rarely gets asked: &lt;strong&gt;can the AI operate the platform itself?&lt;/strong&gt; Not just do work inside the system, but &lt;em&gt;run&lt;/em&gt; it for you — tidy up boards, archive stale tasks, maintain tags, distill hard-won steps into a reusable capability.&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%2F6rbbgc1nt0lyxzjduvm0.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%2F6rbbgc1nt0lyxzjduvm0.png" alt="Not just a worker — an operator of the platform itself" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UnDercontrol's answer comes from its core idea: &lt;strong&gt;Everything as Code&lt;/strong&gt;. Because of it, AI here is both a teammate that does the work and an admin that keeps the system in order.&lt;/p&gt;

&lt;h3&gt;
  
  
  The core: Everything as Code — the platform is the AI's control surface
&lt;/h3&gt;

&lt;p&gt;In UnDercontrol, tasks, notes, boards, skills, custom fields — &lt;strong&gt;all of it is plain Markdown + YAML frontmatter&lt;/strong&gt;, managed declaratively through one kubectl-style &lt;code&gt;ud&lt;/code&gt; CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Creating or updating a task is just applying some text&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' | ud apply -f -
---
title: Ship v1
status: in-progress
tags: [release, urgent]
metadata:
  priority: high
---
Pre-release checklist…
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fioft4l3s00ejqy87roac.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%2Fioft4l3s00ejqy87roac.png" alt="Everything as Code — tasks, boards, skills, metadata are all Markdown + one CLI" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the key: &lt;strong&gt;the same abilities an AI agent uses to read and write code — run commands, read and write text — work unchanged on the whole platform.&lt;/strong&gt; It can create tasks, break out subtasks, change statuses, apply tags, build boards (a board is just a saved query), distill a repeated prompt into a new Skill, patch custom fields… Those management actions are themselves code.&lt;/p&gt;

&lt;p&gt;In short: the AI isn't only a &lt;strong&gt;worker&lt;/strong&gt; inside the platform — it can also be an &lt;strong&gt;admin&lt;/strong&gt;, because managing the platform is itself programmable.&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%2Ft1g0hooibn27ukvg2i37.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%2Ft1g0hooibn27ukvg2i37.png" alt="An Engineering board — columns are saved queries the agent can build and reshape" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical scenarios&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Archive everything marked done this week, then spin up a new board filtered by the &lt;code&gt;release&lt;/code&gt; tag" — the agent just does it with &lt;code&gt;ud apply&lt;/code&gt; / &lt;code&gt;ud patch&lt;/code&gt;, no clicking around.&lt;/li&gt;
&lt;li&gt;"Save the debugging steps you just walked through as a Skill" — the agent turns the method from the conversation into a reusable Skill with &lt;code&gt;ud apply&lt;/code&gt;, and the whole team can use it next time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Breaking it down: the UnDercontrol agent workbench
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Agents as teammates.&lt;/strong&gt; Write a requirement as a task, @mention an agent, and it claims the task, reads the description, notes, and links as context, writes code, runs tests, commits, and writes progress back into the notes. What it picks up isn't a black-box issue — it's &lt;strong&gt;structured Markdown it can also edit itself&lt;/strong&gt;.&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%2F8hcnmq29tr2enq3x6bqt.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%2F8hcnmq29tr2enq3x6bqt.png" alt="Task detail — the agent reads the description and writes progress + commits back into the notes timeline" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Daemon / runtime.&lt;/strong&gt; The agent runs on your own dev machine — a background &lt;strong&gt;daemon&lt;/strong&gt; stays connected over SSE and streams the terminal output back in real time. This remote workspace has been in the works since April 2026; today daemon registration, SSE, multi-surface triggering, and session viewing are all in place — you can start and monitor from the web, the desktop app, the CLI, even your phone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusable skills.&lt;/strong&gt; A Skill is a reusable prompt template stored on the server and injected into any agent via &lt;code&gt;ud prompt&lt;/code&gt;. And because everything is code, &lt;strong&gt;an agent can write and revise Skills itself with &lt;code&gt;ud apply&lt;/code&gt;&lt;/strong&gt; — the skill library is a programmable asset that compounds over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not tied to any one agent.&lt;/strong&gt; UnDercontrol is agent-agnostic: an Agent CLI command template plugs in Claude Code, Codex, Cursor, Hermes, or any terminal-based agent. Swap models or tools without swapping workbenches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You own your data.&lt;/strong&gt; Tasks and notes are plain Markdown files with YAML frontmatter, defined by an open &lt;a href="https://github.com/oatnil-top/ud-schemas" rel="noopener noreferrer"&gt;JSON Schema&lt;/a&gt; (MIT) — version them with Git, export anytime, and self-host (Docker Compose / K8s, SQLite / Postgres).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Not just tasks&lt;/strong&gt;: this Markdown editor and the everything-as-code foundation run through every surface of UnDercontrol — tasks, notes, even expenses and resources. The agent workbench isn't a separate module; it's a capability that grows out of that foundation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why "AI can operate the platform itself" matters
&lt;/h3&gt;

&lt;p&gt;In most tools, AI handles the &lt;strong&gt;execution layer&lt;/strong&gt; (write code, run tests), while the &lt;strong&gt;management layer&lt;/strong&gt; — tidying boards, archiving old tasks, maintaining a tag system, distilling experience into SOPs — still sits on humans.&lt;/p&gt;

&lt;p&gt;When the platform itself is code, that line disappears: AI can share both execution and management. Your knowledge base is both &lt;strong&gt;content&lt;/strong&gt; and a &lt;strong&gt;programmable control surface&lt;/strong&gt;. You gain a teammate who does the work — and an admin who keeps the system in order.&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%2Fqdqjrc7bqbsb8w83m2ri.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%2Fqdqjrc7bqbsb8w83m2ri.png" alt="Most tools stop at execution; here AI shares the management layer too" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;The heart of an "agent workbench" is letting AI do the work reliably, leave durable output, and be directed. UnDercontrol goes one step further — via &lt;strong&gt;Everything as Code&lt;/strong&gt;, it lets AI operate the platform itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks, boards, skills, and metadata are all plain Markdown + CLI-manageable code;&lt;/li&gt;
&lt;li&gt;so the same agent can both &lt;strong&gt;work inside the platform&lt;/strong&gt; (write code, report progress) and &lt;strong&gt;operate the platform itself&lt;/strong&gt; (build boards, archive, write Skills, maintain structure);&lt;/li&gt;
&lt;li&gt;all of it agent-agnostic, triggerable from any device, with your data your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In UnDercontrol, AI is both a teammate and an admin.&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%2Fmgn0tj0v8sx26xrg5i0w.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%2Fmgn0tj0v8sx26xrg5i0w.png" alt="Everything as Code — so AI can run the platform, not just work in it" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>programming</category>
    </item>
    <item>
      <title>One Board, the Whole Project in View — A Week with Kanban</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Mon, 13 Jul 2026 04:52:37 +0000</pubDate>
      <link>https://dev.to/oatnil/one-board-the-whole-project-in-view-a-week-with-kanban-4883</link>
      <guid>https://dev.to/oatnil/one-board-the-whole-project-in-view-a-week-with-kanban-4883</guid>
      <description>&lt;p&gt;Monday, 9 a.m. You open UnDercontrol, glance at one board, and already know where this week starts.&lt;/p&gt;

&lt;p&gt;This is your side project &lt;strong&gt;MorningRun&lt;/strong&gt; — a running social app, currently in Sprint 12. Five columns line up across the board: Todo, In Progress, Review, Deployed, Done. What hasn't started, what's stuck, what's waiting on someone else — you can see it all without opening a single task. Let's walk through a whole week with this one board.&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%2F9v09dxzhg3c5jslklyn4.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%2F9v09dxzhg3c5jslklyn4.png" alt="One board, the whole project in view — drag a card, the status updates itself" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Monday: drag from "Todo" to "In Progress"
&lt;/h3&gt;

&lt;p&gt;You grab a card — "Implement Google OAuth login" — and drag it from &lt;strong&gt;Todo&lt;/strong&gt; to &lt;strong&gt;In Progress&lt;/strong&gt;. The moment you let go, the task's status flips to "In Progress" on its own. No dropdown, no form.&lt;/p&gt;

&lt;p&gt;That's the heart of kanban in UnDercontrol: &lt;strong&gt;columns are the stages of your workflow, and dragging is the status change&lt;/strong&gt;. Whichever column a card lands in, the task's status, tags, even custom fields update to match. And it's instant — the same task in your task list is already in sync.&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%2F8dhw3813dxcxla779ctc.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%2F8dhw3813dxcxla779ctc.png" alt="Sprint 12 board overview — Todo / In Progress / Review / Deployed / Done" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tuesday: a card is more than a title
&lt;/h3&gt;

&lt;p&gt;You open that OAuth card. Inside isn't a single dry line — it's a full Markdown document: a requirements checklist, the technical approach, a couple of open questions. This is the task's living document, its single source of truth.&lt;/p&gt;

&lt;p&gt;Below it you append a &lt;strong&gt;note&lt;/strong&gt;: "Callback URL verified on the staging redirect — commit a1b2c3d." Notes are an append-only timeline that records how the work progressed, and each one keeps a full edit history you can roll back to anytime.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Not just tasks&lt;/strong&gt;: UnDercontrol's editor is shared across every text surface. Task bodies, notes, expense memos, account notes — whatever you write, it's the same Markdown experience. Every card on the board is backed by a container that holds the complete picture.&lt;/p&gt;
&lt;/blockquote&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%2F9zzf799jzu0udi13946o.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%2F9zzf799jzu0udi13946o.png" alt="Card detail — Markdown body (requirements, open questions) and the notes timeline on the right" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Wednesday: customize a column, let the board do the chores
&lt;/h3&gt;

&lt;p&gt;The default columns are status-based. But your team added a code-review step, so you &lt;strong&gt;customize a column&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Open "Edit Column" and you only fill in three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Column name&lt;/strong&gt;: Review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match condition&lt;/strong&gt;: &lt;code&gt;status = 'pending' AND tags CONTAINS 'needs-review'&lt;/code&gt; — which cards land here&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic action&lt;/strong&gt;: when a card enters this column, auto-add the &lt;code&gt;needs-review&lt;/code&gt; tag and @-mention your teammate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when you drag the OAuth card into "Review," a few things happen on their own: the tag is added, your teammate gets pinged. &lt;strong&gt;A column's automatic actions are generated from its match condition&lt;/strong&gt;, always in sync; for anything fancier you can add actions manually.&lt;/p&gt;

&lt;p&gt;A few minutes later your teammate leaves a &lt;strong&gt;comment&lt;/strong&gt; on the card: "The callback URL is missing the staging domain in the allow-list." You reply: "Good catch — added it 👍." Comments are a lightweight, threaded discussion — short and focused, back and forth, without switching to IM and without drowning in the body text. The body says "what it is," notes record "how it evolved," and comments are "let's quickly align on this one card."&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%2F1pxauwe9xz6p0xjuyzmh.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%2F1pxauwe9xz6p0xjuyzmh.png" alt="The comment thread on the card — teammate flags the callback URL, you confirm the fix" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One column isn't enough. You add a second custom column, &lt;strong&gt;"Deployed"&lt;/strong&gt;: match condition &lt;code&gt;status = 'pending' AND tags CONTAINS 'deployed'&lt;/code&gt;, and on enter it sets the status to &lt;code&gt;done&lt;/code&gt;. Two custom columns later, the flow from review to shipped runs right on the board.&lt;/p&gt;

&lt;p&gt;This is where kanban gets genuinely powerful — it doesn't just show, it works for you. Drag a card once, and all the status changes, tagging, and notifications happen in one move.&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%2F410sebv28c5gh38b9ulz.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%2F410sebv28c5gh38b9ulz.png" alt="Edit Column dialog — name, match conditions, and the auto-generated query and actions" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thursday: columns don't have to be statuses
&lt;/h3&gt;

&lt;p&gt;Midweek, you realize status columns aren't enough. MorningRun ships next week, and what you really care about is "what must get done this week." So you spin up another board — "Release Sprint" — where the columns aren't Todo / Done but &lt;strong&gt;This Week / Next Week / Backlog&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because behind every column is a query condition. "This Week" filters &lt;code&gt;deadline &amp;lt;= this Sunday&lt;/code&gt;; "Backlog" filters &lt;code&gt;status = 'todo' AND deadline IS NULL&lt;/code&gt;. A board is essentially &lt;strong&gt;a saved query&lt;/strong&gt;, not a folder that holds things — so the same task can appear on both "Sprint 12" and "Release Sprint" with zero duplication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical scenarios&lt;/strong&gt;: one board to push daily development by status; another to plan priorities by time; a separate one per client project. Same set of tasks, several angles, each its own view.&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%2F0y5v7e3q94jnisbb5qbi.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%2F0y5v7e3q94jnisbb5qbi.png" alt="Release Sprint board — columns become This Week / Next Week / Backlog, the same cards from another angle" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Friday: share the board with your team
&lt;/h3&gt;

&lt;p&gt;MorningRun's designer is taking over the UI cards this week. You open the board settings, click "Share," and pick your team group. She sees the board immediately — but &lt;strong&gt;only the tasks that belong to that group&lt;/strong&gt;; your own private tasks stay hidden. Who's read-only and who can move cards is controlled by permissions.&lt;/p&gt;

&lt;p&gt;No extra sync meeting, no "where are we at?" pings. A shared board is where the team stays aligned.&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%2Fswjzops81ucbzojkdped.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%2Fswjzops81ucbzojkdped.png" alt="Share the board with your team group — members see only group tasks, with read/write permissions" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The week, in summary
&lt;/h3&gt;

&lt;p&gt;This week you didn't hold a single "sync meeting" and didn't bounce between apps. One board showed you the whole MorningRun project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drag = status change&lt;/strong&gt; — columns are workflow stages, drop to update, synced instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A card is a complete information container&lt;/strong&gt; — Markdown body + notes timeline + comments behind every card&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom columns do the chores&lt;/strong&gt; — auto-update status, tag, and notify from a match condition; two columns wired up the review-to-shipped flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Columns don't have to be statuses&lt;/strong&gt; — This Week / Next Week / Backlog; a board is a saved query, not a folder&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A shared board = team alignment&lt;/strong&gt; — only group tasks show, permissions controlled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to try it? Open UnDercontrol and drag your first card — and watch the status change itself.&lt;/p&gt;

</description>
      <category>kanban</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>projectmanagement</category>
    </item>
    <item>
      <title>At 1 A.M., an AI Writes Blog Posts Inside My Task System</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Sun, 12 Jul 2026 02:23:39 +0000</pubDate>
      <link>https://dev.to/oatnil/at-1-am-an-ai-writes-blog-posts-inside-my-task-system-5f8i</link>
      <guid>https://dev.to/oatnil/at-1-am-an-ai-writes-blog-posts-inside-my-task-system-5f8i</guid>
      <description>&lt;p&gt;At eight in the morning, coffee in hand, I open my kanban board. Sitting in the Pending column is a new task:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2026-07-12 Blog Draft (scheduled)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inside it: a complete blog draft. And in the comment thread, two messages left overnight:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;01:01&lt;/strong&gt; — On it — topic scan done, picking task-management-overview. Drafting now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;01:03&lt;/strong&gt; — Done — draft is in the note. Task set to pending for review.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The author is not a person. It's an AI agent. While I was asleep, it picked a topic, checked the product docs, wrote the draft, moved the task to "pending review", and said hi in the comment thread.&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%2Fa4jccz0vt09mrpfnlxt6.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%2Fa4jccz0vt09mrpfnlxt6.png" alt="Kanban board with the blog draft task sitting in the Pending Review column" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I read the draft and replied with one line: "Too broad. Find one concrete use case and tell it as a story." A few minutes later, the draft had been rewritten — the post you are reading now is the product of that rewrite.&lt;/p&gt;

&lt;p&gt;This post is about how that pipeline is built, and why a task system is the most comfortable handoff point between humans and AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  A task is not just a to-do item
&lt;/h3&gt;

&lt;p&gt;First, a core design idea: in UnDercontrol, &lt;strong&gt;a task is a universal information container&lt;/strong&gt;, not just a to-do.&lt;/p&gt;

&lt;p&gt;A task can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An actual to-do ("fix the validation bug on the login page")&lt;/li&gt;
&lt;li&gt;A document (a design proposal, meeting minutes, a wiki page)&lt;/li&gt;
&lt;li&gt;A decision record (why we chose option B)&lt;/li&gt;
&lt;li&gt;A blog draft (this post's draft lives as a note on a task)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The task body is Markdown. Combined with tags and custom metadata, you decide what a task &lt;em&gt;is&lt;/em&gt; — instead of being boxed in by the tool's data structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem: I want a steady blog, without starting from zero every day
&lt;/h3&gt;

&lt;p&gt;Anyone building a product knows this: content needs to ship consistently, but the activation energy of writing is brutal. Picking a topic, gathering material, structuring, drafting — every step burns energy that should have gone into code.&lt;/p&gt;

&lt;p&gt;Let the AI write and publish fully automatically? No. Content that ships without a human gatekeeper burns your own reputation.&lt;/p&gt;

&lt;p&gt;What I wanted was a &lt;strong&gt;human–AI pipeline&lt;/strong&gt;: the AI does the grunt work (topic dedup, doc research, first draft), and I only do the one step that's actually worth my time — judgment and feedback.&lt;/p&gt;

&lt;p&gt;So the question becomes: &lt;strong&gt;where does the AI's work go? Where do I review it? How does feedback flow back?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer: all of it lives in the task system.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pipeline: 24 hours in the life of one task
&lt;/h3&gt;

&lt;p&gt;There is no dedicated "AI platform" here. The pipeline is assembled from four native capabilities of the task system: scheduled jobs, @mentions, notes, and comments.&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%2Frq1sdotm5flhrgpgihrt.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%2Frq1sdotm5flhrgpgihrt.png" alt="The 24-hour handoff loop: scheduled job creates the task, mention wakes the agent, draft lands as a note, human reviews in the morning" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;01:00 — The scheduled job fires&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A daily scheduled job (CRON) creates the day's draft task. The task description is the complete instruction set for the AI, and it opens by @mentioning my agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;@ud-agent&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;mention://member/...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

Generate ONE blog DRAFT for review — do NOT run the full publish pipeline.
&lt;span class="p"&gt;
1.&lt;/span&gt; Pick a topic from &lt;span class="sb"&gt;`auto/blog-topics.json`&lt;/span&gt;. Skip topics already covered —
   check with &lt;span class="sb"&gt;`ud grep task "&amp;lt;slug&amp;gt;"`&lt;/span&gt;. Choose the first uncovered topic.
&lt;span class="p"&gt;2.&lt;/span&gt; Write ONLY the text draft as a NOTE on THIS task.
&lt;span class="p"&gt;3.&lt;/span&gt; Set THIS task status to &lt;span class="sb"&gt;`pending`&lt;/span&gt; and reply in the comment thread.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the design here: &lt;strong&gt;the task description is the prompt&lt;/strong&gt;. Instructions, boundaries ("do NOT publish"), acceptance criteria ("set to pending") — all written into the task. No separate configuration system needed. The task &lt;em&gt;is&lt;/em&gt; the config.&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%2Fmqtuup3e2pox5jtr9af5.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%2Fmqtuup3e2pox5jtr9af5.png" alt="Scheduled Jobs page showing the daily 01:00 blog-draft job" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;01:01 — The @mention wakes the agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The mention triggers an agent work session. It wakes up on my Mac, and the first thing it does is not writing — it's detective work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the topic list (a JSON file in the repo, 18 candidate topics)&lt;/li&gt;
&lt;li&gt;Search old tasks with &lt;code&gt;ud grep task&lt;/code&gt; and &lt;code&gt;ud query "tags CONTAINS 'blog'"&lt;/code&gt; to see which topics are already covered&lt;/li&gt;
&lt;li&gt;Sweep 27 historical blog tasks, find only 2 topics left uncovered — pick the first one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it leaves its first message in the comment thread ("On it — picking task-management-overview") before writing a word. It also reads the product docs to verify feature details first — an AI's worst habit is confidently making things up, and making it read the docs first cures most of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;01:03 — The draft lands, the task flips to pending&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The finished draft doesn't go to some "AI output panel" — it's attached to the task as a &lt;strong&gt;note&lt;/strong&gt;. The task status is set to &lt;code&gt;pending&lt;/code&gt;, which in our status model means "I'm done, waiting on someone else." The agent leaves a second message in the thread and clocks out.&lt;/p&gt;

&lt;p&gt;The whole run took two minutes, and it happened after I fell asleep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;08:00 — I come online, and only judge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My review interface is just the task detail page: the draft in a note, the context in the description, the agent's work log in the comment thread. I don't need to open any other tool.&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%2F204bzycnbew5ut9yvcty.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%2F204bzycnbew5ut9yvcty.png" alt="Task detail page: the scheduled prompt as description, the draft as a note below" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I read the draft and replied with one line in the thread. That line triggered a new agent session — it read the feedback, &lt;strong&gt;updated the same note via &lt;code&gt;note_id&lt;/code&gt;&lt;/strong&gt; (not a new note; notes keep full edit history, so a bad rewrite can always be rolled back), then replied in the thread describing what changed.&lt;/p&gt;

&lt;p&gt;Back and forth, it feels like collaborating with a remote teammate through a ticket. Except this teammate starts work at 1 A.M. and never complains about rework.&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%2F10xy1sqp6po992g3bat1.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%2F10xy1sqp6po992g3bat1.png" alt="The comment thread: agent reports progress, human replies with one-line feedback, agent confirms the rewrite" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the handoff point is a task, not a chat window
&lt;/h3&gt;

&lt;p&gt;The biggest problem with collaborating with AI in a chat window is that &lt;strong&gt;output sinks&lt;/strong&gt;. What it wrote yesterday is fifty screens up today; switch sessions and the context is gone.&lt;/p&gt;

&lt;p&gt;Make the handoff point a task, and every part of the exchange gets a native container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task description&lt;/strong&gt; = requirements and instructions (a living document, always current)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notes&lt;/strong&gt; = deliverables and process records (an append-only timeline with edit history)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comments&lt;/strong&gt; = lightweight conversation (short, threaded, with @ notifications)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt; = position in the workflow (&lt;code&gt;pending&lt;/code&gt; means "awaiting review" — one glance at the board shows everything waiting on you)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And humans and AI access all of it through &lt;strong&gt;the same entrance&lt;/strong&gt;. I read on the web and my phone; the agent reads and writes from the terminal via the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ud describe task 51c4981e      &lt;span class="c"&gt;# read the task (notes, comments, attachments included)&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;draft.md | ud apply &lt;span class="nt"&gt;-f&lt;/span&gt; -   &lt;span class="c"&gt;# write a note&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the entrance is CLI + Markdown, the pipeline is not tied to any specific AI tool — Claude Code, Codex, OpenCode, or any terminal-based agent can plug in. Swap the agent tomorrow; the pipeline doesn't change by a single line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where else this pattern applies
&lt;/h3&gt;

&lt;p&gt;The blog draft is just the most convenient example. The same loop — "scheduled job / @mention → agent works → notes for the record → pending for review → feedback in comments" — also runs our:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Release verification&lt;/strong&gt;: after CI ships a version, a task is created with the release notes attached; the agent runs smoke tests and writes results into a note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily standup&lt;/strong&gt;: a scheduled job creates a standup task every day; the agent summarizes yesterday's changes across all tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code research&lt;/strong&gt;: throw "evaluate option X" at the agent, wake up to a comparison in the notes, ask follow-ups in the comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's only one common thread: &lt;strong&gt;every step of the AI's work stays in the task, and the human appears only at the checkpoints.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaway
&lt;/h3&gt;

&lt;p&gt;This pipeline uses no concept invented specifically for AI. Scheduled jobs, @mentions, notes, comments, status — all of it is what a task system already has. It's just that when your task system meets three conditions, it naturally becomes a human–AI workbench:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Markdown-native&lt;/strong&gt; — AI reads and writes without a translation layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A CLI entrance&lt;/strong&gt; — any terminal agent can plug in; no vendor lock-in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status + comments + notes, all first-class&lt;/strong&gt; — handoff, review, and records each have their place&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One more thing: this very post is what the pipeline produced in the small hours of July 12, 2026. The version you just read is the second draft — written after a human replied with a single line: "Too broad. Find one concrete use case and tell it as a story."&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>automation</category>
    </item>
    <item>
      <title>Turn Any Web Page into Clean Markdown for Your AI — UnDercontrol Web Clipper</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Sat, 11 Jul 2026 02:18:52 +0000</pubDate>
      <link>https://dev.to/oatnil/turn-any-web-page-into-clean-markdown-for-your-ai-undercontrol-web-clipper-13cd</link>
      <guid>https://dev.to/oatnil/turn-any-web-page-into-clean-markdown-for-your-ai-undercontrol-web-clipper-13cd</guid>
      <description>&lt;p&gt;You want to hand a web article to an AI — to summarize it, translate it, or ask questions about it. How do you do that today?&lt;/p&gt;

&lt;p&gt;Select-all and copy? You paste a mess of navigation bars, ads, recommendation widgets, and broken formatting. Send the link? Many AI tools can't fetch pages, and when they can, the result is often incomplete.&lt;/p&gt;

&lt;p&gt;The UnDercontrol &lt;strong&gt;Web Clipper&lt;/strong&gt; Chrome extension gives you a cleaner answer: click &lt;strong&gt;Copy Markdown&lt;/strong&gt;, and the page's article content is extracted into tidy Markdown on your clipboard — &lt;strong&gt;no login, no account, no configuration&lt;/strong&gt;. Install it and it works on any page. Paste it into Claude, ChatGPT, or any AI, and what it gets is pure content with zero noise.&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%2Fy91gkoysvmq5wvtto8rk.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%2Fy91gkoysvmq5wvtto8rk.png" alt="Web Clipper popup — Copy Markdown and Save to Local, no login required" width="640" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy Markdown: copy, redesigned for the AI era
&lt;/h2&gt;

&lt;p&gt;This is the extension's most-used feature, and it doesn't depend on an UnDercontrol server at all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-click copy&lt;/strong&gt;: the page's article content lands on your clipboard as clean Markdown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart extraction&lt;/strong&gt;: powered by Readability + Turndown — ads, navigation, sidebars, and other non-content elements are stripped automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero barrier&lt;/strong&gt;: no sign-up, no login; works instantly on any page&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust&lt;/strong&gt;: heavy elements like video and canvas are skipped automatically, so complex pages won't drag your browser down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Markdown is an AI's native language — clean structure, no markup noise. For the same article, pasting Markdown instead of a raw select-all copy gets you noticeably better comprehension and answers, and saves tokens too.&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%2Fs88c5ziylep5sz4x8iqk.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%2Fs88c5ziylep5sz4x8iqk.png" alt="Web page to clean Markdown to your AI — one click, no login" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Save to Local: archive without logging in
&lt;/h2&gt;

&lt;p&gt;Local save also works without any login. One click downloads two files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A complete HTML snapshot&lt;/strong&gt;: built on the open-source &lt;a href="https://github.com/gildas-lormeau/SingleFile" rel="noopener noreferrer"&gt;SingleFile&lt;/a&gt;, it inlines HTML, CSS, images, and fonts into a single self-contained file that opens offline, exactly as the page looked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The extracted Markdown&lt;/strong&gt;: the same clean article content that Copy Markdown produces&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Links rot and pages get redesigned, but a snapshot is forever the page as it was the moment you saved it. Archive articles, research material, and time-sensitive pages — no server required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Save to UnDercontrol: clipping joins your workflow
&lt;/h2&gt;

&lt;p&gt;If you use UnDercontrol (the extension connects via login or an API key — self-hosted instances work out of the box), clipping goes one step further: the page becomes a &lt;strong&gt;task&lt;/strong&gt;.&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%2F2p7gaye4k5tns21jneef.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%2F2p7gaye4k5tns21jneef.png" alt="Web Clipper ready view — title prefilled, tags, Save Page" width="640" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Markdown content goes into the task description&lt;/strong&gt; — readable and editable right inside the task&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The HTML snapshot is attached&lt;/strong&gt; to the task, so you can always reconstruct the original page&lt;/li&gt;
&lt;li&gt;From there you get the full task toolkit: tags, kanban boards, links to other tasks, notes for your conclusions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI agents can reach it&lt;/strong&gt;: through the ud CLI, Claude Code, Codex, OpenCode, or any terminal-based AI agent can read the task — the description already contains ready-to-use Markdown, so the agent never needs to scrape the web page itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a task produced by a real clip: the description starts with the source URL, the body is the extracted Markdown, and the full HTML snapshot hangs off the attachments panel:&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%2Fzf6f3z1h66eo89rijiu2.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%2Fzf6f3z1h66eo89rijiu2.png" alt="A clipped task — source URL and Markdown in the description, HTML snapshot attached" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In UnDercontrol, a task has never been just a to-do item — it's a universal information container. Web clipping is simply one more way for information to enter it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Bilibili video subtitles become transcripts
&lt;/h2&gt;

&lt;p&gt;Web Clipper also ships with &lt;strong&gt;Bilibili transcript extraction&lt;/strong&gt;: on a Bilibili video page, the extension detects the video and lights up a &lt;strong&gt;Save Transcript&lt;/strong&gt; button that turns CC or AI-generated subtitles into a formatted Markdown transcript — download it locally or save it as an UnDercontrol task. Finish a tech talk video, and the transcript is archived in one click; handing it to an AI for a summary is one more.&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%2F4nu6d9fw6hqcpgm8mv19.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%2F4nu6d9fw6hqcpgm8mv19.png" alt="Bilibili video detected — Save Transcript in one click" width="640" height="906"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical scenarios
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feed your AI&lt;/strong&gt;: copy a long article as Markdown and paste it into any AI to summarize, translate, or interrogate — far cleaner than pasting a link or a raw copy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-later that actually happens&lt;/strong&gt;: clip a worthwhile article into a task with a deadline; write your action items into the task notes when you're done&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive research&lt;/strong&gt;: clip competitors' pricing and feature pages into a research board — when they redesign next week, you still hold today's snapshot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bug evidence&lt;/strong&gt;: a third-party page misbehaves? Clip a full snapshot onto the bug task; even after the page recovers, the scene is preserved&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video study notes&lt;/strong&gt;: turn a Bilibili tech video's subtitles into a Markdown transcript — archive it or let an AI distill the key points&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install and configure
&lt;/h2&gt;

&lt;p&gt;Install from the &lt;a href="https://chromewebstore.google.com/detail/undercontrol-web-clipper/mckkbigikfkoeddpcbhdmpncoljoagog" rel="noopener noreferrer"&gt;Chrome Web Store&lt;/a&gt;. &lt;strong&gt;Copy Markdown and local save work immediately with zero configuration&lt;/strong&gt;; only "save as task" needs a connection to your UnDercontrol server — log in directly, or create an API key (starts with &lt;code&gt;ak_&lt;/code&gt;) under &lt;strong&gt;Settings → API Keys&lt;/strong&gt; in the web app.&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%2Ficikv77ljv45y1q6x5nd.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%2Ficikv77ljv45y1q6x5nd.png" alt="Login to server — username/password or API key, only needed for saving as tasks" width="640" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Chrome internal pages (&lt;code&gt;chrome://&lt;/code&gt;, &lt;code&gt;chrome-extension://&lt;/code&gt;) cannot be captured&lt;/li&gt;
&lt;li&gt;Full snapshots of pages heavy with dynamic content can take up to 2 minutes&lt;/li&gt;
&lt;li&gt;A snapshot is a point-in-time copy — it won't change when the original page does (which is exactly the point)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Web Clipper browser extension itself is open source under AGPL-3.0: &lt;a href="https://github.com/oatnil-top/ud-chrome-extension" rel="noopener noreferrer"&gt;github.com/oatnil-top/ud-chrome-extension&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Without logging in, it's a clean "web page to Markdown + local archive" tool, born for feeding content to AI. Logged in, every clip lands in a task system with tags, kanban boards, and AI-agent access. Next time you want to hand a web page to an AI, try Copy Markdown first.&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>chrome</category>
    </item>
    <item>
      <title>Tags and Custom Fields: Organize Tasks by Your Own Dimensions</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Thu, 09 Jul 2026 13:11:19 +0000</pubDate>
      <link>https://dev.to/oatnil/tags-and-custom-fields-organize-tasks-by-your-own-dimensions-2hed</link>
      <guid>https://dev.to/oatnil/tags-and-custom-fields-organize-tasks-by-your-own-dimensions-2hed</guid>
      <description>&lt;p&gt;Most tools decide for you what a task "looks like": a few fixed dropdowns, a hard-coded set of fields, someone else's taxonomy. But in reality every person, every team, every workflow wants to track different dimensions — one needs "priority", another needs "client", "estimate", "department", and someone else just wants to slap on a tag and filter later.&lt;/p&gt;

&lt;p&gt;UnDercontrol doesn't impose structure. It gives you three composable layers: &lt;strong&gt;free-form tags&lt;/strong&gt;, &lt;strong&gt;typed custom fields&lt;/strong&gt;, and &lt;strong&gt;arbitrary key-value metadata&lt;/strong&gt;. All three are directly queryable, so you can slice the &lt;em&gt;same&lt;/em&gt; set of tasks along &lt;em&gt;your&lt;/em&gt; dimensions instead of bending to the tool's taxonomy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This rests on a core UnDercontrol idea: &lt;strong&gt;a task is not just a to-do&lt;/strong&gt; — it's a universal container for information. The same Markdown editor runs across tasks, notes, expenses, and accounts — every text surface. Tags and custom fields are how you layer &lt;em&gt;your own structure&lt;/em&gt; on top of that container.&lt;/p&gt;
&lt;/blockquote&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%2Fmvhv6nu2paz9eqzv475l.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%2Fmvhv6nu2paz9eqzv475l.png" alt="The same set of tasks, sliced freely by tags / custom fields / key-value metadata" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Free-form tags: the lightest way to organize
&lt;/h2&gt;

&lt;p&gt;A tag is just free text you jot down — no predefined vocabulary, write whatever you want (&lt;code&gt;work&lt;/code&gt;, &lt;code&gt;urgent&lt;/code&gt;, &lt;code&gt;client-acme&lt;/code&gt;, &lt;code&gt;bug&lt;/code&gt;, all fine).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autocomplete built in&lt;/strong&gt;: as you type, suggestions come from tags you've used before (ordered by recency) — free-form, yet you won't misspell or spawn ten spellings for one concept.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch tagging&lt;/strong&gt;: on the task search page you can add or remove tags across a batch of tasks at once, no need to open each one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not only on tasks&lt;/strong&gt;: tags also apply to resources (uploaded files), so you can thread files and tasks together with one shared vocabulary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tags themselves are a queryable array field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tags CONTAINS 'work'                   -- has the work tag
tags IN ('work', 'personal')           -- has work or personal
tags CONTAINS_ALL ('work', 'urgent')   -- has both work and urgent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Typical scenario&lt;/strong&gt;: a batch of related tasks lands on you — slap a shared &lt;code&gt;q3-launch&lt;/code&gt; tag on all of them, then aggregate them from any board with &lt;code&gt;tags CONTAINS 'q3-launch'&lt;/code&gt;. When the push is done, keep the tag as an archival breadcrumb, or batch-delete 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%2Fmu1og7nift2nykbzi5qf.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%2Fmu1og7nift2nykbzi5qf.png" alt="The task-detail tag input, with the historical-tag autocomplete dropdown expanded" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Custom fields: typed, structured dimensions
&lt;/h2&gt;

&lt;p&gt;Tags solve "attach a word". But when what you track has a &lt;em&gt;type&lt;/em&gt; and a &lt;em&gt;value range&lt;/em&gt; — priority is a number, department is a fixed set of options, owner is a specific member — reach for custom fields.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Custom Fields&lt;/strong&gt; page (&lt;code&gt;/custom-fields&lt;/code&gt;, also reachable from a task's properties, the kanban menu, or the command palette) you define a field and pick its type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text&lt;/strong&gt; — free text value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Number&lt;/strong&gt; — numeric, supports comparisons&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select&lt;/strong&gt; — a fixed set of options you list up front&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkbox&lt;/strong&gt; — a yes / no boolean&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt; — pick a member from your workspace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also mark a field required. Once defined, the field shows up in task detail for inline editing, and the value is stored on that task.&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%2Fdxupxp136f8m55b8h6n5.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%2Fdxupxp136f8m55b8h6n5.png" alt="The Custom Fields page and the " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope a field by tag
&lt;/h3&gt;

&lt;p&gt;Here's the key design choice: a custom field doesn't have to apply to every task. When you create a field you pick its &lt;strong&gt;scope&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All tasks&lt;/strong&gt; — every task shows this field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tasks with specific tags&lt;/strong&gt; — only tasks carrying the chosen tags show the field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "tags" and "custom fields" mesh naturally: a task's detail page only surfaces the fields that &lt;strong&gt;match its tags&lt;/strong&gt; — irrelevant fields stay out of your way. Tag a task &lt;code&gt;bug&lt;/code&gt; and "repro steps" / "severity" appear; tag it &lt;code&gt;sales&lt;/code&gt; and "client" / "amount" show up instead.&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%2F71ld3iqy6eh79az2sn79.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%2F71ld3iqy6eh79az2sn79.png" alt="A task tagged bug: the properties panel automatically shows bug-scoped fields like Severity and Reviewer" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical scenario&lt;/strong&gt;: a team runs "engineering bugs" and "sales follow-ups" side by side. Scope the bug fields to the &lt;code&gt;bug&lt;/code&gt; tag and the sales fields to the &lt;code&gt;sales&lt;/code&gt; tag. In one board, each kind of task shows only its own field set, with no cross-talk — no need to split into two systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Arbitrary key-value: for the ad-hoc and the off-schema
&lt;/h2&gt;

&lt;p&gt;Not every piece of metadata is worth defining a field for. Task detail also has an &lt;strong&gt;extra metadata&lt;/strong&gt; section where you drop arbitrary key-value pairs on a task (e.g. &lt;code&gt;jira: PROJ-123&lt;/code&gt;, &lt;code&gt;source: customer email&lt;/code&gt;) without declaring anything in settings first.&lt;/p&gt;

&lt;p&gt;This layer is the buffer between "free tag" and "formal custom field": jot it down first, and once a key gets used often enough to become a stable dimension, promote it to a typed custom field.&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%2Frm1keblxxlvnnkm29ali.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%2Frm1keblxxlvnnkm29ali.png" alt="Free key-value pairs on a task: jira, external_id, source — no upfront definition needed" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical scenario&lt;/strong&gt;: tasks synced in from an external system carry a pile of loose fields (ticket number, source link, external ID) — stash them as key-value pairs verbatim. Whichever key later turns out to need frequent filtering, formalize it into a custom field.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Querying them: the &lt;code&gt;cf.&lt;/code&gt; prefix and kanban columns
&lt;/h2&gt;

&lt;p&gt;The real leverage of custom fields is that &lt;strong&gt;they're queryable just like built-in fields&lt;/strong&gt;. Reference a custom field in a query with the &lt;code&gt;cf.&lt;/code&gt; prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cf.priority &amp;gt; 5                          -- priority above 5
cf.priority IN (1, 2, 3)                 -- priority is 1, 2, or 3
cf.department = 'engineering'            -- engineering department
cf.priority IS NULL                      -- tasks with no priority set
cf.priority &amp;gt; 5 AND status = 'todo'      -- high-priority todos
cf.priority &amp;gt; 5 ORDER BY updated_at DESC -- high priority, newest first
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom fields combine freely with built-in fields (&lt;code&gt;status&lt;/code&gt;, &lt;code&gt;tags&lt;/code&gt;, &lt;code&gt;deadline&lt;/code&gt;, …) in one query. And in UnDercontrol, &lt;strong&gt;every kanban column is essentially a saved query&lt;/strong&gt; — so you can build a column called "High-priority todos" whose condition is &lt;code&gt;cf.priority &amp;gt; 5 AND status = 'todo'&lt;/code&gt;, and any task that matches drops into it automatically, no manual dragging. The task search page can surface custom fields as columns too.&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%2F0g79eglru1rs3d2yxgl1.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%2F0g79eglru1rs3d2yxgl1.png" alt="The kanban column condition builder: Tags has #bug AND Custom: Severity = critical, generating the query tags CONTAINS 'bug' AND cf.severity = 'critical'" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical scenario&lt;/strong&gt;: build a "by client" board for the team, one column per client, each column's condition &lt;code&gt;cf.client = '...'&lt;/code&gt;; a new task snaps into place the moment its client field is filled. The same set of tasks becomes "by priority" or "by department" with a different query — the view follows the dimension, the data stays single-source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;UnDercontrol doesn't decide which dimensions your tasks should have — it hands you three layers to stack from light to heavy as needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free-form tags&lt;/strong&gt; — zero-cost, jot-and-go, batchable, autocompleted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom fields&lt;/strong&gt; — typed (text / number / select / checkbox / user), optionally required, and &lt;strong&gt;scopable by tag&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arbitrary key-value&lt;/strong&gt; — for ad-hoc and off-schema info, promotable to a real field anytime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common foundation under all three is one query language: &lt;code&gt;tags CONTAINS_ALL(...)&lt;/code&gt;, &lt;code&gt;cf.priority &amp;gt; 5&lt;/code&gt;, freely combined with built-in fields, then frozen into kanban columns. The same set of tasks, sliced however you like — the structure is yours, not the tool's.&lt;/p&gt;

&lt;p&gt;All of this rests on UnDercontrol's "a task is not just a to-do" idea: one unified information container, one editor across every text surface, plus tags and fields that let you define your own dimensions. Pair it with Claude Code, Codex, OpenCode, or any terminal-based agent to read and write this structured data — but you always keep the wheel on how it's organized.&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%2Fgqws8giink6ynlcvcsgf.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%2Fgqws8giink6ynlcvcsgf.png" alt="One dataset, many cuts: the same tasks sliced into different kanban views by tag / cf.priority / cf.client" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>devtools</category>
      <category>taskmanagement</category>
      <category>cli</category>
    </item>
    <item>
      <title>Everything is a Task: One Container for To-dos, Docs, Notes, and a Knowledge Graph</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Wed, 08 Jul 2026 06:59:47 +0000</pubDate>
      <link>https://dev.to/oatnil/everything-is-a-task-one-container-for-to-dos-docs-notes-and-a-knowledge-graph-5a8</link>
      <guid>https://dev.to/oatnil/everything-is-a-task-one-container-for-to-dos-docs-notes-and-a-knowledge-graph-5a8</guid>
      <description>&lt;p&gt;Unix has a famous design philosophy: &lt;strong&gt;everything is a file&lt;/strong&gt;. Directories, devices, pipes, sockets — all read and written through one uniform interface. Simple, unified, composable.&lt;/p&gt;

&lt;p&gt;UnDercontrol borrows the same idea, just with a different primitive: &lt;strong&gt;everything is a Task&lt;/strong&gt;.&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%2F80rb6wme5xlcnsdlgxek.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%2F80rb6wme5xlcnsdlgxek.png" alt="Everything is a Task" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most tools treat a "task" as a single line with a checkbox. UnDercontrol never did. Here, a &lt;strong&gt;Task is a universal information container&lt;/strong&gt; — it can be a to-do, a document, a reminder, a blog draft, meeting minutes, a decision record, even a wiki page. One data source, organized your way, all in one place.&lt;/p&gt;

&lt;p&gt;You don't hop between apps; an AI agent needs just one tool to reach everything you have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three content layers
&lt;/h3&gt;

&lt;p&gt;Every task is made of three layers, each with a design intent — but you're free to use them however you like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Design intent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task body&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;The living, canonical document — the Single Source of Truth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;An append-only timeline — how this unit of information evolved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Plain text&lt;/td&gt;
&lt;td&gt;Lightweight, threaded discussion — short and focused&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The body is a living document where you keep the complete, coherent narrative; notes record progress over time (session start, each commit, blockers hit); comments are the quick conversation around the content. Clean separation — and all plain text, so both humans and AI read it directly, with no conversion.&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%2F6dykc2jo6mwhsra0qb9x.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%2F6dykc2jo6mwhsra0qb9x.png" alt="Task detail: Markdown body, tags, status, deadline, notes timeline, and a relation graph at a glance" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A single task detail page makes the point: it's not one line of to-do, but a living document with a Markdown body, tags, status, deadline, a notes timeline, subtasks, and a relation graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  One content, many views
&lt;/h3&gt;

&lt;p&gt;Because there's only one primitive underneath — the Task — UnDercontrol can offer many views over the same data, switchable anytime:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;List view&lt;/strong&gt;: linear and filterable, great for scanning and batch work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kanban view&lt;/strong&gt;: drag cards to change status, manage in-flight workflow visually&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calendar view&lt;/strong&gt;: laid out by deadline, so timing is obvious at a glance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree view&lt;/strong&gt;: expand parent-child relationships to see the hierarchy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph view&lt;/strong&gt;: traverse links, parents, and subtasks as a graph to see how knowledge connects&lt;/li&gt;
&lt;/ul&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%2F75shukef73z820ceoe9y.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%2F75shukef73z820ceoe9y.png" alt="The same data, four perspectives: Kanban, List, Calendar, Graph" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A board isn't "another container" — it's essentially a &lt;strong&gt;saved query&lt;/strong&gt;. The same task can appear on many boards at once, with zero duplication. You change the perspective, not the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Six statuses that match real workflow
&lt;/h3&gt;

&lt;p&gt;Tasks support six statuses that fit how real work moves: &lt;code&gt;todo&lt;/code&gt;, &lt;code&gt;in-progress&lt;/code&gt;, &lt;code&gt;pending&lt;/code&gt; (awaiting confirmation/review), &lt;code&gt;done&lt;/code&gt;, &lt;code&gt;archived&lt;/code&gt;, and &lt;code&gt;stale&lt;/code&gt;. Dragging on the board updates status automatically — and status itself is information: one glance tells you where everything stands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tell things apart with tags and metadata, not folders
&lt;/h3&gt;

&lt;p&gt;If everything is a task, then a "document" and a "to-do" are structurally the same thing. What sets them apart is never the structure — it's &lt;strong&gt;tags, metadata, and views&lt;/strong&gt;. UnDercontrol forces neither a tagging convention nor a folder hierarchy on you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tags&lt;/strong&gt;: free-form labels you define (&lt;code&gt;doc&lt;/code&gt;, &lt;code&gt;meeting&lt;/code&gt;, &lt;code&gt;reminder&lt;/code&gt; — anything)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First-class metadata&lt;/strong&gt;: title, status, tags, deadline, assignee, links — the 20% that covers 80%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom metadata&lt;/strong&gt;: unlimited key-value pairs (&lt;code&gt;doc_type: rfc&lt;/code&gt;, &lt;code&gt;client: acme&lt;/code&gt;), all queryable too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you need precise retrieval, UnDercontrol also gives you a SQL-like query language and natural-language queries — save common conditions as board columns and complex filtering is one step away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Virtual folders + AI: organize information like files
&lt;/h3&gt;

&lt;p&gt;Prefer a "folder" style of organizing? UnDercontrol has that too — &lt;strong&gt;virtual folders&lt;/strong&gt;. Every task carries a &lt;code&gt;path&lt;/code&gt; field (a virtual path, a first-class part of the schema, e.g. &lt;code&gt;/Work/Alpha/&lt;/code&gt;) that adds up to a familiar file tree in the app; drag to file things away. An empty path means "unfiled", &lt;code&gt;/&lt;/code&gt; is the root, &lt;code&gt;/Work/Alpha/&lt;/code&gt; is a specific folder — and it's not just tasks: resources (attachments), skills, and other entities share the same virtual paths, placed in one tree.&lt;/p&gt;

&lt;p&gt;It even syncs between local and cloud like Git: &lt;code&gt;ud pull /Work/Alpha/&lt;/code&gt; checks a virtual directory out into a local folder (creating a &lt;code&gt;.ud/&lt;/code&gt; to hold sync state, just like &lt;code&gt;.git/&lt;/code&gt;), edit it with whatever editor you like, and &lt;code&gt;ud push&lt;/code&gt; sends it back. To move a folder, just move it locally and &lt;code&gt;ud push&lt;/code&gt; updates the cloud path.&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%2Fppsn91rm88y8utfyww5u.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%2Fppsn91rm88y8utfyww5u.png" alt="Virtual folders + AI: organize with a file tree, let AI re-file for you" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What makes organizing truly effortless is &lt;strong&gt;adding AI&lt;/strong&gt;. Because the whole structure is plain text plus paths, an AI agent can read your full picture and tidy it up for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Move all these scattered meeting notes under &lt;code&gt;/Meetings/2026-Q3/&lt;/code&gt;" — the AI rewrites paths in bulk, one sentence&lt;/li&gt;
&lt;li&gt;"Organize this project's tasks into a clean folder structure" — the AI reads the content, decides where things belong, and reorganizes&lt;/li&gt;
&lt;li&gt;"Split this into subtasks and archive the old ones" — the AI handles the splitting, filing, and status changes together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude Code, Codex, OpenCode, or any terminal-based agent can do this through one uniform CLI. You do the thinking; the AI puts information where it belongs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bi-directional links: weave tasks into a knowledge graph
&lt;/h3&gt;

&lt;p&gt;Tasks can connect in several ways: &lt;strong&gt;peer links&lt;/strong&gt; relate two things; &lt;strong&gt;parent/subtask&lt;/strong&gt; relationships break a big goal into executable steps. With the graph view, your task base becomes a traversable knowledge network rather than a pile of isolated entries.&lt;/p&gt;

&lt;p&gt;Inside the body, notes, and comments you can also reference other entities with Markdown links — another task &lt;code&gt;[Title](task://...)&lt;/code&gt;, a note &lt;code&gt;[## Heading](note://...)&lt;/code&gt;, an @mention &lt;code&gt;[@name](mention://member/...)&lt;/code&gt;, even an embedded uploaded image &lt;code&gt;![shot](resource://...)&lt;/code&gt;. The whole base is interconnected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not just tasks: one editor across every text surface
&lt;/h3&gt;

&lt;p&gt;"Everything is a task" has one more layer: UnDercontrol's Markdown editor is &lt;strong&gt;not task-only&lt;/strong&gt; — it's reused everywhere you write in the app: task bodies, notes, even the memos on finance records (expenses, accounts). The editing experience, Markdown syntax, and embedded links and images you know from tasks are identical elsewhere. Learn it once, use it everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attachments and collaboration
&lt;/h3&gt;

&lt;p&gt;Tasks let you &lt;strong&gt;drag files in or paste from the clipboard&lt;/strong&gt; — screenshots, design mockups, documents stay next to the task they belong to. Storage can be local or S3-compatible object storage; your data stays under your control.&lt;/p&gt;

&lt;p&gt;For collaboration, tasks are shared through &lt;strong&gt;groups&lt;/strong&gt; with role-based read/write permissions. The same task can appear on a shared board where teammates discuss and update progress — you share the information, not your whole account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typical scenarios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Personal knowledge base&lt;/strong&gt;: keep meeting notes, decision records, and reading notes all as tagged tasks; retrieve them anytime with queries and boards — one app holds it all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI agent collaboration&lt;/strong&gt;: Claude Code, Codex, OpenCode, or any terminal-based agent reads and writes tasks, appends notes, and records progress through one uniform CLI — human and AI share one source of truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product/engineering pipeline&lt;/strong&gt;: requirements in the task body, progress in notes, review comments in comments; track status flow on a board and see dependencies in the graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content creation&lt;/strong&gt;: a blog's Chinese draft, English draft, and social copy each live as a note; the task itself is the Single Source of Truth, and everything published outward is derived from it.&lt;/li&gt;
&lt;/ul&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%2Fjt5ts9p9437lox1r2mna.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%2Fjt5ts9p9437lox1r2mna.png" alt="Graph: tasks woven into a traversable knowledge network" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In summary
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Everything is a task&lt;/strong&gt; — not just a slogan, but UnDercontrol's underlying design: a Markdown-native, AI-ready universal container, with many views, six statuses, bi-directional links, flexible tags and metadata, and one editor across the whole app. No more shuttling things between a to-do tool, a notes tool, and a docs tool — it all belongs in one place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start here
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🏠 &lt;strong&gt;Website &amp;amp; docs&lt;/strong&gt;: &lt;a href="https://oatnil.com" rel="noopener noreferrer"&gt;oatnil.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;CLI installation guide&lt;/strong&gt;: &lt;a href="https://oatnil.com/docs/cli" rel="noopener noreferrer"&gt;oatnil.com/docs/cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;Desktop App &amp;amp; self-hosting&lt;/strong&gt;: &lt;a href="https://oatnil.com/subscribe" rel="noopener noreferrer"&gt;oatnil.com/subscribe&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One universal container, one home for all your work — try it now with &lt;code&gt;npm install -g @oatnil/ud&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>markdown</category>
      <category>devtools</category>
      <category>cli</category>
    </item>
    <item>
      <title>Manage Your Tasks Like git: ud pull / push Local Bidirectional Sync</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Tue, 07 Jul 2026 00:46:37 +0000</pubDate>
      <link>https://dev.to/oatnil/manage-your-tasks-like-git-ud-pull-push-local-bidirectional-sync-570m</link>
      <guid>https://dev.to/oatnil/manage-your-tasks-like-git-ud-pull-push-local-bidirectional-sync-570m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In one sentence: &lt;code&gt;ud pull&lt;/code&gt; checks your cloud tasks, notes, and attachments out as local Markdown files, and &lt;code&gt;ud push&lt;/code&gt; sends your local edits back. As natural as &lt;code&gt;git clone&lt;/code&gt; and &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Many working copies, one server, edit from anywhere.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fqlwbi4nbmsco1zsi6he0.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%2Fqlwbi4nbmsco1zsi6he0.png" alt="UnDercontrol server and a local folder syncing bidirectionally via ud pull / ud push — edit locally with Obsidian, VS Code, an AI agent, or any tool" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why we built this
&lt;/h3&gt;

&lt;p&gt;UnDercontrol has always been built on one core belief: &lt;strong&gt;your data is yours&lt;/strong&gt;. Tasks, notes, ledgers, resources — every piece of text is plain Markdown, never locked into any single app.&lt;/p&gt;

&lt;p&gt;But "exportable" isn't enough. What developers actually want is to &lt;strong&gt;treat that content as local files&lt;/strong&gt; — edit it with their favorite editor, feed it to AI tools, and sync the changes back when done.&lt;/p&gt;

&lt;p&gt;So we built a git-style command-line sync: &lt;code&gt;ud init&lt;/code&gt; / &lt;code&gt;ud pull&lt;/code&gt; / &lt;code&gt;ud push&lt;/code&gt; / &lt;code&gt;ud status&lt;/code&gt;. There are no new concepts to learn — if you know git, you already know how to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three commands, the exact same mental model as git
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ud command&lt;/th&gt;
&lt;th&gt;git equivalent&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ud pull /Work/Alpha/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check a cloud virtual directory out into the current folder and bind them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ud status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;See what changed locally and remotely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ud push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push local changes back to the cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ud init /Work/Alpha/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publish an existing local folder as a cloud directory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first &lt;code&gt;ud pull /Work/Alpha/&lt;/code&gt; &lt;strong&gt;binds&lt;/strong&gt; the current directory to the virtual path &lt;code&gt;/Work/Alpha/&lt;/code&gt;: a &lt;code&gt;.ud/&lt;/code&gt; folder appears to hold sync state (just like &lt;code&gt;.git/&lt;/code&gt;), and the contents of &lt;code&gt;/Work/Alpha/&lt;/code&gt; land directly in the folder. Every &lt;code&gt;ud pull&lt;/code&gt; after that is &lt;strong&gt;incremental&lt;/strong&gt; — only changed items are downloaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In an empty folder, init + checkout in one step&lt;/span&gt;
ud pull /Work/Alpha/

&lt;span class="c"&gt;# Later: incrementally pull all tracked paths&lt;/span&gt;
ud pull

&lt;span class="c"&gt;# See what changed on both sides&lt;/span&gt;
ud status

&lt;span class="c"&gt;# Push local changes back (shows a change list for confirmation first)&lt;/span&gt;
ud push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fkv7cncjxiuruob9omege.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%2Fkv7cncjxiuruob9omege.png" alt="Local folder layout: one task is one folder, index.md is the task body, every note is its own .md file, and .ud/ holds the sync state" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it looks like locally: a task is a folder, a note is a file
&lt;/h3&gt;

&lt;p&gt;The checked-out structure exactly mirrors the &lt;strong&gt;virtual folder&lt;/strong&gt; hierarchy inside UnDercontrol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alpha/
├── .ud/                      # sync state (like .git/)
│   └── tracking.json
├── Design-Doc/               # one task = one folder
│   ├── index.md              # task body (YAML frontmatter + description)
│   ├── Kickoff-notes.md      # every note = one .md file
│   └── Review-notes.md
├── Sprint-Plan/
│   └── index.md
└── architecture.png          # resources = plain files, placed by virtual path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;index.md&lt;/code&gt; and it's clean Markdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&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;8f3c...&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Design Doc&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;in-progress&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;design&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;alpha&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;deadline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-07-20&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## Background&lt;/span&gt;
The task description body goes here…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few deliberate design choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content is stored verbatim&lt;/strong&gt; — in-app links like &lt;code&gt;resource://&lt;/code&gt;, &lt;code&gt;task://&lt;/code&gt;, and &lt;code&gt;note://&lt;/code&gt; stay exactly as they are. Sync is a &lt;strong&gt;byte-level round-trip&lt;/strong&gt;; your content is never rewritten.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The virtual path is not written into frontmatter&lt;/strong&gt; — the folder's location on disk is the single source of the path. Want to move a task to another directory? Move the folder locally, and &lt;code&gt;ud push&lt;/code&gt; updates the cloud path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File names are sanitized&lt;/strong&gt;, with the original names kept in &lt;code&gt;.ud/tracking.json&lt;/code&gt; — special characters and non-ASCII names are handled for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  On push, ud figures out what you did
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ud push&lt;/code&gt; compares your working directory against the "last known state" in &lt;code&gt;.ud/tracking.json&lt;/code&gt;, item by item, and infers the right action:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you did locally&lt;/th&gt;
&lt;th&gt;What ud push does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Created a task folder (with index.md), or a loose &lt;code&gt;.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Creates a task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Added a new &lt;code&gt;.md&lt;/code&gt; inside a task folder&lt;/td&gt;
&lt;td&gt;Creates a note on that task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Added a non-&lt;code&gt;.md&lt;/code&gt; file&lt;/td&gt;
&lt;td&gt;Uploads it as a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edited index.md / a note / a resource file&lt;/td&gt;
&lt;td&gt;Updates it in the cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moved a file/folder to another directory&lt;/td&gt;
&lt;td&gt;Updates the cloud virtual path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deleted a file/folder&lt;/td&gt;
&lt;td&gt;Soft-deletes in the cloud (recoverable)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In other words: &lt;strong&gt;create a &lt;code&gt;My-Idea.md&lt;/code&gt; file locally, run &lt;code&gt;ud push&lt;/code&gt;, and it becomes a task in UnDercontrol&lt;/strong&gt;. And the other way around: a task created in the cloud shows up locally after &lt;code&gt;ud pull&lt;/code&gt;. Truly bidirectional.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conflicts: like git, nothing gets silently overwritten
&lt;/h3&gt;

&lt;p&gt;If the same task was modified both locally and in the cloud, &lt;code&gt;ud&lt;/code&gt; marks it as a &lt;strong&gt;conflict&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ud push&lt;/code&gt; &lt;strong&gt;skips&lt;/strong&gt; conflicting items by default (and tells you to pull first), or use &lt;code&gt;--force&lt;/code&gt; to overwrite the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ud pull&lt;/code&gt; &lt;strong&gt;keeps the local&lt;/strong&gt; version by default, or use &lt;code&gt;--keep-remote&lt;/code&gt; to let the cloud win.&lt;/li&gt;
&lt;li&gt;In an interactive session, it asks you &lt;strong&gt;item by item&lt;/strong&gt; which version to keep.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run &lt;code&gt;ud status&lt;/code&gt; first, then decide — no data is ever silently lost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Many working copies, one server, anywhere
&lt;/h3&gt;

&lt;p&gt;In git's model, one origin can have any number of local clones. &lt;code&gt;ud&lt;/code&gt; works the same way — &lt;strong&gt;on top of one server, you can have any number of local tracked folders&lt;/strong&gt;, each bound to a different virtual path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laptop              Desktop            Another Mac / server
~/work/alpha  →     D:\notes\alpha  →   ~/proj-x
  binds /Work/Alpha/   binds /Work/Alpha/  binds /Projects/proj-x/
        \                 |                    /
         \                |                   /
          ┌──────────────────────────────────┐
          │      one UnDercontrol server      │
          │ (virtual folders = source of truth)│
          └──────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This buys you a few very practical things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One repo per place, fully independent&lt;/strong&gt;: &lt;code&gt;/Work/Alpha/&lt;/code&gt; and &lt;code&gt;/Projects/proj-x/&lt;/code&gt; are separate tracking roots, each with its own &lt;code&gt;.ud/&lt;/code&gt; state. Check out only the slice you care about right now instead of pulling your entire knowledge base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View and edit from anywhere&lt;/strong&gt;: on any device, &lt;code&gt;ud pull&lt;/code&gt; gets you the latest, and &lt;code&gt;ud push&lt;/code&gt; syncs your edits to everyone and every client. On your phone? Just open the Web or desktop App — &lt;strong&gt;same server, same data&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Humans and AI share one source of truth&lt;/strong&gt;: you edit in Obsidian on your laptop, an AI agent edits via the CLI on a server, teammates edit in the App — everything converges on the same virtual path on the same server, and &lt;code&gt;ud status&lt;/code&gt; always shows who changed what.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: &lt;strong&gt;the server is the single source of truth, and local folders are just its working copies&lt;/strong&gt;. It's the model git has validated for twenty years — applied to your tasks and knowledge base instead of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not just tasks: your whole knowledge base as files
&lt;/h3&gt;

&lt;p&gt;This part matters: UnDercontrol's Markdown editor is &lt;strong&gt;shared across every text surface&lt;/strong&gt; — tasks, notes, even the memo fields on expenses and accounts are all the same Markdown. So what &lt;code&gt;ud pull&lt;/code&gt; checks out isn't an isolated "todo-list export" — it's a &lt;strong&gt;local mirror of your entire knowledge base&lt;/strong&gt;, ready to be opened, edited, and pushed back with any tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typical scenarios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manage tasks in Obsidian / VS Code&lt;/strong&gt;: &lt;code&gt;ud pull&lt;/code&gt; into your vault, enjoy your familiar editor, keybindings, and plugins, then &lt;code&gt;ud push&lt;/code&gt; when done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let AI agents read and write your tasks directly&lt;/strong&gt;: hand the synced folder to Claude Code, Codex, OpenCode, or any terminal-based agent — it can read task context, append notes, even batch-create tasks, because to the agent they're just ordinary local &lt;code&gt;.md&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep tasks next to your code&lt;/strong&gt;: run &lt;code&gt;ud init /Projects/proj-x/&lt;/code&gt; in the project root and version design docs and decision records right alongside the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write offline&lt;/strong&gt;: edit local files on a plane or in the subway; one &lt;code&gt;ud push&lt;/code&gt; syncs everything once you're back online.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local backup&lt;/strong&gt;: a single &lt;code&gt;ud pull&lt;/code&gt; is a plain-text, human-readable, never-expiring full backup.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Get started in three steps
&lt;/h3&gt;

&lt;p&gt;UnDercontrol is a workbench that puts tasks, knowledge base, and AI agents in one place, with a &lt;strong&gt;desktop App&lt;/strong&gt; and &lt;strong&gt;self-hosting&lt;/strong&gt; support — your data stays private, portable, and yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1️⃣ Install the CLI (30 seconds)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @oatnil/ud
&lt;span class="c"&gt;# Don't want to install? Use npx:&lt;/span&gt;
npx @oatnil/ud &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2️⃣ Pull, then edit with whatever you like&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ud pull /Work/     &lt;span class="c"&gt;# check a virtual directory out locally&lt;/span&gt;
ud status          &lt;span class="c"&gt;# see what changed on both sides&lt;/span&gt;
ud push            &lt;span class="c"&gt;# push it back&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3️⃣ Grab the desktop App / self-host your own server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want a GUI, multi-device access, or the whole server running on your own machine? See the links below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start here
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🏠 &lt;strong&gt;Website &amp;amp; docs&lt;/strong&gt;: &lt;a href="https://oatnil.com" rel="noopener noreferrer"&gt;oatnil.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;CLI installation guide&lt;/strong&gt;: &lt;a href="https://oatnil.com/docs/cli" rel="noopener noreferrer"&gt;oatnil.com/docs/cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;Desktop App &amp;amp; self-hosting&lt;/strong&gt;: &lt;a href="https://oatnil.com/subscribe" rel="noopener noreferrer"&gt;oatnil.com/subscribe&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your data, your format, your tools. UnDercontrol just makes them flow — try it now with &lt;code&gt;npm install -g @oatnil/ud&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>cli</category>
    </item>
    <item>
      <title>Everything as Code: When Your Tasks Become Markdown You Can Commit to Git</title>
      <dc:creator>Oatnil</dc:creator>
      <pubDate>Mon, 06 Jul 2026 00:13:04 +0000</pubDate>
      <link>https://dev.to/oatnil/everything-as-code-when-your-tasks-become-markdown-you-can-commit-to-git-1h3f</link>
      <guid>https://dev.to/oatnil/everything-as-code-when-your-tasks-become-markdown-you-can-commit-to-git-1h3f</guid>
      <description>&lt;p&gt;We've all gotten used to "X as Code" — infrastructure as code, configuration as code, docs as code. The reason is simple: plain text can be diffed, reviewed, version-controlled, and read or written directly by scripts and AI.&lt;/p&gt;

&lt;p&gt;So why are your &lt;strong&gt;tasks, notes, and todos&lt;/strong&gt; still locked inside some SaaS database, reachable only by clicking through its UI one item at a time?&lt;/p&gt;

&lt;p&gt;UnDercontrol's answer is &lt;strong&gt;Everything as Code&lt;/strong&gt;. Here, a task &lt;em&gt;is&lt;/em&gt; a piece of Markdown with YAML frontmatter. That's 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%2F0gcaxp3y4x93s06dp9pi.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%2F0gcaxp3y4x93s06dp9pi.png" alt="A task is Markdown: plain text with frontmatter renders into a task card after apply" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What a Task Looks Like
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add a smoke test to the release flow&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;in-progress&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;testing&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;deadline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-07-10&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="gu"&gt;## Goal&lt;/span&gt;
Run the critical path automatically before every release; block the tag on failure.

&lt;span class="gu"&gt;## Steps&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [x] Log in + create task
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Browse the three core pages
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Assert no console errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontmatter is the task's &lt;strong&gt;structured metadata&lt;/strong&gt;: title, status, tags, deadline, assignee, links — the 20% of fields that cover 80% of cases are all first-class, and all queryable. The body below the frontmatter is the task's &lt;strong&gt;canonical document (the Single Source of Truth)&lt;/strong&gt;: a living piece of Markdown.&lt;/p&gt;

&lt;p&gt;No proprietary format. No binary blob to export. No vendor lock-in. What you see is all there is.&lt;/p&gt;

&lt;h3&gt;
  
  
  apply, Just Like kubectl
&lt;/h3&gt;

&lt;p&gt;Save that Markdown to a file, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ud apply &lt;span class="nt"&gt;-f&lt;/span&gt; task.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rules are exactly like &lt;code&gt;kubectl apply&lt;/code&gt;: &lt;strong&gt;no id in the frontmatter means create, an id means update&lt;/strong&gt;. apply is a &lt;strong&gt;full replace&lt;/strong&gt; — the file is the source of truth.&lt;/p&gt;

&lt;p&gt;Want to export in bulk, edit, and push it all back? &lt;code&gt;ud get task -o apply&lt;/code&gt; prints your tasks in the same format apply accepts — a lossless round-trip. That means your task list can be processed like code with sed / jq / any script, then applied back in one shot.&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%2Fm6yaeuhv9onzseago8tl.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%2Fm6yaeuhv9onzseago8tl.png" alt="Lossless round-trip: ud get -o apply exports to local md, scripts process it, ud apply pushes it back" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Is a Superpower for Developers (and AI)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Version-controllable, GitOps-friendly.&lt;/strong&gt; Tasks are plain text, so they naturally diff, live in Git, and go through PR review. Your project plan and your code can share the same commit history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Native I/O for AI agents.&lt;/strong&gt; Markdown is human-readable and AI-readable. Any terminal-based coding agent — Claude Code, Codex, OpenCode, or any agent that lives in your shell — can read and write your tasks directly through the &lt;code&gt;ud&lt;/code&gt; CLI, with no special plugin or SDK. The whole knowledge base is plain-text-native and AI-ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# things an agent can do right in your terminal&lt;/span&gt;
ud get task &lt;span class="s1"&gt;'status = in-progress'&lt;/span&gt;
ud apply &lt;span class="nt"&gt;-f&lt;/span&gt; new-task.md
ud describe task 8b30140e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Scriptable and composable.&lt;/strong&gt; A SQL-like query syntax plus kubectl-style verbs (get / describe / apply / delete / patch) turn task management into something you can drop into any automation. Create a task in CI, bulk-retag from a script, generate a weekly report from cron — each is just a few lines of shell.&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%2F1dnpxadeened7jzr44wc.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%2F1dnpxadeened7jzr44wc.png" alt="Many entry points, one source of truth: CLI, AI agents, and CI scripts all write to the same Markdown data source through ud apply" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Just Tasks
&lt;/h3&gt;

&lt;p&gt;Here's a detail that's easy to miss: UnDercontrol's Markdown editor is &lt;strong&gt;not task-specific&lt;/strong&gt;. It's a single editor shared across every text surface — tasks, notes, even expense and account memos all use the same editing experience and the same Markdown core.&lt;/p&gt;

&lt;p&gt;So the "Everything" in "Everything as Code" is literal: your todos are Markdown, your notes are Markdown, the memo on an expense you logged is Markdown. One data source, organized the way you like, all in one place. No switching between apps, and an AI agent only has to learn a single tool to reach all of your information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three Content Layers
&lt;/h3&gt;

&lt;p&gt;Each information unit has three layers. Each has a design intent, but you're free to use them however suits you:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Design Intent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task body&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;The canonical, evolving document — Single Source of Truth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;An append-only timeline — how this unit evolved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Plain text&lt;/td&gt;
&lt;td&gt;Lightweight, threaded conversation — short and focused&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What distinguishes a "doc" from a "task" isn't the data structure — it's &lt;strong&gt;tags, metadata, and the view&lt;/strong&gt;. UnDercontrol doesn't force a folder hierarchy or a tagging convention on you: the same task can appear on multiple boards (a board is a &lt;em&gt;saved query&lt;/em&gt;, not a container, so there's no duplication).&lt;/p&gt;

&lt;h3&gt;
  
  
  Get Started
&lt;/h3&gt;

&lt;p&gt;If you're tired of trapping your ideas inside a UI, try turning them into Markdown you can apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ud apply &lt;span class="nt"&gt;-f&lt;/span&gt; my-first-task.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything as Code isn't just a slogan — it's how your tasks, your scripts, and your AI agents finally speak the same language.&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
