Agent Instructions Plugin
The Agent Instructions plugin owns the two pieces of instruction prose that
the prompt-assembly redesign moved off the frozen per-edition system-prompt
templates and onto the first-class context-note channel:
- Operator
custom_instructions— the global directives set viaprompt.custom_instructions, rendered as an<additional-instructions>block. Always injected when set. - Repo-local instruction files —
CLAUDE.md,AGENTS.md,.clinerules,.cursorrules,.cursor/rules,.github/copilot-instructions.md, … discovered from the repositories under analysis and wrapped as an<agent_instructions>block. Opt-in; off by default.
It is a builtin, not a config-listed plugin.
custom_instructionsis a
coreprompt.*config field that is injected unconditionally today; a
config-listed plugin would silently drop it from any deployment that doesn't
list it — exactly whycore_notes/repo_inventoryare builtins. Override
its behaviour with a top-levelagent_instructions:config section, not a
plugins:entry.
Overview
Both blocks ride the shared context-note primitive
(codumentor.agent.context_notes.add_context_note) as prefix notes: they
sit right after the system message, tagged synthetic_note (so
last-user-message consumers like RDC retrieval ignore them), and are deduped
per turn by marker. The handler runs at priority 20 — below core_notes (30)
and log_collection (40) — so the notes sort below the worldview/capability
framing, closest to the user message, preserving the historical order in which
<additional-instructions> followed the general framing in the templates.
custom_instructionsis static for the life of a conversation, so a prefix note is cache-safe.- Repo-local files are static unless edited on disk; the loader caches rendered content by
(path, mtime), so the block stays byte-stable across turns. A mid-session edit costs one prompt-cache miss on the changed turn, then is stable again.
Repo-local discovery (opt-in)
When repo_local_enabled: true, the loader walks the repo roots from
config.repo_context (never threaded path helpers — CLAUDE.md §"Repository
paths") and collects the configured filenames in this order (which is the
injection order, lower authority first):
- global —
~/.codumentor/<file>and<config_file_dir>/<file>(include_global). - project —
<repo_root>/<file>; each name may resolve to a file or a directory of files (e.g..clinerules/or.cursor/rules/, concatenated sorted by name). - nested —
<repo_root>/**/<file>(recursive), bounded bymax_depthandmax_nested_files, skipping.git/node_modules/.venv/… and hidden dirs.
Each file is read UTF-8-safe (errors="replace"), truncated to
per_file_max_bytes (via the shared truncate_output), and skipped if it looks
binary (NUL bytes). A single total_max_bytes ceiling caps the aggregate across
a turn; when exceeded, remaining files are dropped with a visible
[N more instruction files omitted …] notice — never a silent truncation. Each
rendered file carries repo / path / source provenance, and the block opens
with a <note> declaring that repo-provided guidance is subordinate to the
system prompt (the principled answer to conflicting instructions).
@path imports (Claude-Code CLAUDE.md style) are supported behind
resolve_imports (default off): resolution is cycle-safe (visited set),
depth-bounded (max_import_depth), and refuses any target that resolves outside
the repo root (symlink/traversal escape). While resolve_imports is on the
mtime cache is bypassed (an imported file changing does not bump the importer's
mtime).
Configuration
Override under a top-level agent_instructions: section (builtin — do not
add it to plugins:):
agent_instructions:
enabled: true # master switch (custom_instructions + repo-local)
repo_local_enabled: false # scan repos for CLAUDE.md/AGENTS.md/… (default off)
filenames:
- AGENTS.md
- CLAUDE.md
- .clinerules
- .cursorrules
- .cursor/rules
- .github/copilot-instructions.md
include_global: false # also ~/.codumentor/<file> + config_file_dir/<file>
recursive: false # scan <repo>/**/<file>
max_depth: 3
max_nested_files: 20
per_file_max_bytes: 32000
total_max_bytes: 96000
reread: mtime # "mtime" | "always" | "once"
resolve_imports: false # @path includes
max_import_depth: 5
target_agents: all # "main" | "subagent" | "all"
Configuration Parameters
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Master switch. When false the plugin registers no hooks and injects nothing. |
repo_local_enabled | bool | false | Discover and inject repo-local instruction files. custom_instructions is unaffected by this flag. |
filenames | list | see above | File or directory names to look for at each repo root, in injection order (lower authority first). |
include_global | bool | false | Also look in ~/.codumentor/<file> and <config_file_dir>/<file>. |
recursive | bool | false | Scan <repo>/**/<file> for nested instruction files. |
max_depth | int | 3 | Max directory depth for the recursive scan. |
max_nested_files | int | 20 | Max nested files collected per repo. |
per_file_max_bytes | int | 32000 | Per-file truncation budget (UTF-8-safe). |
total_max_bytes | int | 96000 | Hard ceiling across all files per turn; overflow is dropped with a visible notice. |
reread | enum | mtime | mtime (re-read on mtime change), always (every turn), once (cache for the process). |
resolve_imports | bool | false | Resolve @path imports (cycle-/depth-/containment-guarded). |
max_import_depth | int | 5 | Max import recursion depth. |
target_agents | enum | all | Which agents receive the notes: main, subagent, or all. custom_instructions historically reached both, hence the all default. |
Notes & limitations
- Prompt assembly never breaks on this plugin's account — the hook swallows any error and injects nothing on failure.
- If a deployment ships a custom prompt template that still embeds
<additional-instructions>itself,custom_instructionswould appear twice. The stock edition templates no longer do (migration step 6 removed the block from all fourgeneral_instructions.jinja2copies). - Repo-local discovery reads repository content into the prompt, so it is off by default and left to the operator to enable per deployment.