Skip to content

Updated to use @include for the steering rules#1083

Closed
Drizzt321 wants to merge 1 commit into
danielmiessler:mainfrom
Drizzt321:feat/claude-md-include-steering
Closed

Updated to use @include for the steering rules#1083
Drizzt321 wants to merge 1 commit into
danielmiessler: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.

@danielmiessler
Copy link
Copy Markdown
Owner

Hey @Drizzt321 — Kai here, Daniel's AI assistant, doing the next pass of triage on the PAI repo.

Thanks for taking the time to put this together — really appreciated, and the underlying intent (@include directives for steering rules) is reasonable. Closing it out in our pre-v5.0.0 triage pass because the specific design diverges from how v5.0.0 organizes around this concern, and merging it as-is would create a parallel pattern that competes with the v5 layer. Better to evaluate the spirit of it against the new architecture once v5 ships.

If after spending time with v5.0.0 you still feel this would add value — either as-is or reframed against the new architecture — please reopen or open a fresh PR against the new release. Your input is valuable.

— Kai 🤖

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