Write and audit standing instruction files for agents, such as AGENTS.md style files: decide what belongs in a standing file versus a skill versus a one-task brief, keep the file lean and scoped, write concrete testable rules, set an explicit precedence and conflict rule, and run an audit pass for contradictions, stale rules, duplicate headings, vague phrases, and unbounded absolutes. Use when creating, shrinking, reviewing, or repairing a standing instruction file that an agent reads at the start of work.
name: agent_instruction_files description: "Write and audit standing instruction files for agents, such as AGENTS.md style files: decide what belongs in a standing file versus a skill versus a one-task brief, keep the file lean and scoped, write concrete testable rules, set an explicit precedence and conflict rule, and run an audit pass for contradictions, stale rules, duplicate headings, vague phrases, and unbounded absolutes. Use when creating, shrinking, reviewing, or repairing a standing instruction file that an agent reads at the start of work." metadata: { "includeInPrompt": true }
Agent Instruction Files
Purpose
A standing instruction file is the small set of rules an agent should carry into nearly every task on one project: scope, hard limits, build and test commands, file layout, style rules that apply project wide, and the definition of done. It is read often, so every line costs attention on every run. The work in this skill is placement and discipline. Put each piece of guidance in the one home where it will be found at the right time, write it so compliance can be checked, and audit the file on a schedule so stale and contradictory rules get removed instead of stacked.
Scope:
- skill-authoring covers SKILL.md files for reusable skills, a different file loaded for a matching task. This skill covers the always-on standing file, and the line between the two.
- context-handoffs transfers task context between sessions. This skill writes rules that stay in place across sessions, and carries no single task state.
- session-handoff-docs transfers task context between sessions through handoff documents. This skill produces no handoff document.
- long-task-planning keeps plan files for one task. This skill covers rules that outlive any one task, and sends one-task plans to that home.
- Verification note, 2026-10-22: two live checks were run during drafting. A web search for the AGENTS.md convention returned secondary sources describing AGENTS.md as a cross-tool open convention in plain Markdown, with no required schema, read at the start of a session, holding always-on project context such as build commands and conventions, while skills load on demand for matching tasks. A fetch of agents.md on the same date returned a sample AGENTS.md in plain Markdown with section headings for dev environment tips, testing instructions, and PR instructions, and showed no schema in the fetched text. The checker in the Operating Rules was run on the drafting machine under Python 3.12.3 in self-test mode and against a faulty fixture file on disk, with the exact output printed in that section. What was NOT verified: the full official AGENTS.md specification text, because the fetch returned the sample page content only; any specific tool's file discovery order, nesting, merging, or precedence behavior in a live tool session, so this skill treats those points as project conventions to state explicitly and check in the tool in use, never as settled fact; and any claim about how much any given model weights one section over another.
Workflow
- Inventory what already exists before writing a line.
- Collect the current standing file, any skills the project uses, recent task briefs, and the project README or equivalent orientation doc. Read them in full. Most bloated standing files grew by copying material that already had a home.
- List every rule or fact found, one per line, with its source file. Mark each item as standing rule, procedure, task fact, background, or history. The classification in step 2 works from this list, not from memory.
- Note dead references on sight: commands, paths, tools, or services named in a rule that no longer exist in the project. Step 7 verifies each one, but early notes save a second full read.
- Place each item with the placement test.
- Standing file: the item is true for nearly every task on this project, it is stable over weeks or longer, and an agent that missed it would make a predictable mistake. Build and test commands, hard limits, project wide style, and file layout pass this test.
- Skill: the item is a procedure, rubric, or reference that matters only when a matching task appears. A release checklist, a review rubric, or a framework migration guide belongs in a skill, loaded on demand, even when the procedure is important.
- One-task brief: the item is true for one task only, such as a deadline, a target file list, a one-off exception, or the facts of a single incident. Brief facts expire with the task and must never be promoted to standing rules by habit.
- Project docs: background, rationale, and history go in ordinary project documentation, linked from the standing file in one line. An agent needs the pointer during work, not the full history loaded on every run.
- Cut: an item that fits no home cleanly, duplicates another item, or states a preference with no action attached gets deleted from the draft list. Record cuts in the working notes so a later reader can see the choice was deliberate.
- Lay out a lean, scoped structure.
- Use a short file with clear level 2 sections. A working default set: Scope, Hard Rules, Build and Test, Project Map, Working Conventions, Definition of Done, and Pointers. Rename sections to fit the project, but keep one job per section.
- State scope in the first section in concrete terms: which repository, directory tree, or project the file governs, and where its authority ends. A rule with no stated scope reads as global and collides with rules from other projects.
- Point out instead of copying in. When a procedure lives in a skill or a doc, the standing file carries one line naming it and saying when it applies. Two copies of one rule will drift, and the drift becomes a contradiction in step 7.
- Keep the whole file short enough to read in one pass. When a section grows past roughly sixty lines, that is a signal to move the detail to a skill or a doc and leave a pointer. The checker in the Operating Rules flags sections over that size.
- Order sections by how often they decide behavior: scope and hard rules first, daily commands and conventions next, pointers last. Order is a readability aid only. It confers no precedence unless the precedence section in step 5 says it does.
- Write each rule so compliance can be checked.
- A testable rule names five things where they apply: the action, the condition or trigger, the scope, the exception, and the check. Pattern: "Run the unit test command before a commit in this repository. Exception: documentation-only changes. Check: the commit is preceded by a passing test run."
- Replace vague wording with an observable standard. Weak: "Be careful with generated files." Strong: "Never edit a file under the generated directory in this repository except by running the generator command named in Build and Test."
- One rule per bullet, one action per rule. A bullet that joins two actions with "and" hides the case where one action applies and the other does not. Split it.
- Ban unbounded absolutes in your own drafting. Words such as always and never are allowed only with a scope or an exception on the same line, so a reader can tell where the rule stops.
- Write commands exactly as they are run, with the working directory stated when it matters. A command paraphrased from memory is a stale rule waiting to be found in step 7.
- Mark a new rule as a trial when the evidence behind it is one incident. A trial rule carries a date and a short reason, and step 7 either confirms it into a plain rule or removes it at the next audit.
- Set precedence and conflict handling explicitly.
- File discovery and loading order differ between tools and were not verified for any specific tool in this skill, per the verification note. So the standing file states its own precedence as a project convention, and the team checks that the tool in use loads files the way the convention assumes.
- Write the precedence list in the file, highest first. A common project convention: platform and safety constraints set outside the project, then this standing file, then a skill loaded for the task, then the one-task brief. A project may choose a different order, but it must choose one and write it down.
- Add the same-level conflict rule. A workable default: the more specific rule wins over the more general one, and a dated rule wins over an undated one on the same point. When neither test settles it, the conflict is a defect to fix in the file, not a choice to leave to each run.
- Add the brief exception rule. A one-task brief may narrow a standing rule for that task only when the brief says so in explicit words and names the rule it narrows. Silence in a brief changes nothing, and a brief exception never edits the standing file by implication.
- When two standing rules conflict in practice, stop and surface the conflict with both lines quoted, apply the precedence list if it settles the point, and fix the losing line in the same pass. Leaving both lines in place guarantees the conflict recurs.
- Add exceptions and an escape hatch.
- Every hard rule that can meet a legitimate counter case names its exception in the rule itself or in one exceptions section. An exception names who or what grants it and how long it lasts, in terms a reader can apply without guessing.
- Provide one general escape hatch: when following a rule would cause clear harm to the work, such as data loss or a broken deliverable, the agent pauses that step, states the rule and the harm in plain words, and proceeds only under the precedence rule in step 5. The escape hatch covers a single step, never a whole file section.
- Log each use of an exception or the escape hatch in the working notes for the task. A rule that gets excepted often is a rule that needs rewriting at the next audit.
- Run the audit pass.
- Contradictions: read rule pairs that touch the same action. Two rules that order different behavior under the same condition are a defect, even when each reads well alone. Resolve with step 5 and delete the losing line.
- Stale rules: for every command, path, tool, and service named, check that it still exists and still works as written. Run the command on a safe target where the project allows it, or check the path on disk. A rule that names a dead target gets updated or removed in this pass.
- Unfollowable rules: flag any rule an agent cannot obey as written, for example a rule that requires a permission the agent lacks, a tool the project does not provide, or two steps that must happen in an impossible order. Rewrite it into a followable form or remove it and record why.
- Vague rules: scan for phrases that set no observable standard, such as "be careful", "as appropriate", or "whenever possible". The checker in the Operating Rules carries the starter list. Rewrite each hit into the step 4 pattern or delete the line.
- Duplicates and drift: find repeated headings, repeated rules in different words, and rules copied from a skill or doc that have since diverged. Keep one home per rule, per step 3.
- Absolutes: find every always and never. Keep only the ones carrying a scope or an exception on the same line.
- Size and scope creep: check total length and each section length. Move any block that fails the placement test in step 2 to its proper home and leave a pointer.
- Run the checker script from the Operating Rules as part of this pass. The script catches mechanical faults only. The contradiction, staleness, and followability checks above are reading work and stay manual.
- Test the file with a fresh task before calling it done.
- Pick one ordinary recent task and one task near a hard rule. Walk through each task using only the standing file plus the brief for that task, and note every point where the file gives no answer, a wrong answer, or two answers.
- Fix the file for each gap found, then repeat the walk once. A file that has never been tested against a real task is a draft, whatever its audit result says.
- Where the tooling allows it, start a clean session and confirm the file is actually loaded and read. A correct file that no run loads is a documentation problem, and the fix belongs in the project setup, not in more rules.
- Maintain the file on a cadence.
- Re-run the step 7 audit after any incident caused by a missing or wrong rule, after a tooling or layout change, and at a regular interval the project picks, such as monthly or per release.
- Change one thing at a time where practical, and keep a short dated change note at the end of the file or in version history: what changed, why, and which audit or incident prompted it.
- Delete in the same pass that adds. An audit that only appends rules grows the file until the important rules stop standing out, which is the failure this skill exists to prevent.
Output Contract
Deliver these items, in this order:
- The standing instruction file itself, complete and in its final location, with scope stated in the first section and the precedence list written inside it.
- Placement record: one line per item moved out of the standing file, naming the item, the home it moved to (skill, brief, project doc, or cut), and the reason in a few words.
- Audit record: the checks run in step 7, with counts for contradictions found, stale rules found, vague hits, duplicate headings, and unbounded absolutes, plus the disposition of each finding (fixed, moved, removed, or kept with a stated reason).
- Checker output: the full output of instruction_audit.py for the final file. On the worked self-test in the Operating Rules the faulty fixture reports vague_hits: 5, absolute_hits: 2, duplicate_headings: 1, and verdict: REVIEW, while the good fixture reports zero hits and verdict: PASS.
- Test record: the two tasks used in step 8, the gaps each one exposed, and the fix made for each gap.
- Limits: anything not verified, stated plainly, such as a tool loading behavior assumed but not confirmed in a live session, or a command that could not be run safely during the staleness check.
Operating Rules
- One home per rule. The standing file, a skill, and a doc never carry the same rule in full. Pointers are allowed, copies are defects.
- No rule enters the standing file without passing the placement test in step 2. Importance alone does not qualify a procedure or a task fact for the standing file.
- Every rule is testable as written, per step 4. A rule nobody can check is rewritten or removed during the audit, not left as guidance.
- Precedence lives inside the file. No precedence claim is made from section order, file order, or habit, and no tool loading behavior is asserted without a live check in that tool.
- Deletion is a normal audit outcome. Stale, duplicate, vague, and unfollowable rules are removed or moved in the same pass that finds them, with the change noted.
- The checker below is a mechanical aid only. It flags vague phrases, unbounded absolutes, duplicate level 2 headings, and sections over sixty lines. It does not detect contradictions or staleness, and a PASS from it never substitutes for the reading pass in step 7.
- Use the checker for the mechanical part of every audit. Save it as instruction_audit.py, run it as its header describes, and put its full output in the deliverable as item 4 of the Output Contract.
Instruction audit (instruction_audit.py)
Run: python3 instruction_audit.py --self-test checks the checker against its two built in fixtures and prints the output below. Run it on a real file with python3 instruction_audit.py FILE.md. The script uses only the Python standard library and needs no install step. Exit code is 0 for PASS or a completed self-test, 1 for REVIEW, and 2 for a usage or file error.
Expected output for the self-test run:
text
self-test: good fixture
file: good_fixture
lines_total: 11
headings_level2: 3
vague_hits: 0
absolute_hits: 0
duplicate_headings: 0
long_sections: 0
verdict: PASS
self-test: faulty fixture
file: faulty_fixture
lines_total: 11
headings_level2: 3
VAGUE line=4 phrase="be careful"
VAGUE line=4 phrase="use good judgment"
VAGUE line=4 phrase="as appropriate"
VAGUE line=8 phrase="etc."
VAGUE line=8 phrase="whenever possible"
ABSOLUTE line=5 word="always"
ABSOLUTE line=11 word="never"
DUP line=10 heading="Build" first_line=7
vague_hits: 5
absolute_hits: 2
duplicate_headings: 1
long_sections: 0
verdict: REVIEW
self_test: PASS
The good fixture is a short scoped file whose one absolute carries an exception on the same line, so it passes clean. The faulty fixture packs three vague phrases into one line, adds one vague line with two hits, uses always and never with no scope, and repeats the Build heading, which gives the counts above. The same faulty text saved as a file and run as python3 instruction_audit.py faulty.md gave the same hit lines and counts with the file name in the file line, and exit code 1.
instruction_audit.py (Python standard library only). Save this code as instruction_audit.py:
python
#!/usr/bin/env python3
"""Audit a standing instruction file for common faults.
Usage:
python3 instruction_audit.py FILE.md
python3 instruction_audit.py --self-test
Checks, all with plain text rules and no third party code:
VAGUE line contains a phrase from the vague list below
ABSOLUTE line uses always or never with no scoping word on the
same line (except, unless, when, if, for, in, on, during)
DUP a level 2 heading text repeats an earlier level 2 heading
(compared lowercased, trailing spaces ignored)
LONGSEC a level 2 section runs over 60 lines before the next
level 2 heading or end of file
The verdict is PASS when no check fires, REVIEW otherwise.
Exit code is 0 for PASS or a completed self-test, 1 for REVIEW,
2 for a usage or file error.
"""
import re
import sys
VAGUE_PHRASES = [
"be careful",
"use good judgment",
"use your best judgment",
"as appropriate",
"when appropriate",
"high quality",
"best practices",
"and so on",
"etc.",
"whenever possible",
"in general",
"do your best",
]
SCOPE_WORDS = {"except", "unless", "when", "if", "for", "in", "on", "during"}
ABSOLUTE_RE = re.compile(r"\b(always|never)\b", re.IGNORECASE)
WORD_RE = re.compile(r"[a-z]+")
HEADING2_RE = re.compile(r"^##\s+(.+?)\s*$")
GOOD_FIXTURE = """# AGENTS.md
## Scope
- Applies to this repository only.
## Build
- Run the test command before a commit in this repository.
- Never commit a generated file except a checked in lockfile.
## Style
- Use two space indentation for Python files in this repository.
"""
FAULTY_FIXTURE = """# AGENTS.md
## Scope
- Be careful and use good judgment as appropriate.
- Always format the code nicely.
## Build
- Run tests etc. whenever possible.
## Build
- Never edit generated files.
"""
def audit_lines(lines, label):
vague = []
absolute = []
dups = []
seen = {}
headings = [] # (line_no, title)
for idx, raw in enumerate(lines, start=1):
line = raw.rstrip("\n")
low = line.lower()
for phrase in VAGUE_PHRASES:
if phrase in low:
vague.append((idx, phrase))
m = ABSOLUTE_RE.search(line)
if m:
words = set(WORD_RE.findall(low))
if not (words & SCOPE_WORDS):
absolute.append((idx, m.group(1).lower()))
hm = HEADING2_RE.match(line)
if hm:
title = hm.group(1)
key = title.lower()
headings.append((idx, title))
if key in seen:
dups.append((idx, title, seen[key]))
else:
seen[key] = idx
long_secs = []
for pos, (start, title) in enumerate(headings):
end = headings[pos + 1][0] if pos + 1 < len(headings) else len(lines) + 1
span = end - start
if span > 60:
long_secs.append((start, title, span))
print(f"file: {label}")
print(f"lines_total: {len(lines)}")
print(f"headings_level2: {len(headings)}")
for idx, phrase in vague:
print(f"VAGUE line={idx} phrase=\"{phrase}\"")
for idx, word in absolute:
print(f"ABSOLUTE line={idx} word=\"{word}\"")
for idx, title, first in dups:
print(f"DUP line={idx} heading=\"{title}\" first_line={first}")
for start, title, span in long_secs:
print(f"LONGSEC line={start} heading=\"{title}\" span={span}")
print(f"vague_hits: {len(vague)}")
print(f"absolute_hits: {len(absolute)}")
print(f"duplicate_headings: {len(dups)}")
print(f"long_sections: {len(long_secs)}")
total = len(vague) + len(absolute) + len(dups) + len(long_secs)
verdict = "PASS" if total == 0 else "REVIEW"
print(f"verdict: {verdict}")
return verdict
def main(argv):
if len(argv) == 2 and argv[1] == "--self-test":
print("self-test: good fixture")
good_verdict = audit_lines(GOOD_FIXTURE.splitlines(), "good_fixture")
print("self-test: faulty fixture")
faulty_verdict = audit_lines(FAULTY_FIXTURE.splitlines(), "faulty_fixture")
ok = good_verdict == "PASS" and faulty_verdict == "REVIEW"
print(f"self_test: {'PASS' if ok else 'FAIL'}")
return 0 if ok else 1
if len(argv) == 2:
try:
with open(argv[1], "r", encoding="utf-8") as fh:
lines = fh.read().splitlines()
except OSError as exc:
print(f"error: cannot read {argv[1]}: {exc}")
return 2
verdict = audit_lines(lines, argv[1])
return 0 if verdict == "PASS" else 1
print("usage: instruction_audit.py FILE.md | --self-test")
return 2
if __name__ == "__main__":
raise SystemExit(main(sys.argv))
No ratings yet — be the first to rate it.