Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions .rulesync-global/.rulesync/skills/agents-md-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
name: agents-md-review
description: >
Review agent instruction files — AGENTS.md, CLAUDE.md, .claude/rules/*.md,
.cursor/rules/*.mdc, copilot-instructions.md — for redundancy, unverifiable
prose, tool-enforced duplication, stale commands, misplaced content, and
context-budget overrun. Use when the user says "review AGENTS.md", "check my
CLAUDE.md", "отревьюй agents.md", "проверь claude.md", "is my agents file any
good", after /init or an LLM generated one, or invokes /agents-md-review.
Also before committing a hand-edited instruction file. NOT for writing
project code, and NOT for README or human-facing docs.
targets:
- '*'
---
Instruction files are a tax paid on every session. Review them like production
code: each line must carry what the agent cannot get from the repo itself.
The best outcome is a shorter file.

## What these files actually do

Measured, so calibrate findings against this rather than against intuition:

- They **save steps, not IQ.** Runtime −28.6% and output tokens −16.6% in one
study; two others found task success flat. Nothing here makes an agent
smarter, so never justify a line by "it improves quality".
- They **cost** ~20% more inference and 14–22% more reasoning tokens. The cost
is proven, the benefit is not. Length must earn itself.
- The one reliably measured lever is **naming a tool**: mentioning `uv` moved
it from ~0 to 1.6 calls per task; repo-specific scripts 0.05 → 2.5. Lines
that steer which command runs are the highest-value lines in the file.
- **Generated files hurt**: −3% success and +20% cost, while hand-written ones
gain ~4%. Provenance is itself a finding.

## The one test

For every line: **would removing it cause the agent to make a mistake?**
If no, it goes in `Cut`. Apply this before any other rule.

## Budgets

| File | Target | Hard limit |
|---|---|---|
| `AGENTS.md` | 20–30 lines to start, ≤100 mature | Codex: whole chain capped at 32 KiB, truncated silently |
| `CLAUDE.md` | <200 lines | none, adherence degrades first |
| `copilot-instructions.md` | ≤2 pages (GitHub's own limit) | — |
| `.cursor/rules/*.mdc` | <500 lines per rule | — |
| auto-memory `MEMORY.md` | one line per entry | first 200 lines / 25 KB load |

Imports do not save context. An `@path` file loads in full at launch.

## Rules

### Content

- `dup:` **Do not restate the repo.** Project overviews, directory trees,
dependency lists, framework facts — measured at zero benefit, and they are
what generated files are made of. Exception: a repo with no documentation at
all, where they measured +2.7%.
- `noise:` **Only non-default behaviour.** The one content class confirmed
useful is non-standard practice. Language defaults, Prettier, PEP 8 — known.
- `missing:` **Name the tools you want used.** Package manager when ambiguous,
test runner, repo-specific scripts. Strongest measured effect in the corpus.
- `vague:` **Commands are executable, with flags.** `uv run pytest tests/unit -v`,
never "run the tests". A rule states what differs, never a virtue.
- `noise:` **Boundaries are addressed.** Three tiers — always / ask first /
never — each naming a path, file, or command. `never modify /app/legacy/, it
is sync on purpose` is signal; `avoid bad practices` is not a boundary.
- `enforced:` **Never re-state the toolchain.** Lint, format, types, CI: point
at the config file. Naming where enforcement lives is fine; copying the rules
it enforces is not.
- Check **security** explicitly. Present in only 14.5% of real files, yet
`never commit secrets` is the single most common useful constraint found
across 2,500 repositories.

### Integrity

- `stale:` **Verify every command and path exists.** A wrong command is worse
than a missing one — the agent trusts it. Real files grow by addition only
(median deletion under 15 words per commit), so drift is the default state,
not the exception.
- `conflict:` **Contradictions resolve arbitrarily.** Across the hierarchy,
files concatenate rather than override. Two rules disagreeing is a defect.
- `dup:` **One source of truth.** Parallel files with ~90% shared content are a
defect. One canonical file, the rest an import or a symlink — both forms are
valid, never flag the choice itself.
- **Nearest file wins.** Root carries what is shared; a package carries its own.

### Provenance

- `generated:` Unedited `/init` output or LLM boilerplate is a finding on its
own, before reading the content. Tells: polite prose, a section per repo
fact, a directory tree, "This project is a...".
- The method that works: note every correction you repeat, and promote only
what recurred. Three independent sources converge on this.

### Contested

- `unproven:` Content whose value is asserted by vendors but measured at zero —
repository overviews above all. **Report it, never cut it.** It goes in its
own section, with the cost named, and the human decides. A navigation map for
a 37-module monolith may well be the exception the studies did not cover.

## Procedure

1. **Collect.** `AGENTS.md` at every level, `CLAUDE.md`, `.claude/CLAUDE.md`,
`CLAUDE.local.md`, `.claude/rules/**/*.md`, `.cursor/rules/*.mdc`,
`.cursorrules`, `.github/copilot-instructions.md`,
`.github/instructions/*.instructions.md`, `AGENTS.override.md`.
2. **Measure.** `wc -lc` per file against the budget table. For Codex, sum the
whole chain — the 32 KiB cap applies to the concatenation.
3. **Ground.** Read the repo's own truth first: package manifests, task runner,
lint/type/format configs, CI workflows. Redundancy must be provable.
4. **Verify.** Every command and path: does the script exist in the manifest,
does the directory exist? Cheap, and it is where the real findings are.
5. **Judge** line by line. Load `references/agent-specific.md` for tool-level
checks. Load `references/salotech-layers.md` only if the repo shows the
markers listed there.
6. **Report.** Change nothing.

Never invent findings to fill a section. A lean file earns a short report.

## Report format

```
# agents-md review

<path> — <N> lines / <N> KiB — target <N> [OK|OVER]
<path> — ...

## Cut
- <file>:L<n> `<tag>` <what it duplicates, or why it is noise>

## Fix
- <file>:L<n> `<tag>` <what is wrong>. → <the concrete replacement line>

## Move
- <file>:L<n> `<tag>` → <destination> (<why it belongs there>)

## Unproven
- <file>:L<n> <what it costs> — <why its value is unmeasured>. Your call.

## Missing
- <what the agent gets wrong without it> → <the line to add>

## Verdict
lines: <before> → <after> (-<N>%)
blocking: <the single change that matters most, or "none">
```

Omit empty sections. If the file is already tight, print `Lean. Ship it.` and
the verdict line, nothing else.

## `--fix`

Report only, by default. With `--fix` or an explicit "apply it", apply `Cut`
and `Fix`, then re-measure and print the new verdict. Never auto-apply `Move`,
`Missing`, or anything in `Unproven` — those create files, invent policy, or
overrule a human's deliberate choice. Preserve any line whose intent you cannot
verify: what looks redundant to you may be a scar from a real incident.

## Boundaries

Agent instruction files only. Not code, not README, not human docs. Does not
write an `AGENTS.md` from scratch — hand-written beats generated by every
measurement available, and a generator here would produce exactly the artifact
this skill exists to catch. For a repo with no instruction file, say so and
hand back an empty 20-line skeleton, not a filled-in one.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Tool-level checks

Load when the repo targets a specific harness. Findings here use the same tags
as the core rules.

## Claude Code

- Reads `CLAUDE.md`, **not** `AGENTS.md`. A repo with only `AGENTS.md` and no
bridge is `missing:` — the bridge is either a first-line `@AGENTS.md` import
or a symlink. Both are correct; symlinks need admin or Developer Mode on
Windows, which is the only reason to prefer the import.
- A bare `@token` outside backticks **is an import**. An email address, a
handle, or `@types/node` in prose silently pulls a file or breaks. High-value
`stale:` check, and almost never caught by hand.
- Imports resolve up to **4 hops** and do not reduce context — everything loads
at launch. Splitting a long file into imports is `bloat:` disguised as
organisation.
- The hierarchy **concatenates**: managed policy → user → project → local, root
down to cwd, `CLAUDE.local.md` last within a directory. Nothing overrides
anything, so contradictions across levels are `conflict:`.
- Path-scoped content belongs in `.claude/rules/*.md` with `paths:` frontmatter.
A rule without `paths:` loads every session like `CLAUDE.md` — check that the
frontmatter is actually there when the file's content is path-specific.
- `paths:` does **not** exist in `SKILL.md`; skills load by description match.
A `paths:` key in a SKILL.md frontmatter is a `misplaced:` finding.
- Multi-step procedures belong in a skill. Anything that must happen every time
without exception belongs in a hook — `CLAUDE.md` is advisory, hooks are
deterministic. A "always run X before committing" line is `misplaced:`.
- Block-level HTML comments are stripped before injection: maintainer notes are
free, so suggest them instead of deleting context the human wants recorded.
- Auto-memory `MEMORY.md` loads only its first 200 lines / 25 KB.

## Codex

- Chain: `~/.codex/AGENTS.override.md` → `~/.codex/AGENTS.md` → every
`AGENTS.md` from git root down to cwd. Later means closer means stronger.
- `project_doc_max_bytes` defaults to **32 KiB for the whole chain**, and
overflow is dropped **silently**. In a monorepo the cap is consumed by the
sum, not by any one file — measure the chain, not the file.
- `AGENTS.override.md` at any level replaces that level entirely.
- `--print-instructions` dumps what actually merged. Prefer it over inference
when the chain is non-trivial.
- OpenAI's own guidance: keep lint and format checks in CI, not in the file.

## GitHub Copilot

- Three mechanisms coexist: `.github/copilot-instructions.md` (repo-wide),
`.github/instructions/*.instructions.md` (needs `applyTo` glob frontmatter),
and `AGENTS.md` anywhere with nearest-file precedence. A root `CLAUDE.md` or
`GEMINI.md` is accepted as an alternative.
- GitHub's stated limits: **no longer than 2 pages**, and **must not be task
specific**. A task-shaped instruction here is `misplaced:` — it belongs in a
skill or prompt.
- Repo-wide and path-specific instructions both apply when both match; they do
not override. Priority runs personal → repository → organization.

## Cursor

- `.cursor/rules/*.mdc` with `alwaysApply`, `description`, `globs` selecting
one of four activation modes.
- A `.md` file in `.cursor/rules/` without frontmatter is **ignored silently** —
always a finding, and invisible without checking.
- Cursor's own limit is <500 lines per rule, and its own advice matches the
core method: add a rule only after the agent repeats a mistake.
- `.cursorrules` is legacy. Flag it as `misplaced:` in a new repo, but do not
flag it in a repo that has carried it for years unless something else reads
the content.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Salotech layer checks

**Load only if a marker matches.** Otherwise this file does not apply and its
rules must not appear in the report.

Markers: a git remote under `KosyanMedia` or `aviasales`; or the repo already
carries the `AGENTS.md` + `CLAUDE.md`-symlink pair together with `.claude/`
skills or commands committed alongside it.

**Status: proposed, not ratified.** The layer architecture is an active
initiative under discussion (UP-810 was in Grooming as of 2026-08-18). Report
deviations as `layer:` findings, never as violations, and never let them
outrank a deliberate decision the user states in chat. Their own architecture
requires exactly this: a conflict gets surfaced, the human chooses, and a
choice against the shared rule is treated as a signal the shared rule may be
stale — not as an error.

## The three layers

Every rule belongs to exactly one:

- **Code** — bound to a place in the tree: repository → service → package.
More specific refines less specific; all of them bind.
- **Team** — cross-cutting agreements that travel with the team across every
project: error handling, test style, interface style. This layer is the core
of the initiative and is meant to stay **small**.
- **Personal** — a person's own config, workflow, and skills. Lives in the home
directory, outside the repo, and travels with the person.

`layer:` findings:

- A team-wide agreement sitting in someone's personal config. A personal skill
may *reference* a team rule but must never be its **source** — otherwise the
shared rule is reachable only through one person's setup.
- A package-specific detail hoisted into the repo root, or a repo-wide rule
buried in one package.
- Team or code rules written so they apply outside the org's repositories.
Those layers are scoped to their projects by design.

## Reachability

A rule must reach the agent **explicitly**. Delivering it as a bare link the
agent may never open is disallowed outright.

This narrows, and does not contradict, the core `enforced:` rule. Naming where
enforcement lives (`ruff.toml`, the CI job) is a pointer to machinery. Handing
the agent a URL and hoping it fetches the rule is a delivery failure. Flag the
second; never flag the first.

## Machine-checkable versus judgement

Format and code style go to the linter, hard. Modularity, readability, and
architecture cannot be linted and belong in the rule sets and human review.
This is the same boundary as the core `enforced:` rule, arrived at
independently — treat agreement between them as strong, not as duplication.

## Freshness

The committed rule: **update an app's `AGENTS.md` in the same PR that touches
its code.** That makes `stale:` mechanically checkable — compare `git log` for
the code paths against the instruction file beside them.

Their split, worth preserving in findings: stable content is maintained by hand
in the PR; drifting content (deployment maps, domain→vendor tables, JSON field
shapes) is re-captured periodically by an agent instead.

## Format

`AGENTS.md` is canonical, `CLAUDE.md` is a symlink to it. Decided twice, in the
AI tactics page and in the monolith task. Do not propose the reverse. Where
duplication across harnesses is genuinely needed, it is generated from one
source, never maintained as two hand-edited copies.

## Known internal tension

Two of their own documents disagree about the Confluence copy: the tactics page
wants it generated or reconciled from a single source, while the storage and
contribution page states these are different documents for different readers
that need no mirroring. Report it as `conflict:` when it shows up in a file.
Do not pick a side.

## Per-app core

The reference shape for a per-app file: one-line purpose · directory structure ·
key models and classes · tests and how to run them.

Directory structure here is `unproven:` by the core rules — vendors recommend
it, measurements show no benefit. Report the cost, note that a 37-module
monolith is plausibly the case the studies never covered, and leave the call to
the human. Do not cut it.