feat(server): resolution capture for persona feedback (CRU-128) - #372
Merged
selfcontained merged 3 commits intoApr 21, 2026
Merged
Conversation
Phase 1 of the review round-trip flow. Captures an explicit "why" on every resolved feedback item and a parent-supplied summary per review, laying the audit-trail foundation Phase 2 will build on. - Migration 0016: resolution_reason/commit/resolved_at on agent_feedback, last_reviewed_commit on persona_reviews, and persona_review_resolutions table (forward-compatible with Phase 2). - dispatch_resolve_feedback + HTTP PATCH: accept optional reason, reject ignored items without one, record HEAD at the call site. - dispatch_submit_resolution (new) + HTTP POST: parent submits a 1–3 sentence summary once every item is resolved. Server rejects if items remain open or ignored items are missing a reason. - Capture parent HEAD on persona launch and on complete_review so Phase 2 can diff round-1 findings against the reviewed snapshot. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses backend-security-review feedback on PR #372. - Preserve resolution_reason / resolution_commit via COALESCE when a later fixed/ignored call passes null, so a benign second call (e.g. a bulk re-resolve) does not wipe the original audit-trail. - Set resolved_at only on the first transition into fixed/ignored; benign re-calls no longer drift the timestamp forward. Re-opening still clears it. - Cap dispatch_resolve_feedback reason at 10,000 chars to match dispatch_submit_resolution summary. - Skip getAgent + git rev-parse in the HTTP PATCH handler when the status change is not a resolution (no resolution_commit recorded). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CRU-128 backend now requires a reason when marking feedback as ignored. Without an inline prompt (CRU-129 scope), the existing Ignore button would 400. Stamp "User's choice" as a placeholder so the button keeps working and CRU-128 can release without CRU-129. CRU-129 will replace this with a proper inline reason prompt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
selfcontained
marked this pull request as ready for review
April 21, 2026 03:45
selfcontained
deleted the
brad/cru-128-phase-1-schema-backend-for-resolution-capture
branch
April 21, 2026 03:45
This was referenced Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the review round-trip flow (CRU-127 / CRU-128). Captures an explicit "why" on every resolved feedback item and a parent-supplied summary per review, laying the audit-trail foundation that Phase 2's round-trip loop will build on.
resolution_reason,resolution_commit,resolved_attoagent_feedback;last_reviewed_committopersona_reviews; and a newpersona_review_resolutionstable. The resolutions table is created withround_numberdefaulting to 1 so Phase 2 (CRU-131) can layer on additional rounds without another table migration.dispatch_resolve_feedback(and HTTPPATCH /api/v1/agents/:id/feedback/:feedbackId) — accept an optionalreason. Rejectsignoreditems without one. Records HEAD at the call site asresolution_commit.dispatch_submit_resolution(new) and HTTPPOST /api/v1/agents/:id/persona-reviews/:personaAgentId/resolution— parent submits a 1–3 sentence summary once every feedback item is resolved. Server rejects if any item is stillopenor anyignoreditem is missing a reason.dispatch_complete_reviewso Phase 2 can diff round-1 findings against the reviewed snapshot.Out of scope for this PR: UI surfacing (CRU-129) and a dedicated test suite for the new paths (CRU-130).
Test plan
pnpm run checkpassespnpm run test— 325 passed, 11 skipped, no regressions (updated one existing test that calledupdateFeedbackStatusByParentwithignoredand no reason)pnpm run test:e2e— 138 passed, 6 skipped