# Scripts and Validators

Course: [Agent Skills](https://www.devtutorials.ai/learn/agent-skills) · Section: Skill Resources
Source: https://www.devtutorials.ai/learn/agent-skills/resources/scripts-and-validators

> Which rules need a script instead of the model, how the agent runs a validator and fixes its reply, real validators across the stack, short OK/FAIL output, and telling the agent when to run each script.

## Some Rules Need Code, Not Words

A **validator** = a small script that checks a reply against one exact rule. In this lesson, you will learn which rules need a script. You will also learn how a skill tells the agent to run it.

A model is good at reading and writing.

But it is not good at exact work.

For example, a model may:

- miscount characters in a line
- guess a contrast ratio by eye
- miss one leaked key in a long file
- skip one heading out of five

A script does not guess. It gives the same answer every time.

**Simple lesson:** let the model write. Let a script check the exact rules.

### A Real-World Example

A cook tastes the soup to see if it is good.

But the cook uses a thermometer to see if the chicken is safe.

Taste is judgment. Temperature is a number. Skills work the same way: the model judges, and the script measures.

Click the button and open the **Run** tab. Press **Run**.

- **Under the reply:** a line that starts with **Script OK**.
- **The number:** `#9CA3AF on #FFFFFF = 2.54:1`. The rule needs 4.5:1.
- **The result:** the review called out the faint text, and the script confirmed it.

**Simple lesson:** a script turns "looks fine" into an exact number.

## What You Will Learn

In this lesson, you will learn:

1. Which rules should be scripts, and which should stay with the model.
2. How the agent runs a script, reads the result, and fixes the reply.
3. How real validators check UI, frontend, backend and security replies.
4. How to write output that the agent can act on.
5. How to tell the agent in `SKILL.md` when to run each script.

**About this lesson's Skill Lab**

- The lab runs every `scripts/*.js` file in a skill on each reply.
- You see **Script OK** or **Script FAIL** under the reply.
- Each lab script gets the reply as `output`. It returns a line that starts with `OK` or `FAIL`.
- In a real project, the same check is usually a Node or Python script that reads a file.

## Script or Model?

Ask one question about each rule.

Does it have one exact right answer?

**Give it to a script when:**

- the rule has one right answer
- it needs counting, measuring or pattern matching
- a mistake is costly and easy to miss

**Keep it with the model when:**

- the answer needs judgment
- it needs to understand what the user meant
- several answers could be fine

Example:

- "Contrast is at least 4.5:1" → script.
- "This error message is friendly" → model.
- "No verbs like `/get` in the route" → script.
- "This API design makes sense" → model.

**Simple lesson:** the best skills use both. The model decides. The script checks.

## The Fix Loop

A script is only useful if the agent acts on what it prints.

The loop has four steps:

1. Write a draft.
2. Run the script on it.
3. Read the result.
4. If it says FAIL, fix that problem and run the script again.

Watch `release-note-helper` go round this loop:

The script needed three runs. Each FAIL named one exact problem.

**Important:**

- Only the short result enters the agent's context, not the script's code.
- So a script costs very few tokens.
- The user sees only the final reply, which passed every rule.

**Simple lesson:** the agent keeps fixing until the script says OK.

## Validators Across the Stack

Every DevKit stack skill has one script for its most slippery rule.

| Skill | The rule that kept slipping | The script |
| --- | --- | --- |
| `ui-review` | Faint text was called "fine" | `check_contrast.js` works out the real ratio |
| `react-component` | A clickable `<div>` or a hard-coded color | `check_component.js` |
| `api-endpoint` | A route like `/getOrders`, or SQL built from input | `check_route.js` |
| `security-review` | No severity labels or OWASP categories | `scan_secrets.js` |

Watch each script check two replies to the same request:

The reply without a skill fails every time. The reply with the skill passes.

Click the button and open the **Run** tab. Press **Compare**.

- **Without the skill:** the reply uses `/getOrders` and builds SQL from the request. `check_route.js` fails it.
- **With `api-endpoint`:** the route and the query follow the rules. The script prints OK.

Press **Compare** again.

- **Without the skill:** no severity labels and no OWASP categories. The script fails it.
- **With `security-review`:** the reply passes, and shows only `acme...` instead of the whole key.

A secret scanner only finds the patterns it knows.

A clean scan does not prove the code is safe.

Use it next to your platform's secret scanning and pre-commit hooks, not instead of them.

**Simple lesson:** one small script per slippery rule is enough.

## Good Script Output

The agent reads the script's output to decide what to do next.

So the output must be short and clear.

Good output:

- starts with **OK** or **FAIL**
- names each problem on its own
- says where the problem is, so it is easy to fix
- is a few lines, not a long dump

Example:

```text
check_component: FAIL (2)
  - clickable <div> (use <button>)
  - hard-coded #ccc (use a token)
```

**Important:** real scripts should also set an exit code. Use 0 for OK and 1 for FAIL. Then CI and Git hooks can use the same script.

**Simple lesson:** if the agent can't tell what to fix, the script is not done.

Click the button and open the **Library** tab.

- **Each check:** one short test, such as "has a Props type".
- **The last line:** returns OK, or FAIL with every problem joined together.

## Tell the Agent When to Run It

A script in the folder does nothing on its own.

The agent runs it only if `SKILL.md` says so.

In **Final checks**, say three things:

- **When** to run it, for example "before replying".
- **What the result looks like**, OK or FAIL.
- **What to do on FAIL**, fix each problem and run it again.

```markdown
## Final checks
- Before replying, run scripts/check_route.js on your answer.
- It prints OK, or FAIL with each problem.
- On FAIL, fix each problem and run it again.
```

Keep each script small and easy to read.

A reviewer should understand it in a minute.

If a script grows large, move it into CI or a real tool.

**Simple lesson:** a script nobody mentions is a script nobody runs.

## Write Your Own Validator

Add a script to `test-planner` that needs at least one **integration** test.

1. Open `test-planner` in the Library.
2. Type `scripts/check_integration.js` in the path box and press **+ Add file**.
3. Paste this function body and press **Save**:

```js
return /\[integration\]/.test(output) ? "OK" : "FAIL no integration test listed";
```

4. In `SKILL.md`, add a final check: "Before replying, run scripts/check_integration.js on the plan." Press **Save**.
5. Go to **Run**, pick **Test plan**, and press **Run**.

The recorded plan has only unit tests. So your new script fails.

**Simple lesson:** a new rule is one short file plus one line in Final checks.

## TL;DR

1. **Validator** = a small script that checks a reply against one exact rule.
2. Scripts check exact rules:
   - counting, measuring, pattern matching
   - required headings and their order
3. The model keeps judgment:
   - is it clear, friendly, sensible
4. **Fix loop** = draft → run script → read result → fix → run again.
5. Only the script's short result enters the context. So scripts are cheap.
6. Good output starts with OK or FAIL and names each problem.
7. In `SKILL.md`, say when to run the script and what to do on FAIL.
8. A clean scan is a safety net, not proof.

## Common Mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Asking the model to check exact rules | "The model can count." | Put counting and measuring in a script. | The model miscounts and says "looks fine". |
| Scripts that print too much | "More output is more helpful." | Print OK or FAIL and a short list. | The agent wastes tokens and misses the problem. |
| A script the body never mentions | "The agent will find it." | Name it in Final checks, with when to run it. | The script is never run. |
| No step for a FAIL result | "The agent knows what to do." | Say "fix each problem and run it again". | The agent replies with a failing answer. |
| Showing full secrets in output | "Print the key so we can find it." | Print a short prefix and the line number. | The secret leaks again into the chat. |
| Treating a clean scan as proof | "No FAIL means safe." | Use other security tools too. | Unknown secret formats slip through. |
| Running scripts you have not read | "A shared skill is safe." | Read every script before you run it. | A downloaded script runs on your machine. |

## Check Your Understanding

## Exercises

These exercises help you practise scripts and validators.

Press **Check** when you are ready. Use **Show Hint** if you get stuck.

## What to Remember

- A script does exact work. The model does judgment.
- The agent drafts, runs the script, fixes, and runs it again.
- Each DevKit stack skill has one script for its most slippery rule.
- Good output is short. It starts with OK or FAIL and names each problem.
- Final checks must say when to run the script and what to do on FAIL.
- A clean scan is not proof. Read every script before you run it.

Next: **Choosing the Right Owner**. You will decide which jobs belong in a skill, and which belong in instruction files, tools or plugins.
