Skip to content

Skill lifecycle phase 3: reflection rides the persistence branch - #624

Merged
jamiepine merged 3 commits into
mainfrom
jamiepine/skill-reflection
Aug 9, 2026
Merged

Skill lifecycle phase 3: reflection rides the persistence branch#624
jamiepine merged 3 commits into
mainfrom
jamiepine/skill-reflection

Conversation

@jamiepine

@jamiepine jamiepine commented Aug 9, 2026

Copy link
Copy Markdown
Member

Re-lands #623. It was stacked on the phase 2 branch and got merged into that branch just after #622 had already landed on main — so the reflection commit never reached main. Same diff, reviewed there; branch is based on exactly the tree #622 merged.

Original description and discussion: #623

Phase 3 of docs/design-docs/skill-lifecycle.md — the outcome-to-skill
pump. One deliberate divergence from the doc: no separate reflection
branch. The persistence branch is already the silent replay-fork this
needs, so reflection rides it as a single unified pass (the shape the
Hermes reference implementation runs in production).

- Channel accumulates a reflection signal: a turn crossing
  min_tool_iterations tool calls, or a worker completing successfully.
  Cron conversations never reflect.
- When the signal is set and the per-conversation cooldown allows, the
  next persistence branch spawns with skill_reflection: its prompt gains
  the reflection section and its toolset gains read_skill/skill_manage/
  skills_list under WriteOrigin::Agent, so every phase-2 rail applies.
  The signal alone can spawn the pass; passes without it are unchanged.
- Reflection prompt section: decide-first (no writes is the common
  case), the patch-over-create preference ladder, and the negative-
  capture bans (no environment flukes, no negative tool claims, no
  transient errors, no one-off narratives).
- [skills.reflection] config: enabled / min_tool_iterations (10) /
  cooldown_secs (3600), defaults + per-agent override, hot-reloadable.
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 987058d4-b6c4-4d70-8824-2723aefc8eee

📥 Commits

Reviewing files that changed from the base of the PR and between 79a4b48 and 31365da.

📒 Files selected for processing (2)
  • prompts/en/memory_persistence.md.j2
  • src/agent/channel.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • prompts/en/memory_persistence.md.j2
  • src/agent/channel.rs

Walkthrough

The change adds configurable skill reflection settings, tracks reflection eligibility during channel activity, and lets memory persistence branches update skills with conditional prompts and tool access.

Changes

Skill reflection persistence

Layer / File(s) Summary
Reflection configuration and runtime resolution
src/config/..., src/api/agents.rs
TOML schemas and resolved configurations now support reflection enablement, tool-iteration thresholds, cooldowns, defaults, agent overrides, and runtime reloads.
Reflection signals and persistence scheduling
src/agent/channel.rs, src/agent/channel_history.rs
Tool-call thresholds and successful worker completions set reflection signals. Cooldowns, cron exclusions, trigger types, state resets, and tool-call counting govern persistence.
Reflection prompt and branch skill tooling
prompts/en/memory_persistence.md.j2, src/prompts/engine.rs, src/agent/channel_dispatch.rs, src/tools.rs, src/agent/ingestion.rs
Reflection branches render conditional guidance, propagate the reflection flag, and receive skill tools with the configured write origin. Tests cover prompt modes and configuration merging.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the skill lifecycle reflection change and its integration with the persistence branch.
Description check ✅ Passed The description explains that the pull request re-lands the reflection changes and gives relevant branch and merge context.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jamiepine/skill-reflection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/agent/channel.rs (1)

3829-3855: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Retain the reflection request when branch creation fails.

Lines 3832-3835 start the cooldown and clear the signal before spawn_memory_persistence_branch succeeds. If spawning fails, no reflection branch runs, but the next check is suppressed by the cleared signal and cooldown.

Restore the prior reflection state on the error path, or commit the signal reset and cooldown only after the branch is created.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/agent/channel.rs` around lines 3829 - 3855, Retain the pending reflection
request when spawn_memory_persistence_branch fails. Move the reflection cooldown
and reflection_signal reset from before the spawn into the successful
Ok(branch_id) path, or restore both prior values in the Err(error) path, while
preserving the existing branch insertion and logging behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@prompts/en/memory_persistence.md.j2`:
- Around line 81-84: Provide a supported reference-file write path for the
reflection persistence flow: in prompts/en/memory_persistence.md.j2 lines 81-84,
replace write_file with an implemented skill-management operation if one
supports writing references; otherwise, update src/tools.rs lines 912-939 to
register a constrained reference-file write capability only for
reflection-enabled persistence branches while preserving agent-origin
restrictions.

In `@src/agent/channel.rs`:
- Around line 2934-2956: Move tool-call counting in the turn-history block to
occur before apply_history_after_turn mutates or sanitizes guard, using the
net-new source history including PromptCancelled.chat_history. Keep
apply_history_after_turn responsible for applying sanitized history, then use
the pre-sanitization count for the reflection.min_tool_iterations check and
mark_reflection_signal.
- Around line 3422-3430: Update the successful worker-completion branch in the
surrounding channel handler so that, after
mark_reflection_signal("worker_completed") sets the reflection signal, it
schedules check_memory_persistence. Preserve the existing reflection.enabled
guard and normal persistence controls while ensuring persistence is checked even
when no later user message occurs.
- Around line 3773-3780: Update the early-return condition in the
reflection/persistence flow to return whenever persistence_enabled is false,
regardless of reflection_due. Only allow reflection_due to trigger processing
after the existing memory-persistence controls pass, preserving the behavior of
self.reflection_due() for enabled persistence.

---

Outside diff comments:
In `@src/agent/channel.rs`:
- Around line 3829-3855: Retain the pending reflection request when
spawn_memory_persistence_branch fails. Move the reflection cooldown and
reflection_signal reset from before the spawn into the successful Ok(branch_id)
path, or restore both prior values in the Err(error) path, while preserving the
existing branch insertion and logging behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4350e341-4b98-40d7-8090-bf9759c06550

📥 Commits

Reviewing files that changed from the base of the PR and between 648a380 and 44edee9.

📒 Files selected for processing (12)
  • prompts/en/memory_persistence.md.j2
  • src/agent/channel.rs
  • src/agent/channel_dispatch.rs
  • src/agent/channel_history.rs
  • src/agent/ingestion.rs
  • src/api/agents.rs
  • src/config/load.rs
  • src/config/runtime.rs
  • src/config/toml_schema.rs
  • src/config/types.rs
  • src/prompts/engine.rs
  • src/tools.rs

Comment thread prompts/en/memory_persistence.md.j2
Comment thread src/agent/channel.rs Outdated
Comment thread src/agent/channel.rs
Comment thread src/agent/channel.rs
Comment thread src/agent/channel.rs Outdated
self.message_count = 0;
self.last_persistence_at = std::time::Instant::now();
if reflection_due {
self.last_reflection_at = Some(std::time::Instant::now());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This consumes the reflection signal and starts the cooldown before the branch actually spawns. If spawn_memory_persistence_branch fails, reflection is lost for the full cooldown without ever running. Consider moving the cooldown update and reflection_signal.store(false, ...) into the Ok arm.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 31365da — the cooldown start and signal clear moved into the Ok arm; a failed spawn leaves the signal set so the next check retries. (Same fix covers the outside-diff comment on lines 3829-3855.)

jamiepine and others added 2 commits August 8, 2026 22:37
- tool iterations counted from the pre-sanitization turn history;
  PromptCancelled/MaxTurnsError use the chat_history carried in the
  error, so reply-tool turns no longer report zero tool calls
- successful worker completion schedules a persistence check instead of
  leaving the reflection signal pending until the next user message
- reflection rides the persistence pass and now obeys the same write
  controls: no reflection-only branch when persistence is disabled,
  interval is zero, or the conversation memory mode isn't Full
- reflection signal and cooldown are consumed in the spawn Ok arm, so a
  failed spawn retries instead of losing the reflection for a cooldown
- persistence prompt names skill_manage's write_file action rather than
  a bare write_file tool
@jamiepine
jamiepine merged commit 9151bf3 into main Aug 9, 2026
4 checks passed
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