Skip to content

feat: tell agents to write in Simple English, with hooks - #833

Draft
nieblara wants to merge 5 commits into
mainfrom
cursor/simple-english-agent-guidance-e375
Draft

nieblara wants to merge 5 commits into
mainfrom
cursor/simple-english-agent-guidance-e375

Conversation

@nieblara

Copy link
Copy Markdown
Contributor

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

None. The rules come from the Simple English skill, which uses the MIT license.

Describe the solution you've provided

Summary

This PR tells AI agents to write in Simple English in this repository. Simple English is plain English that follows the rules of ASD-STE100 Simplified Technical English. The rules give short sentences, active voice, one word for one meaning, and no filler words.

The PR has three parts:

  1. A copy of the Simple English skill in .agents/skills/simple-english/
  2. A new section in AGENTS.md that tells agents to use the skill
  3. Hooks for Cursor, Claude Code, and Codex that load the rules and lint Markdown files

The guidance

The new "Writing Style: Simple English" section in AGENTS.md applies to replies, Markdown files, pull request descriptions, commit messages, and new code comments. It lists the rules that agents break most often. It also tells agents not to change code, generated files, or text that their task does not touch. CLAUDE.md is a link to AGENTS.md, so Claude Code gets the same section.

The hooks

A hook is a command that an agent tool runs at a fixed point, for example at the start of a session. All the hooks run one script, .agents/skills/simple-english/scripts/hook.py. The hooks are advisory, so they never block an action.

Tool Configuration What the hooks do
Cursor .cursor/hooks.json Load the rules at session start. Lint each Markdown file after a write.
Claude Code .claude/settings.json Load the rules at session start. Lint each Markdown file after a write. Report bold text, headers, lists, and em dashes in each reply.
Codex .codex/hooks.json Load the rules at session start.

The lint reports only the lines that differ from the last commit. For example, README.md has 20 old violations today. If an agent adds one bad line, the hook reports that line only. A new file gets a full lint.

Cursor also runs the hooks in .claude/settings.json. For this case, the script finds the Cursor input and runs only the Cursor hooks. Cursor Cloud Agents do not run session start hooks, so they get the rules from AGENTS.md.

To turn off the hooks, set SIMPLE_ENGLISH_HOOKS=off.

A fix in the linter

The skill includes a linter, scripts/ste_lint.py. In the upstream version, each line number after a code block or a table is too small. In this repository, the upstream linter put 34 hits on the wrong line, in 26 of the 33 Markdown files. The copy in this PR keeps the newlines, so all hits go to the correct line. The violation counts do not change. UPSTREAM.md records this change and the steps to update the copy.

Tests

scripts/test_hook.py has 15 tests. The tests cover these areas:

  • The output format for each tool
  • The Claude Code hooks that Cursor runs
  • The lint of changed lines only, with code blocks and tables before the changed line
  • The files that the lint skips, such as CHANGELOG.md
  • The reply report for Claude Code
  • Input that is not valid JSON

To run the tests, run python3 .agents/skills/simple-english/scripts/test_hook.py. I also ran the hook on real files in this repository. I did not run the hooks in a live Cursor, Claude Code, or Codex session, because this environment has no credentials for those tools.

Describe alternatives you've considered

We did not use the upstream hook scripts. The upstream scripts need the layout of a Claude Code or Codex plugin, and they do not support Cursor.

We did not add a Cursor stop hook for the reply report. A Cursor stop hook can only start a new agent turn, and that can cause a loop.

We did not lint the full file after each edit. The full lint told agents to correct old text that their task did not touch.

Additional context

The hooks need python3. Codex runs project hooks only in a trusted project, and Codex asks you to approve each hook. Open /hooks in Codex to approve it.

Open in Web Open in Cursor 

cursoragent and others added 5 commits September 29, 2026 21:32
Copy the Simple English skill into .agents/skills/simple-english. Cursor
and Codex load project skills from .agents/skills. The files come from
commit 79b590fc8596523d92c26b1ea7e33236606ef069 with no changes. The
project uses the MIT license, and LICENSE holds the license text.

Co-authored-by: Ramon Niebla <nieblara@users.noreply.github.com>
The upstream strip_code function replaced each code block and some table
rows with one space. It removed their newlines, so each line number after
a code block or a table was too small. In this repository, 34 hits went to
the wrong line.

strip_code now keeps the newlines that it removes. The violation counts do
not change.

Co-authored-by: Ramon Niebla <nieblara@users.noreply.github.com>
Add hooks that load the Simple English rules at session start and lint
the Markdown files that an agent writes. The hooks are advisory, so they
never block an action.

One script, scripts/hook.py, serves the three tools. The lint reports only
the lines that differ from the last commit, so an agent does not rewrite
old text. Cursor also runs the hooks in .claude/settings.json. The script
finds this case and runs only the Cursor hooks.

Co-authored-by: Ramon Niebla <nieblara@users.noreply.github.com>
Add a Writing Style section to AGENTS.md. CLAUDE.md is a link to this file.
The section gives the rules that agents break most often, the text that the
rules cover, and the hooks for each tool.

Co-authored-by: Ramon Niebla <nieblara@users.noreply.github.com>
The upstream file ends with a blank line. The end-of-file-fixer pre-commit
hook requires one newline at the end of each file, so the build failed.
UPSTREAM.md now records this change.

Co-authored-by: Ramon Niebla <nieblara@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants