Skip to the content.

Module 2: Guardrails before skills · Lesson 4 of 7 · 3 min read

Write the guardrail before the skill

Start from 'how would I know this was wrong?', turn an atom's rules into a script, and let the skill become the checklist that passes it.

The order people get wrong

The agent harness playbook names the mistake: writing the skill first feels productive because prose is easy, and it produces a harness where the standard lives in a paragraph nobody can run. Start instead from one question — how would I know this was wrong? — and write that check. For a component the playbook lists three: does the folder have a story file, does the source import from the store, is the interactive element reachable by keyboard.

Why the story file is rule one

A Story is “a component development snapshot” — one visual state with precise props and data, or in the doc’s words, “unit tests for the eyes”. Every atom in the templates ships one: templates/chota-react-redux/src/ui/atoms/Button/ holds Button.component.jsx, Button.style.css, Button.stories.js and Button.test.jsx.

The atom guardrail question makes a missing story a failure, because “an atom nobody can see in isolation is not reusable”. It is also the cheapest check there is. The question splits its rules in two:

  • Structural — the three files exist; the component is under 120 lines. File-system facts: they cost nothing and never give a false negative. Write these first.
  • Semantic — no import from src/state, src/containers or a store package; no useEffect, onMounted or ngOnInit doing I/O; every button, link and input has an accessible name.

Stories keep paying later. The ui-story skill’s quality gates ask for a story per meaningful state — error, empty, loading — with args rather than inline props, and the accessibility gate in the next lesson renders each component from its stories. The story is what turns a component into something a script can render.

A first checker

// node check-atom.mjs src/ui/atoms/Button
import { readdirSync, readFileSync } from "node:fs";
const dir = process.argv[2].replace(/\/$/, ""), name = dir.split("/").pop(), files = readdirSync(dir), fail = [];
for (const kind of ["component", "style", "stories"])
  if (!files.some((f) => f.startsWith(`${name}.${kind}.`))) fail.push(`${dir}: missing ${name}.${kind}.* (rule 1)`);
const src = files.find((f) => f.startsWith(`${name}.component.`));
if (src && /from\s+["'][^"']*(\bstate\/|containers\/|redux|@ngrx|pinia)/.test(readFileSync(`${dir}/${src}`, "utf8")))
  fail.push(`${dir}/${src}: atom imports from the store (rule 2)`);
fail.forEach((line) => console.log(line));
process.exit(fail.length ? 1 : 0);

Every message names the file and the rule, as the question’s rubric requires, and no rule asks a model for an opinion. A regex over import lines is the right first pass; upgrade it when a false positive actually bites. The accessible-name rule will not survive regexes for long — it is a property of the rendered DOM, which is where the templates’ Vitest setups take over.

Now write the skill, then run the loop

With the check in place, the skill is just the checklist that makes it pass first time. Point an agent at a broken atom:

Make `node check-atom.mjs src/ui/atoms/Badge` exit 0.
Do not edit check-atom.mjs. Paste its output after every attempt.

Record how many attempts it takes, and watch for gaming: the 120-line rule can be met by moving code into a sibling file. When that happens, the rule measured the proxy instead of the thing.

Encode it, then practise it

Agent Skill: ui-story The SKILL.md that encodes Story for a coding agent. Install it into your agent, or download it for any Agent-Skills-compatible runtime.
npx skills add grvpanchal/elegant --skill ui-story
Download ui-story SKILL.md

Practise it

Write a guardrail for the ui-atom skill

Turn "this is a good atom" into a script an agent cannot argue with, then run an agent against it.

harness medium ui 40 min Solved

Course contents (7 lessons)

Module 1: What a skill is

  1. A skill, a guardrail and a loop done
  2. Anatomy of a SKILL.md done
  3. Install a skill and let paths activate it done

Module 2: Guardrails before skills

  1. Write the guardrail before the skill done
  2. Thresholds, baselines and scope done

Module 3: Closing the loop

  1. When the agent satisfies the measure, not the goal done
  2. Score a skill with an eval set done