Skip to content

feat: soul.md + user.md persona injection#75

Merged
royosherove merged 1 commit into
mainfrom
feat/persona-files
May 9, 2026
Merged

feat: soul.md + user.md persona injection#75
royosherove merged 1 commit into
mainfrom
feat/persona-files

Conversation

@royosherove
Copy link
Copy Markdown
Member

Adds personality and user context files that shape agent behavior.

  • ~/.roundhouse/soul.md — agent identity (name: Loki, direct/technical vibe)
  • ~/.roundhouse/user.md — learns about the human over time
  • Injected as <persona> block on every turn (before tools)
  • No caching — edits take effect immediately
  • Provisioned on install/update (never overwrites user edits)
  • 393 tests green

- Bundled defaults provisioned to ~/.roundhouse/ on install/update
- Never overwrite user's customized versions
- Injected as <persona> section in every prompt (before tools)
- No caching: files re-read each turn (agent updates user.md over time)
- soul.md: agent identity, personality, boundaries
- user.md: info about the human (filled in over time)
- Same pattern as OpenClaw SOUL.md/USER.md
- 393 tests green
@royosherove royosherove merged commit 1a07f44 into main May 9, 2026
1 check passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b513da6629

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (user) parts.push(user);
const persona = parts.join("\n\n---\n\n");

return `<persona>\n${persona}\n</persona>\n\n${text}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Escape persona content before closing the persona block

injectPersonaSection inserts raw soul.md/user.md text inside <persona>...</persona> without escaping, so any literal </persona> in those files will terminate the wrapper early and leak subsequent content into the main prompt. Because this feature is intended to evolve user.md from conversation data, a crafted note can create persistent prompt-injection behavior across turns; this should be sanitized the same way tools-inject.ts sanitizes <tools> tags.

Useful? React with 👍 / 👎.

*/
export function injectPersonaSection(text: string): string {
const soul = loadFile("soul.md").trim();
const user = loadFile("user.md").trim();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope learned user persona per conversation identity

This always loads a single global user.md file and injects it into every turn, which means notes learned from one person are automatically shown to all chats/users handled by this gateway. In environments with multiple allowedUsers or shared bots, that causes cross-user context bleed and privacy leakage; persona state should be keyed per user/chat (or disabled when multiple users are configured).

Useful? React with 👍 / 👎.

royosherove added a commit that referenced this pull request May 10, 2026
1. Escape </persona> in persona content (XML injection prevention)
2. mtime check uses !== instead of > (catches deletions/replacements)
3. mkdirSync before writeSettings (handles fresh installs)
4. /later@BotName suffix stripped in group chats

All from Codex PR review comments on #75, #77, #66, #67.
393 tests green.

Co-authored-by: Loki FastStart <loki@faststart.internal>
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