Skip to content

Updated to use @include for the steering rules#1083

Open
Drizzt321 wants to merge 1 commit intodanielmiessler:mainfrom
Drizzt321:feat/claude-md-include-steering
Open

Updated to use @include for the steering rules#1083
Drizzt321 wants to merge 1 commit intodanielmiessler:mainfrom
Drizzt321:feat/claude-md-include-steering

Conversation

@Drizzt321
Copy link
Copy Markdown

In regards to getting PAI to follow the steering rules and other stuff that we've added, discussions like #945 and others exist which all involve trying to rein in our PAI installations where it starts to lose our instructions as sessions go on.

In doing analysis of Claude Code, and with the recent ability to get an insight into it's inner workings, I found something very interesting. The Operator rules in Claude Code explicitly delegate to CLAUDE.md by giving that instruction, tagging the section as claudeMd, and so CLAUDE.md effectively becomes part of the Operator prompt section. This is this:

<system-reminder>
As you answer the user's questions, you can use the following context:
# claudeMd
Codebase and user instructions are shown below. Be sure to adhere to these instructions.
IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.
[CLAUDE.md content — including all @include content — here]
# currentDate
Today's date is YYYY-MM-DD.
</system-reminder>

This causes it to be in a special Memory Files section of the context, which is also automatically reloaded verbatim to the beginning of the context on any compact event.

The existing PAI memory layout comes from SessionStart hook loading, as well as attempts to ensure that they are reloaded via other hooks after a compact event.

CLAUDE.md                                ← operator delegation (Tier 1)
  └── Mode routing, output formats, critical rules, prose refs

LoadContext.hook.ts → loadAtStartup      ← NO delegation (Tier 2)
  ├── PAI/AISTEERINGRULES.md             ← <-- behavioral rules live here
  ├── PAI/USER/AISTEERINGRULES.md        ← <-- behavioral rules live here
  └── PAI/USER/PROJECTS/PROJECTS.md      ← project registry

LoadContext.hook.ts → dynamic block      ← NO delegation (Tier 2, runtime-computed)
  ├── Relationship context
  ├── Learning readback
  └── Active work summary

MEMORY.md                                ← system prompt (capped 200 lines)
  └── Index of memory files (pointers)

On-demand (not auto-loaded)              ← Tier 3
  └── CONTEXT_ROUTING.md, Algorithm, DA identity, individual memories

However, none of these are part of the special Operator (and thus delegated to CLAUDE.md) <system-reminder> section. CLAUDE.md content is different: Claude Code re-injects it via prependUserContext() on every turn as part of the user-context prefetch (context.ts:155, memoized). It survives compaction by design — this is the standard Claude Code expectation for "content the model must always have." The PAI files loaded via the hooks are treated as regular context/conversation history by Claude Code agents.

So CLAUDE.md also has the ability to inline other files, path relative from CLAUDE.md, via @ including them. When I changed to include PAI/AISTEERINGRULES.md and PAI/USER/AISTEERINGRULES.md, I immediately and clearly noticed a HUGE difference, especially in long context sessions. It constantly follows my rules, especially around not jumping ahead and starting to edit/update/change things before we've completed our discussion/determination/etc.

I have a gist at https://gist.github.com/Drizzt321/a4c567f0d263701152bf4e13c17855f1 which also describe this in more detail, as well as instructions to manually modify existing installs, but I wanted to PR this to bring it back in this way since I think it makes a HUGE difference in user experience.

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.

1 participant