Skip to content

fix(playbook): reconstruct full provenance for manual review - #397

Merged
yyiilluu merged 3 commits into
mainfrom
codex/review-recent-user-playbooks-org48
Jul 30, 2026
Merged

fix(playbook): reconstruct full provenance for manual review#397
yyiilluu merged 3 commits into
mainfrom
codex/review-recent-user-playbooks-org48

Conversation

@yyiilluu

@yyiilluu yyiilluu commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Make manual historical playbook review reconstruct the exact finalized extraction window instead of applying the current last-k window and source filter.
  • Keep candidate evidence restricted to persisted cited interaction IDs while using the rest of the generation window only as chronology.
  • Preserve batch progress by skipping only an unreconstructable playbook and continuing with later rows.
  • Leave the active reviewer prompt unchanged from main; this PR is limited to provenance and evidence plumbing.

Changes

Historical provenance

  • Add backend-neutral and SQLite lookup support for the latest finalized playbook extraction run associated with a request.
  • Rebuild request-grouped review context from the run interaction IDs plus consolidation-retained cited IDs.
  • Preserve the original extraction request on reviewer-created successors so later manual reviews retain provenance.

Evidence and resilience

  • Rebuild cited evidence spans from exact stored interaction IDs, without requiring every span to remain duplicated in a consolidated source span.
  • Introduce a specific evidence reconstruction error and convert it into a per-playbook skip rather than a batch failure.
  • Extend the synchronous timeout for report-only review runs.

Verification and docs

  • Cover full-window reconstruction across sources, consolidation citations, missing and cross-user provenance, truncated historical source spans, automatic-review invariants, storage lookup wiring, timeout behavior, and batch continuation.
  • Update client and service documentation for manual versus automatic review semantics.

Follow-ups

  • Match report-only Python client requests to the server's 600-second synchronous limit while preserving longer caller-configured timeouts.
  • Add direct coverage for newest-run selection, FINALIZED_PENDING_TOOL, deterministic timestamp ties, and report-only storage immutability via a full SQLite dump digest.
  • This OSS PR should merge before downstream repositories update their submodule pins.

Test Plan

  • Affected prompt, playbook, storage, middleware, and enterprise wiring suites: 158 passed, 4 skipped.
  • Follow-up OSS regression selection: 38 passed.
  • Ruff and Pyright on the follow-up files: passed with 0 type errors.
  • Programmatically loaded the active reviewer prompt, confirmed version 1.0.0, and verified its file is identical to main.
  • Pre-commit hooks on all changed OSS files: passed.
  • Report-only org48 provenance replay: all 10 selected playbooks were reconstructable with 0 skips, including historical playbook 1203; before and after storage digests matched.

Summary by CodeRabbit

  • Bug Fixes

    • Improved manual playbook reviews by reconstructing evidence from the correct finalized context.
    • Rows with missing, invalid, or unverifiable evidence are now skipped safely without stopping other reviews.
    • Playbook review requests now receive the appropriate longer timeout.
    • Revised playbooks preserve their original request association.
  • Documentation

    • Clarified review selection, evidence handling, provenance requirements, and skip decisions.
  • Tests

    • Added coverage for evidence reconstruction, missing provenance, cross-user data, review continuation, and request timeout behavior.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Persisted playbook reviews now reconstruct finalized generation windows from stored provenance, rebuild cited evidence from exact interaction IDs, skip unreconstructable rows, preserve successor request lineage, and use synchronous timeouts for the review endpoint.

Changes

Persisted playbook review hardening

Layer / File(s) Summary
Finalized run provenance lookup
reflexio/server/services/storage/.../agent_run/_agent_run_store.py, tests/server/services/storage/.../test_agent_run_storage.py
The agent-run contract and SQLite implementation add a latest-finalized-run lookup filtered by organization, extractor, user, and request, with recency ordering and coverage for matching and non-matching bindings.
Persisted review-window reconstruction
reflexio/server/services/playbook/review_service.py, tests/server/services/playbook/test_playbook_review_service_integration.py, tests/server/services/playbook/test_playbook_generation_service.py
Manual review reconstructs validated chronological windows from finalized run provenance, stored interactions, and requests; missing, invalid, or cross-user records are skipped, and edit successors retain the original request ID.
Cited evidence reconstruction and review policy
reflexio/server/services/playbook/components/reviewer.py, reflexio/server/services/playbook/README.md, reflexio/client/client.py, reflexio/models/api_schema/domain/entities.py, tests/server/services/playbook/test_playbook_reviewer.py
Reviewer evidence is rebuilt strictly from cited interaction IDs, with unmappable or empty evidence producing a dedicated error that becomes a skipped review result. Documentation, client guidance, result semantics, and prompt tests reflect the updated provenance rules.
Synchronous review request handling
reflexio/server/middleware.py, tests/server/test_api_security_middleware.py
The playbook review route now selects the configured synchronous timeout without requiring a query parameter, with middleware test coverage.

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

Sequence Diagram(s)

sequenceDiagram
  participant ReviewAPI
  participant UserPlaybookReviewService
  participant AgentRunStore
  participant InteractionStorage
  participant PlaybookCandidateReviewer
  ReviewAPI->>UserPlaybookReviewService: review persisted playbooks
  UserPlaybookReviewService->>AgentRunStore: load latest finalized playbook run
  AgentRunStore-->>UserPlaybookReviewService: finalized provenance
  UserPlaybookReviewService->>InteractionStorage: load and validate requests and interactions
  InteractionStorage-->>UserPlaybookReviewService: chronological review window
  UserPlaybookReviewService->>PlaybookCandidateReviewer: decide using cited interaction IDs
  PlaybookCandidateReviewer-->>UserPlaybookReviewService: decision or evidence error
  UserPlaybookReviewService-->>ReviewAPI: reviewed or skipped result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: manual playbook review now reconstructs full provenance for historical review.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/review-recent-user-playbooks-org48

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
reflexio/client/client.py (1)

1622-1637: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Report-only reviews can exceed the default client timeout

review_user_playbooks() uses the client default timeout=300, while /api/review_user_playbooks allows 600s server-side. Long report-only runs will still fail client-side unless callers raise the timeout for this endpoint.

🤖 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 `@reflexio/client/client.py` around lines 1622 - 1637, Update
review_user_playbooks to use an endpoint-specific client timeout of 600 seconds,
matching the /api/review_user_playbooks server limit, so default report-only
calls can complete without requiring callers to override the timeout.
🧹 Nitpick comments (3)
tests/server/services/storage/sqlite_storage/test_agent_run_storage.py (1)

129-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the "latest" ordering and FINALIZED_PENDING_TOOL.

The test proves filtering but not the two remaining contract clauses: newest-first selection among multiple finalized runs for the same request, and that FINALIZED_PENDING_TOOL rows qualify. Both are silent-regression prone since ordering relies on timestamp string comparison.

🤖 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 `@tests/server/services/storage/sqlite_storage/test_agent_run_storage.py`
around lines 129 - 147, Extend the test around
get_latest_finalized_agent_run_for_request to add multiple qualifying finalized
runs for the same request with differing timestamps, asserting the newest run is
selected, and add a FINALIZED_PENDING_TOOL row that is accepted by the query.
Keep the existing organization, extractor, user, and request filtering
assertions intact.
reflexio/server/services/playbook/review_service.py (1)

145-157: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Batch the request lookup. This loop does one get_request() call per distinct request_id, so large review windows turn into an N+1 storage pattern. Add a bulk get_requests_by_ids() path and use it here.

🤖 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 `@reflexio/server/services/playbook/review_service.py` around lines 145 - 157,
Replace the per-item self.storage.get_request call in the review-window loop
with a bulk self.storage.get_requests_by_ids lookup for all request IDs before
iteration. Index the returned requests by ID, then preserve the existing
missing-request and ownership validation in the loop using that indexed result.
reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py (1)

225-246: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Add a more selective index for this lookup.
idx_agent_runs_binding only covers (org_id, extractor_kind, user_id), so this query still has to filter request_id and status and then sort by created_at, updated_at, and id. A composite index that matches the full predicate and ordering would reduce work on this path.

🤖 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
`@reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py`
around lines 225 - 246, Add a composite SQLite index for the lookup in the
agent-run store, covering org_id, extractor_kind, user_id, request_id, status,
and the created_at/updated_at/id descending ordering. Register it alongside the
existing idx_agent_runs_binding definition and ensure the schema/migration path
creates it.
🤖 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.

Outside diff comments:
In `@reflexio/client/client.py`:
- Around line 1622-1637: Update review_user_playbooks to use an
endpoint-specific client timeout of 600 seconds, matching the
/api/review_user_playbooks server limit, so default report-only calls can
complete without requiring callers to override the timeout.

---

Nitpick comments:
In `@reflexio/server/services/playbook/review_service.py`:
- Around line 145-157: Replace the per-item self.storage.get_request call in the
review-window loop with a bulk self.storage.get_requests_by_ids lookup for all
request IDs before iteration. Index the returned requests by ID, then preserve
the existing missing-request and ownership validation in the loop using that
indexed result.

In
`@reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py`:
- Around line 225-246: Add a composite SQLite index for the lookup in the
agent-run store, covering org_id, extractor_kind, user_id, request_id, status,
and the created_at/updated_at/id descending ordering. Register it alongside the
existing idx_agent_runs_binding definition and ensure the schema/migration path
creates it.

In `@tests/server/services/storage/sqlite_storage/test_agent_run_storage.py`:
- Around line 129-147: Extend the test around
get_latest_finalized_agent_run_for_request to add multiple qualifying finalized
runs for the same request with differing timestamps, asserting the newest run is
selected, and add a FINALIZED_PENDING_TOOL row that is accepted by the query.
Keep the existing organization, extractor, user, and request filtering
assertions intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 74747c5f-6515-4cb4-b804-7fe1139ce05b

📥 Commits

Reviewing files that changed from the base of the PR and between b507e21 and 961d93d.

📒 Files selected for processing (14)
  • reflexio/client/client.py
  • reflexio/models/api_schema/domain/entities.py
  • reflexio/server/middleware.py
  • reflexio/server/prompt/prompt_bank/playbook_candidate_review/v1.0.0.prompt.md
  • reflexio/server/services/playbook/README.md
  • reflexio/server/services/playbook/components/reviewer.py
  • reflexio/server/services/playbook/review_service.py
  • reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py
  • reflexio/server/services/storage/storage_base/agent_run/_agent_run_store.py
  • tests/server/services/playbook/test_playbook_generation_service.py
  • tests/server/services/playbook/test_playbook_review_service_integration.py
  • tests/server/services/playbook/test_playbook_reviewer.py
  • tests/server/services/storage/sqlite_storage/test_agent_run_storage.py
  • tests/server/test_api_security_middleware.py

@yyiilluu yyiilluu changed the title fix(playbook): review full persisted generation windows fix(playbook): reconstruct full provenance for manual review Jul 30, 2026
@yyiilluu

Copy link
Copy Markdown
Contributor Author

Follow-up review addressed in 61bc74c:

  • report-only client calls now use at least the server's 600-second synchronous timeout;
  • latest-run coverage now includes newest selection, FINALIZED_PENDING_TOOL, and deterministic timestamp ties;
  • report-only no-write behavior now compares a full SQLite dump digest.

I did not add a cross-backend bulk request API or a specialized SQLite index in this PR: this admin path is explicitly bounded by top_k, and those changes would broaden the storage contract/migration surface without evidence that this lookup is a bottleneck.

@yyiilluu
yyiilluu merged commit b23b6ee into main Jul 30, 2026
1 check 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