<?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: Stuart Dobson</title>
    <description>The latest articles on DEV Community by Stuart Dobson (@stuartdotnet).</description>
    <link>https://dev.to/stuartdotnet</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%2F165155%2Fba824eda-8248-4061-8907-9924d8dce16f.jpg</url>
      <title>DEV Community: Stuart Dobson</title>
      <link>https://dev.to/stuartdotnet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stuartdotnet"/>
    <language>en</language>
    <item>
      <title>Build Transformative AI Assistants with Claude Code Workspaces</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Tue, 18 Aug 2026 08:50:16 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/build-transformative-ai-assistants-with-claude-code-workspaces-34p6</link>
      <guid>https://dev.to/stuartdotnet/build-transformative-ai-assistants-with-claude-code-workspaces-34p6</guid>
      <description>&lt;p&gt;I’ve been using Claude Code workspaces for about 6 months. They are one of the reasons I’m positive about AI. They’re like auxiliary brains, opening so many doors of opportunity.&lt;/p&gt;

&lt;p&gt;I built a workspace for preparing for job interviews. It had MCP tools which researched the interviewer’s LinkedIn, company website, and the role description, and then synthesized the information. It had commands that generated practice questions based on the interviewers’ roles and the position. I used my resume and the job application as grounding references. I had a skill which gave me ideas for what to say for my intro - tailored to the company’s needs.&lt;/p&gt;

&lt;p&gt;I’ve never found a good website for homework questions for my son. They’re always full of ads and often inappropriate content. So I built a workspace for it. It knows his interests and customises learning projects based on them and his level. It generates a set of questions on various subjects when requested. Over time I have tweaked it to improve the questions. When the question is complex, we’re able to ask in-depth follow up questions.&lt;/p&gt;

&lt;p&gt;I built a workspace for managing my study for a Microsoft exam. It researches the current literature on Microsoft Learn and creates a weekly learning schedule.&lt;/p&gt;

&lt;p&gt;I’ve built workspaces for brainstorming, deep research, planning, code generation, code evaluation and more. The opportunities workspaces present are endless. The output they create has been a game changer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Claude Code Workspace That Actually Works
&lt;/h2&gt;

&lt;p&gt;The problem with basic chat is that it often gets things wrong, but one of the best ways to improve this is to give it &lt;em&gt;grounded&lt;/em&gt; information as a baseline. A collection of hardwired instructions, consistent context, and a limited working space.&lt;/p&gt;

&lt;p&gt;A workspace is a structured environment that gives Claude persistent context, repeatable skills it executes consistently, hooks that enforce rules it can’t override, and a clear design for what gets loaded when. Once you’ve built one, going back to ad-hoc prompts feels like &lt;a href="https://wiredlegacy.substack.com/p/ai-has-made-search-engines-obsolete" rel="noopener noreferrer"&gt;going back to using a search engine&lt;/a&gt;. Oh the horror!&lt;/p&gt;

&lt;p&gt;This post walks you through the pattern using a consulting operations workspace as the concrete example: client intake, proposals, status reports. The structure applies to anything repeatable: content pipelines, research workflows, team operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: Get Claude Code Running
&lt;/h2&gt;

&lt;p&gt;Before any of the workspace stuff matters, you need Claude Code installed and running. Here’s how.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install Claude Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The easiest option is the desktop app. Download it from &lt;a href="https://code.claude.com/docs/en/desktop" rel="noopener noreferrer"&gt;code.claude.com/docs/en/desktop&lt;/a&gt; and run the installer. The desktop app installs everything including the &lt;code&gt;claude&lt;/code&gt; terminal command, so Steps 3 and 4 below will work straight after.&lt;/p&gt;

&lt;p&gt;If you’re a developer and prefer the CLI directly:&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; @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll need Node.js installed first if you go that route.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Open your workspace folder in VS Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a folder somewhere sensible (e.g. &lt;code&gt;my-workspace&lt;/code&gt;), then open it in VS Code. File &amp;gt; Open Folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Open the terminal in VS Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;Ctrl+`&lt;/code&gt; (backtick, the key above Tab) or go to Terminal &amp;gt; New Terminal. A terminal panel opens at the bottom of the screen. My recommendation - grab the top border and make it take up at least half the screen. :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Run Claude&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type &lt;code&gt;claude&lt;/code&gt; and press Enter. Claude Code starts in your terminal, reads your workspace folder, and you can start talking to it.&lt;/p&gt;

&lt;p&gt;Everything you build in the workspace - the CLAUDE.md, the context files, the skills - is picked up automatically. Claude reads the folder it was opened in.&lt;/p&gt;

&lt;p&gt;One more thing: VS Code also has a Claude Code extension in the marketplace. Same result, slightly friendlier interface. Either works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Folder Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-workspace/
├── CLAUDE.md                     # Session constitution, keep it lean
├── .claude/
│   ├── commands/                 # Simple slash commands
│   ├── skills/                   # Rich workflows with bundled assets
│   │   ├── new-client/
│   │   │   └── SKILL.md
│   │   ├── proposal/
│   │   │   ├── SKILL.md
│   │   │   └── proposal-template.md
│   │   └── status-report/
│   │       └── SKILL.md
│   ├── agents/                   # Specialist subagents
│   │   └── research-agent.md
│   └── settings.json             # Hooks
├── context/                      # Always-loaded session context
│   ├── personal-info.md
│   ├── strategy.md
│   └── current-data.md
├── reference/                    # On-demand only, loaded by skills
│   └── client-templates/
└── outputs/
    ├── clients/
    ├── proposals/
    └── reports/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things drive every design decision here: the &lt;strong&gt;context window&lt;/strong&gt; and the &lt;strong&gt;session lifecycle&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Design Decision That Matters Most
&lt;/h2&gt;

&lt;p&gt;Every file Claude reads at session start consumes context window permanently for that session. Blow your context budget upfront and you have a sluggish, forgetful Claude by the time you’re halfway through a real task.&lt;/p&gt;

&lt;p&gt;The fix is a hard split between what gets loaded every session and what gets loaded on demand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Always-loaded&lt;/strong&gt; (&lt;code&gt;CLAUDE.md&lt;/code&gt; + &lt;code&gt;context/&lt;/code&gt;): who you are, what you’re optimising for, operational rules. Lean. If removing a line wouldn’t cause Claude to make a mistake, cut it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;On-demand&lt;/strong&gt; (&lt;code&gt;reference/&lt;/code&gt;, skill assets): style guides, client templates, source link libraries. Loaded only when a specific command needs them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A 200-line style guide loaded every session costs you context whether you’re drafting or just asking a quick question. Loaded only when &lt;code&gt;/draft-post&lt;/code&gt; fires, it costs nothing on sessions where it’s not required.&lt;/p&gt;

&lt;p&gt;Most workspace guides tell you to put everything in CLAUDE.md. That is completely wrong. The loaded-vs-on-demand split is the design decision that separates a working harness from one that slowly stops working as your workspace grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLAUDE.md: Should be Lean
&lt;/h2&gt;

&lt;p&gt;CLAUDE.md is auto-loaded every session. Treat it like a constitution, &lt;em&gt;not a knowledge base&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What belongs here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rules that apply to every task (“always respond in British English”, “never commit without running tests”, “never use em dashes”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Workspace structure: what the folders are for and how to navigate them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@context/personal-info.md&lt;/code&gt; style imports that pull in context files without embedding them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Commands available and what they do&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What doesn’t:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Detailed style guides (they go in &lt;code&gt;reference/&lt;/code&gt;, loaded by skills)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything that only applies to one type of task&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Information Claude can infer by reading the files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anthropic’s test is blunt: &lt;em&gt;“Would removing this line cause Claude to make a mistake?”&lt;/em&gt; If no, cut it. A bloated CLAUDE.md causes Claude to gradually deprioritise your rules as the session progresses. Not because it ignores them. Because they get buried under more recent context. The rules don’t disappear. They just lose.&lt;/p&gt;

&lt;p&gt;Keep CLAUDE.md under 200 lines. Use &lt;code&gt;@path/to/file&lt;/code&gt; imports to pull in section-level context rather than embedding everything directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory: What Claude Learns Automatically
&lt;/h2&gt;

&lt;p&gt;CLAUDE.md is what you write deliberately, upfront. Memory is what Claude writes as it works with you.&lt;/p&gt;

&lt;p&gt;Claude’s auto memory system lives outside the repo in its config directory. As sessions progress, it captures things you’d otherwise repeat across sessions: preferences you’ve stated, corrections you’ve made, project context it has learned. Next session, those facts are already there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What belongs in memory:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Preferences learned through use (“prefers bullet lists over tables: pushed back on this in post 7”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Corrections and feedback (“never use em dashes: corrected twice, now a standing rule”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Project context that isn’t in the code (“AI-103 exam target is early June 2026”)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What doesn’t:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rules you’ve decided upfront - those go in CLAUDE.md&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything that needs to be shared with teammates or version-controlled - memory is private to your Claude config, not in the repo&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The distinction: CLAUDE.md is designed. Memory is learned.&lt;/p&gt;

&lt;p&gt;One gotcha: memory entries go stale. If a project priority shifts or a preference changes, Claude may still act on an old memory. Audit memories periodically the same way you audit CLAUDE.md.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context: What Claude Always Knows
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;context/&lt;/code&gt; folder is small by design. Three files, not thirty. Claude reads them at the start of every session: who you are, what you’re currently working toward, and the live numbers that inform decisions. Keep them small!&lt;/p&gt;

&lt;p&gt;A typical setup - your situation may vary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;personal-info.md&lt;/code&gt;: role, background, relevant expertise&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;strategy.md&lt;/code&gt;: current priorities and what success looks like&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;current-data.md&lt;/code&gt;: live numbers, updated weekly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything here pays a context window tax on every session. If a piece of information only matters for one type of task, it belongs in &lt;code&gt;reference/&lt;/code&gt;, not here.&lt;/p&gt;

&lt;h2&gt;
  
  
  References and On-Demand RAG
&lt;/h2&gt;

&lt;p&gt;Nothing in &lt;code&gt;reference/&lt;/code&gt; loads unless a skill requests it. That’s the rule.&lt;/p&gt;

&lt;p&gt;It’s effectively RAG (Retrieval Augmented Generation - “a technique used to improve the accuracy of Large Language Models (LLMs) like ChatGPT or Gemini by fetching facts from an external, trusted database before generating a response, rather than relying solely on the AI’s internal training memory.”) for your workspace. An exam guide, sample homework questions, your client proposal template, your list of research sources: none of it costs context window unless it’s actually needed. A skill that creates a client proposal loads &lt;code&gt;reference/client-templates/&lt;/code&gt;. A skill that researches a topic loads &lt;code&gt;reference/brainstorm/&lt;/code&gt;. A plain coding question loads nothing from &lt;code&gt;reference/&lt;/code&gt; at all.&lt;/p&gt;

&lt;p&gt;If you’re tempted to put a file in &lt;code&gt;context/&lt;/code&gt; because “Claude might need it,” ask whether it’s needed every session or just on specific tasks. If specific tasks, it belongs in &lt;code&gt;reference/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outputs: Where the Work Lives
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;outputs/&lt;/code&gt; folder is where Claude writes its deliverables. Structure it by workflow type, not file type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;outputs/
├── casestudies/
│   ├── drafts/
│   └── research/
├── clients/
├── proposals/
└── reports/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some scenarios, you might need Claude to read items from these folders as inputs to another. This is why separating them logically is important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills: Repeatable Workflows with Bundled Assets
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;skill&lt;/strong&gt; is a markdown file in &lt;code&gt;.claude/skills/&amp;lt;name&amp;gt;/SKILL.md&lt;/code&gt; that defines a repeatable workflow. Invoke it explicitly with &lt;code&gt;/skill-name&lt;/code&gt;, or let Claude auto-trigger it when it judges the description matches your task.&lt;/p&gt;

&lt;p&gt;Anthropic created skills. Read &lt;a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview" rel="noopener noreferrer"&gt;their guide&lt;/a&gt; before working with them.&lt;/p&gt;

&lt;p&gt;Here’s the client intake skill for the consulting workspace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;---&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;
&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"Create a new client project brief from intake information."&lt;/span&gt;
             &lt;span class="n"&gt;Invoke&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;invocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;---&lt;/span&gt;

&lt;span class="n"&gt;Parse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;following&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;intake&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;brief&lt;/span&gt;
&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;`outputs/clients/{client-name}/brief.md`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="k"&gt;Extract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Problem&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="k"&gt;Scope&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;deliverables&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Timeline&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;budget&lt;/span&gt; &lt;span class="k"&gt;constraints&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;criteria&lt;/span&gt;

&lt;span class="n"&gt;Confirm&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;brief&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ask&lt;/span&gt; &lt;span class="n"&gt;whether&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;draft&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;proposal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="k"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ARGUMENTS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;disable-model-invocation: true&lt;/code&gt; prevents auto-triggering. Use it on any skill that creates files or has side effects. You want explicit invocation for anything with consequences. Leave it off for knowledge skills Claude should apply automatically, like coding conventions or tone guidelines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The description matters more than people expect.&lt;/strong&gt; It’s how Claude decides whether to auto-load the skill. Vague descriptions cause wrong skills to fire. &lt;em&gt;“Handles client work”&lt;/em&gt; will trigger on things you didn’t intend. &lt;em&gt;“Create a new client project brief from intake information”&lt;/em&gt; will not. Be specific about the exact scenario.&lt;/p&gt;

&lt;p&gt;Skills can carry sibling files (templates, reference docs, examples, tools) that load alongside the instructions. The proposal skill carries &lt;code&gt;proposal-template.md&lt;/code&gt;. The logic lives in &lt;code&gt;SKILL.md&lt;/code&gt;; the reference material sits next to it. Nothing leaks into CLAUDE.md.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commands: Lightweight Slash Shortcuts
&lt;/h2&gt;

&lt;p&gt;Commands are markdown files in &lt;code&gt;.claude/commands/&lt;/code&gt;. You invoke them with &lt;code&gt;/command-name&lt;/code&gt; and they run immediately. No sibling assets, no auto-trigger logic. Simple, explicit shortcuts for bounded tasks.&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="gh"&gt;# Image Prompt&lt;/span&gt;

Generate a sumi-e style blog header image prompt for post $ARGUMENTS.
Read the brief or draft, identify the central concept and key metaphors,
then output a ready-to-paste prompt for DALL-E, Midjourney, or similar.
Style rules are in &lt;span class="sb"&gt;`reference/image-style.md`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use commands for things you trigger manually on demand: &lt;code&gt;/prime&lt;/code&gt; to initialise a session, &lt;code&gt;/research "topic"&lt;/code&gt; to kick off an investigation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/create-plan&lt;/code&gt; &lt;strong&gt;is worth calling out separately.&lt;/strong&gt; Before any multi-file change or new feature, it writes a structured implementation plan and waits for your sign-off before touching anything. Claude confirms the right approach first, rather than confidently building the wrong thing. Add it to every workspace that involves code or complex deliverables.&lt;/p&gt;

&lt;p&gt;Skills are the right choice when a workflow needs sibling assets, when the logic is long enough to warrant structure, or when you want auto-trigger behaviour. For everything else, a command is faster to write and easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hooks: Rules Claude Can’t Override
&lt;/h2&gt;

&lt;p&gt;CLAUDE.md instructions are &lt;strong&gt;advisory&lt;/strong&gt;. Claude reads them, weighs them against everything else in context, and may deprioritise them in a long session. Hooks are different. They’re shell commands that run deterministically at specific lifecycle events. Claude can’t reason its way around them. If you don’t know how to script, simply ask Claude to write it.&lt;/p&gt;

&lt;p&gt;Configure them in &lt;code&gt;.claude/settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PostToolUse&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;matcher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write|Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;$(date): modified $FILE_PATH&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;gt;&amp;gt; outputs/ledger.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This logs every file write to an audit ledger automatically. No prompting required. Claude can’t skip it.&lt;/p&gt;

&lt;p&gt;Use hooks for things that must happen every time with zero exceptions: formatting after file edits, blocking writes to protected directories, logging outputs, running lint before a commit. If it’s important enough that “Claude forgetting” is unacceptable, it belongs in a hook, not CLAUDE.md.&lt;/p&gt;

&lt;p&gt;One gotcha: don’t let hooks block mid-edit. Hooks that interrupt Claude while it’s reasoning through a multi-file change break the reasoning chain. Block at the end of a task, not mid-stream.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP Servers: External Tool Integration
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol connects Claude to external services: file systems, GitHub, Google Drive, Slack, databases, web search. Each MCP server exposes a set of tools Claude can call directly within a session.&lt;/p&gt;

&lt;p&gt;Configure them in &lt;code&gt;.claude/settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@modelcontextprotocol/server-github"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"GITHUB_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${GITHUB_TOKEN}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, Claude can read and create PRs, check CI status, and search your repository without you copying anything into the chat. Add web search and Claude can pull current documentation. Add a database MCP and Claude can query your schema directly.&lt;/p&gt;

&lt;p&gt;MCP servers run as local processes. Each one consumes resources. Don’t add servers you won’t use. Vet community servers before depending on them: check the last commit date and the issue tracker. Official integrations (GitHub, Google Drive, Slack) are stable. Community servers vary significantly and can be dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sub Agents: Specialist Workers
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.claude/agents/&lt;/code&gt; folder holds specialist agent definitions. Each is a markdown file describing a narrow-purpose assistant Claude can spin up for specific tasks.&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="nn"&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;research-agent&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Research agent for web searches and source collection.&lt;/span&gt;
             &lt;span class="s"&gt;Invoke for background research that shouldn't consume main session context.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="s"&gt;You are a focused research assistant. Given a topic, search for&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="s"&gt;1. Official documentation and release notes&lt;/span&gt;
&lt;span class="s"&gt;2. Community tutorials and real-world usage examples&lt;/span&gt;
&lt;span class="s"&gt;3. Known issues or limitations&lt;/span&gt;

&lt;span class="na"&gt;Return a structured summary with links. Research only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no code, no recommendations.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main value is context isolation. Hand a task to a sub agent and it runs in its own context window. A research sweep that reads twenty web pages stays in the agent’s context, not yours. Your main session stays clean.&lt;/p&gt;

&lt;p&gt;Use sub agents for tasks that are parallel, independent, or context-heavy: background research, specialist review, parallel file analysis. Don’t use them for tasks that need your session’s context. The agent starts fresh. It won’t know what you’ve been doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The /prime Session Initialisation Pattern
&lt;/h2&gt;

&lt;p&gt;Every session should start with explicit initialisation. Don’t trust Claude to figure out context from the project root. Depending on what you ask first, it may or may not read the right files.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;/prime&lt;/code&gt; skill handles this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&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;prime&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Initialise a new session with full context.&lt;/span&gt;
             &lt;span class="s"&gt;Run at the start of every session.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="s"&gt;1. Read CLAUDE.md and context/personal-info.md, context/strategy.md,&lt;/span&gt;
   &lt;span class="s"&gt;context/current-data.md&lt;/span&gt;
&lt;span class="na"&gt;2. Summarise your understanding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;who I am, what this workspace is for,&lt;/span&gt;
   &lt;span class="s"&gt;current priorities&lt;/span&gt;
&lt;span class="s"&gt;3. Confirm readiness to assist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;/prime&lt;/code&gt;. Claude reads the files, summarises back, and you can verify immediately if anything’s missing. Thirty seconds max. Prevents the most common workspace failure: a session where Claude lacks context and you don’t notice until you’ve wasted twenty minutes on outputs that miss the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workspaces vs Claude Cowork
&lt;/h2&gt;

&lt;p&gt;Claude Cowork is Anthropic’s other desktop product, and it’s worth understanding the difference before you commit to building a workspace.&lt;/p&gt;

&lt;p&gt;Cowork is designed for autonomous, goal-driven tasks. You give it an outcome (“prepare a briefing document from these three reports”) and it handles the steps: opening files, synthesising information, producing the deliverable. No programming required. It’s aimed at researchers, analysts, and knowledge workers who need Claude to operate on their local files without any setup.&lt;/p&gt;

&lt;p&gt;A Claude Code workspace is the opposite philosophy. You define the structure, the context, the rules, and the repeatable workflows. Claude follows them consistently across every session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Cowork&lt;/strong&gt; is the right choice when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The task is one-off or hard to predict in advance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The user isn’t technical and won’t be configuring anything&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want autonomous execution with minimal setup&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Claude Code workspace&lt;/strong&gt; is the right choice when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You run the same workflows repeatedly and want consistent results&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need hooks that enforce rules Claude can’t reason around&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want context that persists and compounds across sessions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’re a developer who wants programmatic control over how Claude operates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most technical people will end up using both. Cowork for ad-hoc heavy lifting. A workspace for the repeatable stuff that needs to work the same way every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CLAUDE.md bloat kills rule adherence.&lt;/strong&gt; Past ~200 lines, rules start getting quietly ignored. Claude doesn’t warn you. Audit your CLAUDE.md periodically and prune anything that doesn’t pass the mistake test. If you’ve added something since day one that Claude was already doing correctly, delete it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill descriptions consume context on every tool call&lt;/strong&gt;: roughly 2% of your context window per skill, even if the skill isn’t active. Keep descriptions to 2-3 lines. Don’t write essays in the frontmatter; you’re paying for that space in every session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The on-demand split requires discipline.&lt;/strong&gt; The moment you put detailed reference material in &lt;code&gt;context/&lt;/code&gt; instead of &lt;code&gt;reference/&lt;/code&gt;, you’ve broken the pattern. Strict rule: if a piece of information only matters for one type of task, it doesn’t go in &lt;code&gt;context/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session context drifts in long sessions.&lt;/strong&gt; &lt;code&gt;/clear&lt;/code&gt; between unrelated tasks is not optional. It’s how you maintain output quality. Mixing research, drafting, and code review in one session produces mediocre results across all three. The instructions are still there. The signal-to-noise ratio isn’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP server quality varies significantly.&lt;/strong&gt; Before depending on a community MCP server, check the last commit date. The ecosystem has a long tail of abandoned projects. Official integrations (Google Drive, GitHub, Slack) are stable; community servers need vetting before you build workflows on top of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Build First
&lt;/h2&gt;

&lt;p&gt;Start small. Don’t wire up MCP on day one or write six skills before you’ve tested one.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create the folder structure&lt;/strong&gt;: directories only, no content yet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write CLAUDE.md&lt;/strong&gt;: twenty lines maximum, workspace structure and core rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add&lt;/strong&gt; &lt;code&gt;context/personal-info.md&lt;/code&gt;: who you are and what this workspace is for&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write one skill&lt;/strong&gt;: pick the task you do most often, document its steps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a&lt;/strong&gt; &lt;code&gt;/prime&lt;/code&gt; &lt;strong&gt;skill&lt;/strong&gt;: one invocation that confirms Claude has context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add one hook&lt;/strong&gt;: start with an output ledger, low-risk and immediately useful&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The workspace pattern compounds. A working harness with three skills beats an over-engineered one with twelve half-tested ones.&lt;/p&gt;

&lt;p&gt;You’ll find that the demands grow as you use your workspace. You’ll consistently create new commands, plugins and skills for various things as they come up. But start with a basic workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell Claude to Improve Its Own Workspace
&lt;/h2&gt;

&lt;p&gt;Here’s something I’ve found really useful: ask Claude to modify the workspace itself.&lt;/p&gt;

&lt;p&gt;If you find yourself typing the same instruction at the start of every session, tell Claude to add it to CLAUDE.md. If a task you do repeatedly doesn’t have a command yet, ask Claude to build one. The workspace doesn’t have to be designed upfront. It can grow from usage.&lt;/p&gt;

&lt;p&gt;Some examples of what this looks like in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;“I keep having to tell you to check the briefs file before drafting. Add that as a rule in CLAUDE.md.”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;“Build me a command called&lt;/em&gt; &lt;code&gt;/weekly-review&lt;/code&gt; &lt;em&gt;that reads&lt;/em&gt; &lt;code&gt;context/current-data.md&lt;/code&gt; &lt;em&gt;and outputs a summary of progress against my targets.”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;“I want a skill that generates LinkedIn posts from a blog draft. Look at how&lt;/em&gt; &lt;code&gt;/draft-post&lt;/code&gt; &lt;em&gt;works and create something similar.”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude writes the markdown, creates the file, and confirms what it did. You review it, ask for tweaks, and move on. No separate design session required.&lt;/p&gt;

&lt;p&gt;The best workspaces I’ve built weren’t architected in one sitting. They accumulated through use. Every time friction showed up, I turned it into a command or a rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimising Your Workspace
&lt;/h2&gt;

&lt;p&gt;A workspace that worked well at week one will have friction by week eight if you don’t maintain it. Three areas to audit regularly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLAUDE.md:&lt;/strong&gt; Run the mistake test on every line. &lt;em&gt;“If I removed this, would Claude make a mistake?”&lt;/em&gt; Anything that doesn’t survive the test is noise. Also check for rules Claude was already following correctly before you wrote them down. You’re paying context window for instructions you don’t need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills and commands:&lt;/strong&gt; Vague descriptions cause wrong skills to fire. If a skill is auto-triggering on tasks you didn’t intend, tighten the description. If you have skills you haven’t used in a month, archive them. Description overhead accumulates even for idle skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hooks:&lt;/strong&gt; Review what’s actually firing. The audit ledger is your ground truth. If a hook isn’t appearing when it should, the matcher is wrong. If it’s appearing on tasks where it’s irrelevant, the matcher is too broad.&lt;/p&gt;

&lt;p&gt;Beyond maintenance, the fastest way to level up a workspace is to use a skill like &lt;a href="https://github.com/TheDecipherist/claude-code-mastery" rel="noopener noreferrer"&gt;claude-code-mastery&lt;/a&gt;. Add it to your skills folder and call it with /claude-code-mastery and it will assess your workspace. The last time I ran this it found a few optimisations that dropped my initial context from 10000 to 100 tokens. For real! Highly recommended.&lt;/p&gt;

&lt;p&gt;The other signal is your own session transcripts. If you’re repeatedly typing the same instructions at the start of a session, that’s missing context file info or missing MEMORY. If you’re correcting Claude on the same point every few sessions, that’s a hook or rule that needs to be written. Let your friction tell you what to build next.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern Scales
&lt;/h2&gt;

&lt;p&gt;The same structure works whether you’re running a content pipeline, a learning workspace, an interview preparation tool, a team operation, or a solo research workflow. The skills change. The context files change. The design decisions don’t.&lt;/p&gt;

&lt;p&gt;CLAUDE.md is the constitution.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;context/&lt;/code&gt; is the always-loaded minimum.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reference/&lt;/code&gt; is the on-demand library.&lt;/p&gt;

&lt;p&gt;Skills are repeatable procedures.&lt;/p&gt;

&lt;p&gt;Hooks are non-negotiable rules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/prime&lt;/code&gt; is the session handshake.&lt;/p&gt;

&lt;p&gt;Build it once. Adjust the skills for your domain. Spin it up for each project or client as a template.&lt;/p&gt;

&lt;p&gt;Now you’re using AI properly.&lt;/p&gt;




&lt;p&gt;Thanks for reading. You can find more of my work at &lt;a href="https://stuartdobson.net" rel="noopener noreferrer"&gt;stuartdobson.net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegroundeddeveloper.substack.com/p/build-transformative-ai-assistants?utm_source=substack&amp;amp;utm_medium=email&amp;amp;utm_content=share&amp;amp;action=share" rel="noopener noreferrer"&gt;Share&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>harnesses</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Story Points are Utter Nonsense</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Fri, 27 Feb 2026 02:55:05 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/story-points-are-utter-nonsense-43m6</link>
      <guid>https://dev.to/stuartdotnet/story-points-are-utter-nonsense-43m6</guid>
      <description>&lt;p&gt;For over a decade, I've lived a lie.&lt;/p&gt;

&lt;p&gt;I made myself believe that Agile Story points made sense.&lt;/p&gt;

&lt;p&gt;I rationalised it like we all did.&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"They map to complexity, not time".
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yet we spend hours on Sprint Planning meetings deciding how many jobs we can fit into a Sprint - a unit of time. Also - doesn't complexity relate to time?&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"They're a rough guide, they're not supposed to be accurate."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;How on Earth did we end up with a unit of measure that is "not supposed to be accurate"?&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"It depends on experience of the person doing the job."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is like saying the length of a centimeter depends on the tape measure you're using.&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"They're a measure of relative complexity."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Relative to what? Another story you did which didn't have an accurate estimate?&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"We use shirt sizes/Fibonacci/animals/fruit."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is this supposed to make it easier to understand? Why can't I give a task 4 points?&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"We have to agree on size before we can move on."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, let's ensure the contractor watering the plants gets a say on this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Planning poker helps us find a consensus."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;I guess it does, once everyone is worn down enough to just agree.&lt;/p&gt;

&lt;p&gt;A recent discussion highlighted the absurdity. I asked people to define what story points were, and just like the multiple meetings I've had over many years, it was clear that nobody could agree.&lt;/p&gt;

&lt;p&gt;I got the usual selection of contradictions and confusion.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Story points have no unit of value&lt;/li&gt;
&lt;li&gt;    Story points are a non standard unit of value(?)&lt;/li&gt;
&lt;li&gt;    They're team specific, so they don't map to anything&lt;/li&gt;
&lt;li&gt;    They don't map to time, but they do map to a sprint, which is time&lt;/li&gt;
&lt;li&gt;    They map to complexity, but how much depends on the experience of who is doing the job, and the maturity of the team, which changes over time.&lt;/li&gt;
&lt;li&gt;    They're only supposed to be used for Epics, and Stories are estimated in time&lt;/li&gt;
&lt;li&gt;    A Story point is like a chicken&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, that was a legitimate answer from someone attempting to explain what a story point was.&lt;/p&gt;

&lt;p&gt;It's like a chicken.&lt;/p&gt;

&lt;p&gt;This is a real thing a human said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I once had a Scrum consultant working with our team who said a story point can be a chicken if you wanted. Find a story that the team can say is a very simple piece of work and call that your chicken. This chicken is then 1 story point. A story that would be twice as difficult or complex would be a two-chicken story (or 2 story points). It's over-simplified, but perhaps you get the point."
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not sure I do..&lt;/p&gt;

&lt;p&gt;Agile is a cult. This is evident in the explanations which pervade this space that are often repeated ad nauseam. One of these explanations becomes our rationalistion: "It's Agile. It's flexible - you can do it how you want."&lt;/p&gt;

&lt;p&gt;It's time we admit that it doesn't work and it's really just a cocktail of nonsense, designed to put a framework around what is, in the end, an impossibly hard thing to plan.&lt;/p&gt;

&lt;p&gt;I'm going to invent a new system of organising workloads. You have planning meetings once every 13 days unless there's a full moon. In those meetings you can play Snakes and Ladders to determine the "relative complexity" of a ticket. Then you throw that number out, and just do the job anyway. Every 15 minutes someone has to stand up and shout "Bingo". Then someone else picks up the ball.&lt;/p&gt;

&lt;p&gt;Actually, this makes as much sense as our Agile rituals, so it'll probably take off.&lt;/p&gt;

&lt;p&gt;I apologise to the workers of 2040.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>estimation</category>
    </item>
    <item>
      <title>Why should I care about Quality? I'm a developer!</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Sun, 15 Dec 2024 06:47:21 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/why-should-i-care-about-quality-im-a-developer-39o3</link>
      <guid>https://dev.to/stuartdotnet/why-should-i-care-about-quality-im-a-developer-39o3</guid>
      <description>&lt;p&gt;Quality is something QA do, right?&lt;/p&gt;

&lt;p&gt;OK, so no developer wants to create bad quality code. But for most developers, quality is seen as something separate from development, something that is checked after the work has been done. It is something that QA do, after you throw your code over the fence. Thinking about quality at during development is a burden, slowing down the creation of functionality, holding up new features. Thinking about quality before development? That's just crazy talk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Old Habits Die Hard
&lt;/h2&gt;

&lt;p&gt;In the Agile world, Quality &lt;em&gt;should&lt;/em&gt; be baked into the development process and there is more interaction between development and QA during the development phase. At least, that's the theory. In practice, we often slip back into bad habits of throwing code over the fence.&lt;/p&gt;

&lt;p&gt;The reason we keep falling back into bad habits is because the attitude around quality is the same as it always was. It is still seen as something separate from development, separate from design, separate from planning. This causes it to be seen as a burden - extra work that just has to be done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality as the Glue
&lt;/h2&gt;

&lt;p&gt;If instead, we change our perspective, and try to see Quality as an integral part of the entire development process, it can change the way we all work, from developers to product owners. Instead of a burden, quality should be a thread that runs throughout the process, and actually defines how all work is done from the ground up. If this is done, it can actually simplify and speed up development.&lt;/p&gt;

&lt;p&gt;Baking quality into your process shifts the responsibility to everyone, rather than just QA. Having the whole team (including product owners) take responsibility for quality sets the focus around Acceptance Criteria. This "requirements-centric" approach gets everyone thinking about quality right from the refinement meeting. When the entire team comes together and builds good Acceptance Criteria, quality becomes a natural, and welcome, part of the development process.&lt;/p&gt;

&lt;p&gt;Several things then happen. First, the whole team are forced to agree on the details of the requirements before development starts. Before any technical decisions or implementation planning, the exact requirements are clarified. Only by making this an imperative part of the process (usually the refinement meeting) can this happen effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good Acceptance Criteria Drives Good Development
&lt;/h2&gt;

&lt;p&gt;With clear Acceptance Criteria, development is simplified. Development knows exactly what they need to implement, and when they know this, the process of writing automated tests is no longer abstract and difficult. Test Driven Development is a tricky thing to do, in practice. However, with clear goals, a developer can start with "pseudo tests" - tests which are just code comments - but which outline the business logic before coding begins. These will be a granular list of Prerequisite/Action/Assertions - Unit tests, essentially - outlining the required logic. Then, development becomes a process of implementing that logic.&lt;/p&gt;

&lt;p&gt;Breaking the logic down before development begins is a very effective way of ensuring that clean code practices, especially the Single Responsibility Principle, are followed. It becomes natural to keep the logic simple, concise, and separated from other concerns, such as infrastructure. It encourages clean Object Orientated design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good Acceptance Criteria Drives Good QA
&lt;/h2&gt;

&lt;p&gt;Also QA know exactly what they will be getting. They know what parts of the job will be automated, so they can design better integration, acceptance, and End to End tests, as well as an effective exploratory strategy.&lt;/p&gt;

&lt;p&gt;Without this clarity, QA are left with waiting until a job is done and not knowing what they're going to get - which is a recipe for annoying manual regression testing, and no doubt, bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agile Demands Quality, Quality Brings Clarity
&lt;/h2&gt;

&lt;p&gt;Agile is about iterating fast. You cannot do this when QA are held back by a requirement to constantly manually regression test, or worse still, you avoid regression testing and hope new development doesn't break anything.&lt;/p&gt;

&lt;p&gt;With good Acceptance Criteria baked into the process, everyone has clarity. As a developer, this makes your life so much easier. You know what needs to be developed before you start, which allows you to concentrate on technical implementation details. With clear requirements, the code is cleaner, so development and maintenance is easier. This allows the team to iterate fast, able to add new features quickly.&lt;/p&gt;

&lt;p&gt;Early automated testing becomes a something that fits into the process, and with this automation in place, QA can focus on exploration. With automation, we are able to develop with confidence, and innovate freely.&lt;/p&gt;

&lt;p&gt;Quality no longer slows down the development process, but guides it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's&lt;/em&gt; why developers should care about quality.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>tdd</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How to name Unit Tests</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Mon, 02 Dec 2024 23:59:11 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/how-to-name-unit-tests-5ff3</link>
      <guid>https://dev.to/stuartdotnet/how-to-name-unit-tests-5ff3</guid>
      <description>&lt;p&gt;How should you name your Unit Tests? What standards should you have in place for their names?&lt;/p&gt;

&lt;p&gt;Who cares.&lt;/p&gt;

&lt;p&gt;I'm not going to tell you the exact structure and format you need to use. That's up to you, your company, your Technical Lead, or whoever thinks this is important.&lt;/p&gt;

&lt;p&gt;What I'm here to tell you is there are certain things you should always do when naming Unit tests and that &lt;em&gt;it is quite important that these things are done.&lt;/em&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.amazonaws.com%2Fuploads%2Farticles%2F4nvtlgzletog129yx2fn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4nvtlgzletog129yx2fn.png" alt=" " width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what are these important things that you need to do when naming Unit tests?&lt;/p&gt;

&lt;p&gt;They need to be named in a way that tells you what &lt;strong&gt;scenario&lt;/strong&gt; they are testing and what the &lt;strong&gt;outcome&lt;/strong&gt; should be. Seems obvious but there's a bit of an art to this, and it's very easy to do wrong.&lt;/p&gt;

&lt;p&gt;Why is it important for unit tests to tell you what they do? It's because coding is a team sport. Code needs to be read and maintained. Unit Tests are code and they also serve as documentation of your functionality. More so sometimes, than the code itself.&lt;/p&gt;

&lt;p&gt;Other people (including future you) need to be able to look at the names of the test and know what specifically is being tested. Not just the what, but the when. When does the thing that you're testing happen? What is specific to this particular scenario that makes it special?&lt;/p&gt;

&lt;p&gt;An example of naming being done badly would be Verify_Process. What does verify actually mean, and what is the Process?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Oh, the method you're testing is called "SomethingProcess()"? Well that's a problem right there. Rename it to explain what exactly the "process" is doing!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Also, verify doesn't tell me anything. What are you verifying? What makes the thing you're testing “verified”? How is someone who looks at this code in 18 months going to know that by looking at this name? If they can't determine its purpose from the name they'll end up having to look through the code of the test, which is a considerably slower process.&lt;/p&gt;

&lt;p&gt;Telling us just what the test does is also not enough. AddNewCustomerTest is not enough. What scenario are you testing? That a new customer can be added is not a scenario but an action. What about testing when a customer is not added successfully, for some reason, or when they are added but already exist?&lt;/p&gt;

&lt;p&gt;Also, when are they being added? For example, you might name the test: WhenCustomerHasFullName_CustomerAddedSuccessfully. Here is a test which tests the scenario of when the customer's full name is included in the post. The name includes the scenario "When the Customer's full name is entered" and the expectation: "Customer Added Successfully".&lt;/p&gt;

&lt;p&gt;Including the scenario is the critical part of your test name. It explains the conditions of the action you’re performing. "When I do this". "When this data is included". "When I try to access this as an administrator".&lt;/p&gt;

&lt;p&gt;The expectation is your expected result. The outcome of the test. This is as critically important as the scenario. Together they form a combination explaining the reason the test exists. "When this happens, this should happen".&lt;/p&gt;

&lt;p&gt;Some of you may be aware of the pattern "SystemUnderTest_When_Then" for naming tests. This is fine, and I would recommend this structure, but only because it includes the scenario and the expectation. System under test, or the thing that you're testing, is descriptive and useful of course, but it can be easily inferred by looking at the code (unlike the scenario; and expectations can usually be easily gleaned from the Assertions), and also, you could include this in the class name, tags, or some other descriptor.&lt;/p&gt;

&lt;p&gt;It's the &lt;strong&gt;scenario&lt;/strong&gt; and &lt;strong&gt;expectation&lt;/strong&gt; that anyone looking at the tests wants to know. These are the critical parts of a test's name.&lt;/p&gt;

&lt;p&gt;Getting this right not only means that your tests are easy to follow and understand, but it encourages you to think up more combinations. You can write these combinations of scenario/expectation out before you even complete the bodies of the tests. If you were to name a test "GetTimeZoneTest", or "FileProcessorTest" how would you do this?&lt;/p&gt;

&lt;p&gt;It's worth noting too, that you can include everything I talk about here in Description Attributes, or Tests Cases, if that's preferred, over the Test name. The point is that it's clear what the tests are doing.&lt;/p&gt;

&lt;p&gt;By including the scenario and the expectation in your test names/descriptions, it will encourage you to think like a tester. You will become concerned with &lt;em&gt;why&lt;/em&gt; you are writing the tests, and learn to link scenarios with expectations.&lt;/p&gt;

&lt;p&gt;It will also make your tests easy to read and forms helpful documentation for future maintainers.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cleancode</category>
      <category>unittesting</category>
    </item>
    <item>
      <title>Don't Chase Unit Test Coverage</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Sun, 13 Nov 2022 09:57:18 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/why-chasing-unit-test-coverage-can-be-a-bad-idea-de0</link>
      <guid>https://dev.to/stuartdotnet/why-chasing-unit-test-coverage-can-be-a-bad-idea-de0</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.amazonaws.com%2Fuploads%2Farticles%2F0hexr086zpxp5lj7msst.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hexr086zpxp5lj7msst.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the long running battle between management chasing metrics and developers just trying to get the job done, (hi boss!)  I wanted to provide some less obvious examples of why chasing code coverage is a damaging process. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why Unit Test Code Coverage targets are bad
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Code Coverage can be gamed, incentivising low quality tests
&lt;/h2&gt;

&lt;p&gt;If the coverage percentage is all that matters, there are many ways to increase that number without actually improving the quality and reliability of the code. Having a test doesn’t mean no bugs - it just means the code is being run by a test, that the pathways through the code are exercised by another piece of code. &lt;/p&gt;

&lt;p&gt;There’s not really any link in these tests to importance of functionality, or even any consideration of code doing the right thing, just that it’s being exercised.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests add a maintenance burden
&lt;/h2&gt;

&lt;p&gt;In the writing of low value tests written only to satisfy KPIs, developers are actually making more work for themselves in the future. &lt;/p&gt;

&lt;p&gt;All code adds a maintenance burden. Tests are code so adding tests adds to this burden. If they’re not valuable, they’re detrimental.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chasing coverage leads to more brittle tests
&lt;/h2&gt;

&lt;p&gt;The more coverage you have, the more brittle your tests actually become. By covering every internal path of a method, you are tightly coupling the tests with the implementation details. &lt;/p&gt;

&lt;p&gt;This goes against the spirit of testing. You should be testing the functionality of the code - the inputs, outputs, and decisions it makes, and the edge cases.You don’t need to be too concerned with how it makes those decisions. &lt;/p&gt;

&lt;p&gt;This in turn makes you write tests the right way - thinking about the desired functionality instead of the coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give a false impression of robust code
&lt;/h2&gt;

&lt;p&gt;It should be obvious but it’s often overlooked. High coverage, which as discussed leads to low quality tests which often don’t test the right things, gives a false sense of security. You may have 80% coverage but if the last 20% is all the business critical functionality, or vital areas of the code, this could be hiding big problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chasing metrics hides opportunities to improve the code quality
&lt;/h2&gt;

&lt;p&gt;Let’s remember why we write tests in the first place. It’s to have confidence that our code is meeting the requirements, can handle edge cases, and is free of bugs. By focusing on coverage, you are missing the opportunity to write tests which do this - tests which actually lead to better quality code.&lt;/p&gt;

&lt;p&gt;Thinking about what scenarios you need to cover when writing code, encourages you to write the code in a testable way. If you write it in a testable way, you’ll be more likely to write tests - valuable tests. Better still, you’ll be more inclined to write the tests, or at least stubs of them, first (Test Driven Development).&lt;/p&gt;

&lt;p&gt;If you write code and then add tests as an afterthought, you’ll probably focus on coverage instead of functionality, because you’ll be thinking about “adding tests” and increasing coverage - rather than thinking about the original intentions of the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Code Coverage is good
&lt;/h1&gt;

&lt;p&gt;Despite all these issues, Code coverage has a place in software development and there are some benefits to monitoring it, as opposed to incentivising it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifies areas of low coverage
&lt;/h2&gt;

&lt;p&gt;In combination with your knowledge of where important functionality lies, you can see where tests are needed. Without code coverage metrics, it’s pretty hard to do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instills a culture of continually adding tests as you go
&lt;/h2&gt;

&lt;p&gt;Let’s not forget that we want to be writing tests. We’ll get good coverage just by doing it as a habit, and by monitoring the coverage, we’ll see it go down if we write code that’s untested. So this encourages us to keep up with writing tests as we add features, and helps us see when we’re not adding them.&lt;/p&gt;

&lt;p&gt;This keeps test writing on everyone’s minds, and influences the culture to make people value tests. &lt;/p&gt;

&lt;p&gt;If you’re not measuring, you don’t know if you’re improving!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This article is very much a developer’s perspective, but at the end of the day, code coverage is a Return on Investment decision. Care should be taken on where the coverage is increased. Writing tests for existing code should be done in a way that prioritises high value, low effort new tests.&lt;/p&gt;

&lt;p&gt;Code coverage is a good thing in that it gives a picture of where you are, and helps you monitor your testing journey. It’s always problematic to incentivise metrics, or even push to maintain a level. But we should be mindful of the level of coverage. &lt;/p&gt;

&lt;p&gt;Focus on code coverage detracts from why you should be writing tests in the first place. The important thing is that we build tests around requirements and edge cases - tests which exercise and document real life scenarios. Tests are not about lines of code covered. This is an indicator - not an incentive.&lt;/p&gt;

&lt;p&gt;Writing tests is a very important part of software development. Do it for the right reasons, and it will be done well. &lt;/p&gt;

</description>
      <category>unittesting</category>
      <category>codequality</category>
      <category>testing</category>
      <category>testautomation</category>
    </item>
    <item>
      <title>The Importance of Good Acceptance Criteria</title>
      <dc:creator>Stuart Dobson</dc:creator>
      <pubDate>Thu, 23 Sep 2021 07:49:50 +0000</pubDate>
      <link>https://dev.to/stuartdotnet/the-importance-of-acceptance-criteria-5gn8</link>
      <guid>https://dev.to/stuartdotnet/the-importance-of-acceptance-criteria-5gn8</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.amazonaws.com%2Fuploads%2Farticles%2Fz2klbprb5pypb4q710pq.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.amazonaws.com%2Fuploads%2Farticles%2Fz2klbprb5pypb4q710pq.jpg" alt="Acceptance Criteria" width="800" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acceptance Criteria can be seen as a chore, a convoluted, verbose set of prose with the sole purpose of satisfying "the business". At best, its value is underestimated and it is often written as a vague list of requirements.&lt;/p&gt;

&lt;p&gt;Given the right attention, Acceptance Criteria can be extremely valuable to all members of a Scrum team. Before it can be done correctly, we have to understand its value.&lt;/p&gt;

&lt;p&gt;So what exactly is the point of Acceptance Criteria?&lt;/p&gt;

&lt;h1&gt;
  
  
  Purpose of Acceptance Criteria
&lt;/h1&gt;

&lt;h2&gt;
  
  
  To define boundaries
&lt;/h2&gt;

&lt;p&gt;Acceptance criteria help development teams define the boundaries of a user story. In other words, acceptance criteria help you confirm when the application functions as desired.&lt;/p&gt;

&lt;h2&gt;
  
  
  To reach consensus
&lt;/h2&gt;

&lt;p&gt;Having acceptance criteria synchronises the development team with the client. The team knows exactly what conditions should be met, just as the client knows exactly what to expect from the developed functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  To allow for accurate planning and estimation
&lt;/h2&gt;

&lt;p&gt;Acceptance criteria scenarios allow for the correct division of user stories into tasks so user stories are correctly estimated and planned.&lt;/p&gt;

&lt;h2&gt;
  
  
  To serve as a basis for tests
&lt;/h2&gt;

&lt;p&gt;Acceptance criteria provide a good baseline for writing tests. Test cases can break down Acceptance Criteria to go into more functional detail, and to cover edge cases.&lt;/p&gt;

&lt;h1&gt;
  
  
  Acceptance Criteria helps the team deliver quality
&lt;/h1&gt;

&lt;p&gt;Acceptance Criteria is vital for delivering quality. If done correctly, it can simplify development and guide a comprehensive testing strategy. It is the glue that holds requirements together.&lt;/p&gt;

&lt;p&gt;Acceptance Criteria is valuable to all stakeholders; Developers, QA, Product Owners, and the team as a whole. How it helps each stakeholder, however, varies according to their role.&lt;/p&gt;

&lt;h1&gt;
  
  
  Good Acceptance Criteria
&lt;/h1&gt;

&lt;h2&gt;
  
  
  How it benefits Developers
&lt;/h2&gt;

&lt;p&gt;Good Acceptance Criteria gives developers clarity and allows them to break down their tasks into manageable pieces of functionality. With visibility of all possible scenarios, good Acceptance Criteria actually allows optimum design of the code. It enables developers to structure their code in a way that best meets the requirements. The code can be written around each scenario, ensuring each criteria is met in the simplest way possible.&lt;/p&gt;

&lt;p&gt;The clarity given by good Acceptance Criteria keeps the business requirements at the forefront of the developer's mind, helping them to avoid getting bogged down in technical details which may not be conducive to the task.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it benefits QA
&lt;/h2&gt;

&lt;p&gt;Good Acceptance Criteria can guide QA in generating test cases and any required test data. With clear, simple scenarios, QA will have a solid base for test cases, and can then focus on expanding the Acceptance Criteria to cover edge cases.&lt;/p&gt;

&lt;p&gt;Without clear, broken down Acceptance Criteria, it can be hard to work out test cases. If this happens, certain scenarios might be missed, and the important expectations of the job might be overlooked.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it benefits the team
&lt;/h2&gt;

&lt;p&gt;Good Acceptance Criteria helps get all the team on the same page. It aligns everyone with common goals, and helps them work together to build out the requirements. This collaboration is important and often overlooked.&lt;/p&gt;

&lt;p&gt;Development and QA can come together at the start of a task in order to work out what needs to be tested. This allows Development to perform some degree of Test Driven Development. Even if it isn't possible to write automated tests before the code, the developer will at least have a good idea of what those tests are going to be before writing any code.&lt;/p&gt;

&lt;p&gt;QA can guide this process, elaborating on what they will be testing, helping to set up test data, and informing the developer of possible edge cases to watch out for.&lt;/p&gt;

&lt;p&gt;If the Acceptance Criteria is missing anything, the Product Owner can be questioned for more details before the work commences. Without clear Acceptance Criteria, there is no way of knowing if there are any missing details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Good Acceptance Criteria can make a difference
&lt;/h1&gt;

&lt;p&gt;With good Acceptance Criteria, the team is able to see, at a glance, what is required from a task. It provides a consensus for the whole team which aids both planning and delivery.&lt;/p&gt;

&lt;p&gt;Good Acceptance Criteria helps developers come up with cleaner code. It makes testers' lives much easier. It helps the team come up with the best Automated Testing solutions, which is vital for Agile projects. It helps the team plan the best possible approach, and avoids stumbling into questions mid-development.&lt;/p&gt;

&lt;p&gt;Don't underestimate the value of good Acceptance Criteria. It can increase productivity, collaboration, and quality.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>acceptancecriteria</category>
      <category>planning</category>
    </item>
  </channel>
</rss>
