Skip to content

feat(skills): durable reflection-run record with activity timeline surface - #641

Draft
jamiepine wants to merge 2 commits into
mainfrom
capy/skill-reflection-run-record
Draft

feat(skills): durable reflection-run record with activity timeline surface#641
jamiepine wants to merge 2 commits into
mainfrom
capy/skill-reflection-run-record

Conversation

@jamiepine

Copy link
Copy Markdown
Member

What

Adds a persisted reflection_runs table and event for the skill-reflection pump, closing the remaining user-visible part of the shipped reflection loop. Every reflection pass now records its lifecycle and surfaces in the portal timeline.

Changes

Database: New reflection_runs migration with agent/channel identity, trigger source (turn_work / worker_success / reflection), referenced worker IDs (JSON), start/end timestamps, terminal status (success / no_op / error / cancelled), declared rationale (separate from observed actions), outcome summary, affected skill identifiers, and token usage slot.

Event: ProcessEvent::ReflectionRunCompleted on the shared event bus — same pattern as BranchResult, WorkerComplete, etc. — piped through the existing ApiEvent SSE pipeline. ApiEvent::ReflectionRunCompleted with the reflection_run_completed SSE event type.

Persistence: ReflectionRunLogger in conversation/history.rs, fire-and-forget matching ProcessRunLogger. Write-on-start (INSERT), guarded completion update (UPDATE … WHERE status = 'running'), preventing duplicate completions.

UI: InlineReflectionRunCard in PortalTimeline.tsx — a quiet divider bar showing "Learned: …" / "No change: …" / "Error: …" — same inline pattern as chronicle checkpoints, no parallel event system.

Validation

  • cargo fmt --check — clean
  • cargo check — clean
  • cargo test --lib — 594 passed, 0 failed
  • cargo test --test '*' — 117 passed, 0 failed
  • 12 new unit tests covering: no-op detection, error detection, success with skill extraction, duplicate avoidance, keyword exclusion, default signal state
  • bun run build — clean
  • just preflight — passed
  • just gate-pr — all gates green (fmt, check, migration conflicts, lib tests, integration tests)

Intentional deferments (documented in skill-lifecycle.md)

  • Curation (Phase 4): deterministic stale/archive pass, LLM consolidation, snapshots + rollback
  • Full surfaces (Phase 5): POST /agents/skills/write, CreateSkill.tsx, full SkillInspector usage row, write_approval staging mode
  • CLI: pin/adopt/archive/restore commands
  • Token usage: slot exists on the row but is not populated yet (requires branch-level token accounting)
  • Observed actions: slot exists but is populated with empty array — tool-call-level observability for reflection branches is future work

Design invariants preserved

  • Reflection remains silent in conversation (timeline-only)
  • Agent-origin skill mutation rails unchanged (WriteOrigin::Agent, read-before-write, archive-on-delete)
  • Cron conversations never reflect (ChannelKind::suppresses_reflection)
  • No tool authority expansion
  • No hidden chain-of-thought stored
  • Duplicate completions guarded by WHERE status = 'running'

…rface

Add a persisted reflection_run lifecycle table and event for the
skill-reflection pump. Every reflection pass (riding the memory-
persistence branch) now records agent/channel identity, trigger
provenance, referenced worker IDs, start/end timestamps, terminal
status (success/no_op/error), declared rationale distinct from
observed actions, outcome summary, and affected skill identifiers.

ReflectionRunCompleted flows through the shared ProcessEvent bus,
the existing ApiEvent SSE pipeline, and renders as an inline card
in the portal timeline — same pattern as chronicle checkpoints,
no parallel event system.

Deferred curation (snapshots, stale/archive passes, consolidation)
and full SkillInspector surface remain for follow-up PRs as
documented in the updated skill-lifecycle.md shipped-status section.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 253afe2d-ddbb-4d9c-ac37-978245294155

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

The reflection_run timeline type is client-only (not in the OpenAPI
TimelineItem union). Use double-cast through unknown for pushItem and
Record<string,unknown> for the type discriminator in PortalTimeline,
matching the existing pattern used by checkpoint rendering.
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