# What Does `scripts/check-rule-copies.js` Compare to Keep the Ruleset Aligned?

> Understand how scripts/check-rule-copies.js aligns the ponytail ruleset by comparing AGENTS.md canonical rule bodies with editor-specific copies and verifying invariant phrases in SKILL.md.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: internals
- Published: 2026-09-12

---

**The [`scripts/check-rule-copies.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/check-rule-copies.js) validation script compares the canonical rule body stored in [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md) against compact copies distributed across editor-specific directories, while simultaneously verifying that critical invariant phrases appear in both [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) and [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md), ensuring the entire ruleset remains synchronized.**

In the DietrichGebert/ponytail repository, maintaining consistent coding guidelines across multiple AI agent configurations requires rigorous validation. The Node.js utility located at [`scripts/check-rule-copies.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/check-rule-copies.js) serves as the automated gatekeeper that prevents documentation drift by performing two distinct comparative analyses every time it runs.

## Comparing Canonical Rules Against Compact Copies

The primary function of the script is to ensure that distributed rule files remain identical to the source of truth. At **line 16**, the script extracts the **canonical rule body** from [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md), which serves as the master reference for all agent instructions.

The script then iterates through an internal list of **compact copy locations**, including:

- `.cursor/rules/ponytail.mdc`
- [`.windsurf/rules/ponytail.md`](https://github.com/DietrichGebert/ponytail/blob/main/.windsurf/rules/ponytail.md)
- [`.github/copilot-instructions.md`](https://github.com/DietrichGebert/ponytail/blob/main/.github/copilot-instructions.md)

For each target file, the script applies normalization functions—either `stripFrontmatter` to remove YAML headers or a simple `trim` operation—to eliminate formatting differences. The normalized text is then compared character-for-character against the canonical body at **lines 31-34**. If any compact copy deviates from the original, the script immediately logs a drift warning and terminates with exit status 1.

## Validating Rule Invariants Across Authoritative Sources

Beyond file matching, the script enforces semantic consistency through a hardcoded **invariant phrase list**. Defined in the `INVARIANTS` array at **lines 45-57**, these critical safety and quality phrases—such as "input validation at trust boundaries" and "prevents data loss"—must appear verbatim in both [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) and [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md).

The script reads both authoritative sources and checks for the presence of every invariant phrase. If **line 65** detects a missing phrase in either file, it outputs a specific error message identifying the violation, preventing merges that would fragment the safety guidelines.

## Running the Validation Locally

Developers can execute the validation script manually to verify ruleset alignment before committing changes.

```bash

# Verify all rule copies and invariants

node scripts/check-rule-copies.js

```

A successful run produces confirmation that all copies match and invariants are present:

```bash
Rule copies match AGENTS.md; 13 rule invariants present in SKILL.md and AGENTS.md.

```

## Interpreting Drift Detection Output

When the script detects misalignment, it provides explicit feedback about which file contains the discrepancy.

```bash
$ node scripts/check-rule-copies.js
.github/copilot-instructions.md drifted from AGENTS.md
Update the copied rule text, AGENTS.md, or SKILL.md so the shared rules match.

```

To resolve the failure, either restore the compact copy to match the canonical [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md) version, or update [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md) and propagate the change to all listed copy locations.

## Summary

- **[`scripts/check-rule-copies.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/check-rule-copies.js)** performs two validation checks: canonical rule comparison and invariant phrase verification.
- The script extracts the master rule body from **[`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md)** at line 16 and compares it against normalized versions of editor-specific copies.
- An **`INVARIANTS`** array at lines 45-57 defines mandatory safety phrases that must appear in both **[`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md)** and **[`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md)**.
- Any detected drift triggers a non-zero exit status, blocking merges until the ruleset is reconciled.

## Frequently Asked Questions

### What files does [`scripts/check-rule-copies.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/check-rule-copies.js) check for rule alignment?

The script checks compact copies located at `.cursor/rules/ponytail.mdc`, [`.windsurf/rules/ponytail.md`](https://github.com/DietrichGebert/ponytail/blob/main/.windsurf/rules/ponytail.md), [`.github/copilot-instructions.md`](https://github.com/DietrichGebert/ponytail/blob/main/.github/copilot-instructions.md), and other defined paths against the canonical source in [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md). It also validates that invariant phrases exist in both [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) and [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md).

### How does the script normalize text before comparing rule copies?

The script applies either a `stripFrontmatter` function to remove YAML metadata blocks or a basic `trim` operation to each compact copy before performing the equality check. This ensures that formatting differences do not trigger false positives during the comparison at lines 31-34.

### What happens if an invariant phrase is missing from the rules?

If any phrase defined in the `INVARIANTS` array is absent from either [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) or [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md), the script outputs an error message at line 65 and exits with status 1. This enforcement ensures that critical safety requirements remain present across all authoritative documentation.

### Can the script be integrated into CI/CD pipelines?

Yes, because [`scripts/check-rule-copies.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/check-rule-copies.js) returns a non-zero exit code when it detects drift or missing invariants, it can serve as a gate in continuous integration workflows. Any mismatch will fail the build, forcing developers to reconcile rule differences before merging pull requests.