Metadata-Version: 2.5
Name: rulereach-delegate
Version: 0.1.1
Summary: Audit what reaches a Claude Code subagent: instructions, skills and tools that delegation drops without an error.
Project-URL: Homepage, https://github.com/Topicspot/rulereach-delegate
Project-URL: Repository, https://github.com/Topicspot/rulereach-delegate
Project-URL: Issues, https://github.com/Topicspot/rulereach-delegate/issues
Project-URL: Changelog, https://github.com/Topicspot/rulereach-delegate/blob/main/CHANGELOG.md
Author: Topicspot
License: MIT
License-File: LICENSE
Keywords: agent-skills,claude-code,developer-tools,lint,subagents
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6.0
Requires-Dist: tomli>=2.0.1; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: mypy==2.3.0; extra == 'dev'
Requires-Dist: pillow>=11; extra == 'dev'
Requires-Dist: pip-audit>=2.7; extra == 'dev'
Requires-Dist: pytest>=9.0; extra == 'dev'
Requires-Dist: ruff==0.16.0; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Requires-Dist: vulture>=2.16; extra == 'dev'
Description-Content-Type: text/markdown

# rulereach-delegate

**English** · [Русский](docs/README.ru.md) · [简体中文](docs/README.zh-CN.md) · [Español](docs/README.es.md) · [Português](docs/README.pt-BR.md)

[![PyPI](https://img.shields.io/pypi/v/rulereach-delegate?style=flat-square&label=pypi&color=3775A9)](https://pypi.org/project/rulereach-delegate/)
[![Python](https://img.shields.io/pypi/pyversions/rulereach-delegate?style=flat-square&color=4B8BBE)](https://pypi.org/project/rulereach-delegate/)
[![CI](https://github.com/Topicspot/rulereach-delegate/actions/workflows/ci.yml/badge.svg)](https://github.com/Topicspot/rulereach-delegate/actions/workflows/ci.yml)
[![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](https://github.com/Topicspot/rulereach-delegate/blob/main/LICENSE)

A subagent definition is a promise about a fresh context window: this prompt, these tools,
these skills. Claude Code keeps part of that promise and quietly rewrites the rest. A
background subagent, which is the default, keeps only a fixed list of built-in tools, so
`BashOutput` in your `tools` list is dropped with no error. A `tools` list that survives
none of the filters makes the agent fail to launch. A skill named in the prompt but missing
from the `skills` field is not in the context at startup. A skill that forks into `Explore`
sees no `CLAUDE.md` at all. An `agent:` that does not resolve falls back to a general-purpose
agent with a wider tool pool than the one you asked for.

`rulereach-delegate` reads `.claude/agents/`, plugin `agents/` directories and every
`SKILL.md` in a repository, applies the documented startup and tool-filter rules, and reports
what delegation drops. It runs offline and cites the documentation page behind every finding.

![rulereach-delegate demo](https://raw.githubusercontent.com/Topicspot/rulereach-delegate/main/assets/demo.gif)

```console
$ rulereach-delegate check
.claude/agents/narrowed.md
  x skill-unreachable the prompt mentions the 'deep-research' skill, but it is not preloaded and the agent has no Skill tool
      fix: add deep-research to the skills field, or add Skill to tools
      docs: https://code.claude.com/docs/en/sub-agents#preload-skills-into-subagents
  ! tools-background-removed BashOutput is dropped for a background subagent, which is the default, and the removal reports no error
      fix: keep the agent in the foreground for this work, or drop the tool from the list so the definition says what the agent really gets
      docs: https://code.claude.com/docs/en/sub-agents#available-tools
.claude/agents/zero-tools.md
  x tools-zero no entry in tools survives the documented filters, so the agent fails to launch
      fix: list tools the agent can actually keep, such as Artifact, Bash, Edit, EnterWorktree
      docs: https://code.claude.com/docs/en/errors#agent-would-be-spawned-with-zero-tools
.claude/skills/deep-research/SKILL.md
  ! fork-skips-memory agent: Explore skips the CLAUDE.md hierarchy, so 4 instruction line(s) in it, 3 of them prohibitions, do not reach this fork
      fix: restate the rules this task depends on inside the skill, or fork into an agent that loads CLAUDE.md
      docs: https://code.claude.com/docs/en/sub-agents#what-loads-at-startup

rulereach-delegate: 5 error(s), 5 warning(s), 2 note(s)
```

## Install

```bash
pipx install rulereach-delegate     # or: uv tool install rulereach-delegate
```

Nothing is sent anywhere: the tool reads files and exits. No API keys, no network calls.

## Use

```bash
rulereach-delegate check                  # report what delegation loses, exit 1 on errors
rulereach-delegate check --strict         # exit 1 on warnings and notes too
rulereach-delegate check --check tools-zero          # one check at a time
rulereach-delegate check --exclude "tests/fixtures/**"
rulereach-delegate list                   # every subagent and forking skill
rulereach-delegate explain code-reviewer  # what that agent starts with
```

`explain` is the answer to "why did the subagent ignore that":

```console
$ rulereach-delegate explain deep-research
deep-research (.claude/skills/deep-research/SKILL.md, forking skill)

Reaches it at startup:
  - its own system prompt: the skill content, injected as the task

Does not reach it:
  - the CLAUDE.md hierarchy: 4 instruction line(s), 3 of them prohibitions, and the git status snapshot
  - the parent conversation history and the files already read
  - skills invoked in the parent session, unless named in the skills field
  - the output style and the parent's auto memory

Tools: inherits every tool available to subagents.
Runs in the background (the default); a background subagent keeps only a fixed set of built-in tools, 19 of them, plus every MCP tool.
```

Add `--json` to any command for machine-readable output.

## Checks

| ID | What it catches |
| --- | --- |
| `not-loaded` | agent file Claude Code skips: unparsable frontmatter, no `name`, a `name` with a colon or leading hyphen, or a `name` with no `description` |
| `unknown-field` | frontmatter key that is not a subagent field, such as a skill's `allowed-tools`, so it is ignored |
| `tools-removed` | tool removed from every subagent even when listed, such as `AskUserQuestion` or `ExitPlanMode` outside plan mode |
| `tools-background-removed` | built-in tool a background subagent does not keep, dropped without an error |
| `tools-zero` | no entry in `tools` survives the filters, so the agent fails to launch |
| `tools-denied-conflict` | tool in both `tools` and `disallowedTools`, so it is denied |
| `skill-missing` | `skills` names a skill that is not in the repository |
| `skill-not-preloadable` | `skills` names a skill with `disable-model-invocation: true`, which cannot be preloaded |
| `skill-unreachable` | prompt names a skill that is neither preloaded nor reachable, because the agent has no `Skill` tool |
| `skill-not-preloaded` | prompt names a skill the agent must discover itself instead of starting with its content |
| `fork-agent-unresolved` | `agent:` in a forking skill that resolves to nothing, so the fork runs general-purpose with a wider tool pool |
| `fork-skips-memory` | fork into `Explore` or `Plan`, which skip the `CLAUDE.md` hierarchy and git status |
| `fork-background-tools` | tool pre-approved in `allowed-tools` that a background fork does not have |
| `model-unknown` | `model` that is neither an alias nor a full model ID |

Severity is about consequence, not style. An error means the definition cannot do what it
says: the agent does not load, does not launch, or loses a capability it names. A warning
means it silently gets less than the file promises. A note is behaviour worth knowing that is
not a mistake.

The documented sentences each check is built on are collected in
[docs/semantics.md](docs/semantics.md), with the date they were read.

## Scope

Claude Code only, and only what a repository can carry: `.claude/agents/`, plugin `agents/`
directories, `.claude/skills/*/SKILL.md`, the `CLAUDE.md` hierarchy with its imports, and
`.claude/rules/`. Subagents installed at user scope in `~/.claude/agents/` are outside a
repository, so they are outside a repository check. Runtime behaviour is out of scope too:
this is a static audit of definitions, not a transcript analyser.

## Configuration

Optional. Put the flags you would otherwise repeat into `pyproject.toml`:

```toml
[tool.rulereach-delegate]
exclude = ["tests/fixtures/**"]
strict = false
```

Projects without a `pyproject.toml` can use a `.rulereach-delegate.toml` with the same keys at
the top level. If both exist, `.rulereach-delegate.toml` wins, and command line flags win over
both. An unreadable file, an unknown key or a value of the wrong type is reported on stderr
rather than ignored.

## In CI

```yaml
- name: rulereach-delegate
  run: uvx rulereach-delegate check
```

`check` exits 1 when there is at least one error, 0 otherwise. Use `--strict` to fail on
warnings as well.

## Alternatives

- [skilldoctor](https://github.com/studiomeyer-io/skilldoctor), [skillcheck](https://github.com/erphq/skillcheck),
  [claudelint](https://github.com/pdugan20/claudelint) and
  [claude-plugins-validation](https://github.com/Emasoft/claude-plugins-validation) validate
  the shape of skill, `CLAUDE.md` and subagent files: frontmatter schema, referenced paths,
  security patterns. Some of them check a subagent's frontmatter fields as well. They stop at
  the file; this tool continues into what the runtime does to it, which is where the tool
  filters and the startup composition live.
- [rule-trace](https://github.com/seanleecoder/rule-trace) answers the same question at
  runtime: it asks the agent to disclose which rules it applied, and counts those disclosures
  over time. That needs your rules migrated into its format and a hook wired up. This tool is
  static and needs nothing but the repository.
- `claude plugin validate` finds agent files whose frontmatter does not parse. It does not
  flag a file that parses but has no `name`, and it does not model the tool filters.

## Related

- [rulereach](https://github.com/Topicspot/rulereach) - whether an instruction file reaches
  the main agent at all: Codex, Claude Code, Cursor, Copilot.
- [skillfrisk](https://github.com/Topicspot/skillfrisk) - scan agent skills and MCP servers
  for prompt injection and unsafe instructions.
- [ciparity](https://github.com/Topicspot/ciparity) - find drift between pre-commit hooks
  and your CI pipeline.

## License

MIT
