Authors

Vedanshu Joshi
Vedanshu Joshi Software Engineer
GP Saggese
GP Saggese Chief Technology Officer
Shayan Ghasemnezhad
Shayan Ghasemnezhad Infrastructure & DevOps Lead Engineer

Metadata

Monday, May 18, 2026
Software Engineering Developer Tools
TL;DR

Three building blocks close the gap between a capable AI and a reliable team member: skills that encode one task precisely, rules files that capture conventions once, and templates that show Claude what good output looks like.


AI coding assistants are powerful, but they are stateless. Every new conversation starts from zero. Ask Claude to format a file on Monday and again on Friday and you will likely get two different results. The docstring style, import order, and comment density will differ unless you re-explain your conventions each time.

For a small codebase or a solo developer, re-explaining is tolerable. For a team of ten working across a 500,000-line Python monorepo with strict style rules, it is a bottleneck. Every developer phrases the same request slightly differently. Claude interprets each phrasing slightly differently. The result is AI-assisted code that is inconsistent in style, unpredictable in quality, and expensive to review.

We hit this problem early at Causify. Our solution is a library of reusable skills (small markdown files that encode exactly how to do one thing, managed by a tool called mdm). This post explains how the system works and why the design choices matter.

The Inconsistency Problem#

The root cause is not that AI models are bad at following instructions. It is that instructions are re-specified from scratch in every session, by every developer, in slightly different language.

A conventional linter solves this for syntactic style: one config file, one run, consistent output. AI assistance does not have an equivalent. The conventions that matter most (how to structure a docstring, how to name a test, when to use a golden file instead of an inline assertion) live nowhere but in the team's collective memory and in code review comments.

Skills are our version of that config file.

Skills: Encoding One Convention at a Time#

A skill is a markdown file that tells Claude exactly how to perform one specific task, following the team's rules. It lives in the .claude/skills/ directory as <topic>.<action>/SKILL.md.

The simplest skill looks like this:

---
description: Fix Python Docstrings
---

- I will pass you one or more files `<files>`

- Read and apply the rules from `.claude/skills/coding.rules.md`
    `## Use REST Style for Comments`

- Make sure that the intention of the code is not changed

That is the entire file for coding.fix_docstring. It is small because the conventions themselves live in coding.rules.md. The skill is a thin wrapper that says "apply those rules to this file."

Invoking it in Claude Code is one command:

/coding.fix_docstring

Claude loads the skill, reads the rules file it references, and applies the conventions to the current file. No re-explanation needed. Same output whether it is Monday or Friday, and whether the request comes from a senior engineer or an intern.

The Key Design Decision: Rules vs Skills#

The most important structural choice in the system is the separation between rules files and skills.

A rules file (<topic>.rules.md) captures conventions for an entire domain. coding.rules.md defines how all Python code in the project should look: docstring format, import order, comment style, type hint conventions, and more. testing.rules.md defines how unit tests should be structured: test class naming, golden file patterns, what to mock and what not to.

A skill (<topic>.<action>/SKILL.md) does one specific thing and references the relevant rules file for the conventions it needs.

The consequence is that the two can evolve independently at different rates:

  • coding.rules.md changes when the team decides to update a convention (e.g., switch from """ to ''' for docstrings).
  • Every skill that cites coding.rules.md picks up the change automatically, and no skill file needs to be edited.

Compare this to the alternative: duplicating convention prose in every skill. When the convention changes, every skill that duplicated it must be found and updated. Skills and conventions drift apart. Claude gets inconsistent instructions depending on which skill was last updated.

The rules/skills split is, in essence, applying the DRY principle to AI instructions.

Templates: Concrete References, Not Abstract Descriptions#

Rules files tell Claude what good looks like. Templates show it.

A template is a reference implementation stored in .claude/templates/ that rules and skills point to directly:

  • code.template.py: canonical Python file structure
  • testing.template.py: canonical test file structure
  • notebook_template.ipynb: canonical notebook structure

Instead of describing in prose that "functions should have a one-line summary followed by Args and Returns sections", coding.rules.md points to code.template.py and says "follow this structure." Claude reads the file and extracts the pattern directly, which is more reliable than parsing a description of the pattern.

Templates are the third leg of the system: rules say what, skills say how, templates show what the result should look like.

Managing the Library with mdm#

Over time, we accumulated 120 skills covering coding, testing, markdown formatting, notebook style, slide creation, blog writing, and more. Managing them individually with vim and find was becoming its own chore.

mdm (Markdown Document Manager) is a Python CLI that provides a single, consistent interface for all markdown content types in the repository: skills, rules files, blog posts, research notes, and stories.

# See everything available.
mdm skill list

# Find skills in a specific domain.
mdm skill list coding

# Read descriptions without opening files.
mdm skill describe

# Create or edit a skill (generates a template automatically if new).
mdm skill edit coding.fix_empty_lines

# Copy an existing skill as a starting point.
mdm skill copy coding.fix_comments coding.fix_todo

Before mdm, each content type had its own bash script family: skill*, blog*, res*, story*. The interface was similar but not identical, and knowing which script to use required memorizing the ecosystem. mdm replaces all of them with one tool and prefix-matched arguments (sk matches skill, bl matches blog, l matches list, e matches edit).

Skills in Practice#

A typical day using the skill system:

  1. Open a Python file that needs its docstrings cleaned up.
  2. Run /coding.fix_docstring in Claude Code. Claude applies the docstring conventions from coding.rules.md without any further instruction.
  3. Open the corresponding test file. Run /testing.format. Claude writes or updates tests following testing.rules.md: golden file pattern, correct class naming, right markers.
  4. Run /markdown.format on a markdown document. The linter runs automatically as part of the skill.

Each step is one command. No session context is needed. A new team member gets the same output on day one as a veteran gets on year three.

Why Not Just Use a System Prompt?#

The obvious alternative is a long CLAUDE.md file that dumps all project conventions into a global system prompt. We do have a CLAUDE.md, but it handles project-wide invariants ("never commit without user permission", "inherit from hunitest.TestCase for tests") rather than task-specific transformation instructions.

Long system prompts have two problems as they grow:

  • Scope creep: Every convention ends up in one file, making it hard to find what applies to any specific task.
  • Inconsistency: There is no mechanism to ensure the system prompt stays aligned with actual code conventions as the codebase evolves.

Skills are scoped (one task, one file), composable (reference shared rules), and reviewable (each skill is a diff in a pull request). A system prompt is none of those things.

Custom AI agents are the other alternative for teams with more complex orchestration needs. Agents require code (Python, TypeScript), deployment, and maintenance. Skills require a text editor. For encoding conventions and triggering repeatable transformations, skills are the right level of abstraction.

The System Is Open-Source#

The .claude/ directory structure, skill files, rules files, and mdm tool are all open-source under the Apache 2.0 license in our helpers repository.

To use it in your own project:

git clone https://github.com/causify-ai/helpers.git
# Copy the .claude directory into your project root.
cp -r helpers/.claude /path/to/your/project/
# Add mdm to your PATH.
export PATH="$PATH:/path/to/helpers/dev_scripts_helpers/system_tools"

Then open the rules files in .claude/skills/ and replace the conventions with your team's own. The skill files themselves rarely need editing.

The relevant components are:

  • .claude/skills/: the skill and rules file library
  • dev_scripts_helpers/system_tools/mdm: the management CLI
  • .claude/templates/: reference templates for code, tests, and notebooks

Full documentation on the skill system:

The system takes an afternoon to set up and a few days to tune. After that, it runs silently in the background: one slash command, consistent output, every time.

Share

Related Posts

A Look at Runnable Directories: The Solution to the Monorepo vs Multi-repo Debate Friday, January 16, 2026
Stop Maintaining Tests by Hand: Causify's Open-Source pytest Framework Thursday, May 07, 2026
Back to Blogs Stop Maintaining Tests by Hand…