feat(remediation): conditional approval (A-keep) — free-core auto-approves#606
Closed
remyluslosius wants to merge 1 commit into
Closed
feat(remediation): conditional approval (A-keep) — free-core auto-approves#606remyluslosius wants to merge 1 commit into
remyluslosius wants to merge 1 commit into
Conversation
…roves Implements the A-keep ADR: free-core single-rule remediation no longer requires a separate human approval, so a single operator can request and Fix a finding directly (removing the self-review deadlock). The approve/reject flow with separation of duties is retained for the licensed bulk/auto track. - Request(...requiresApproval bool): false (free core) inserts an 'approved' row directly (reviewed_at set, reviewed_by NULL, auto-approved review_note) and emits remediation.requested + remediation.approved; true (licensed bulk/auto) inserts 'pending_approval' and goes through Approve/Reject. - The single-rule request handler passes false. - Tests: AC-01 covers auto-approve + the approval-required path; the HTTP AC-05/AC-06 approve and pending-execute paths seed a pending_approval request (the free-core POST auto-approves). Frontend unchanged (the hook already renders approved -> Fix and keeps the pending_approval/approve UI for the licensed track). Note: the ADR + governance docs land in #604; their status flips to 'implemented' once both merge.
This was referenced Jun 19, 2026
Contributor
Author
|
Folded into #609 (release: bundle 0.2.0-rc.11) and merged there to avoid the CHANGELOG rebase cascade. Content is on main. |
remyluslosius
added a commit
that referenced
this pull request
Jun 20, 2026
… 110) (#610) - CLAUDE.md: Last Updated 2026-06-20; Remediation row -> Complete (#601/#606/#607); scanning-status note -> v0.2.0-rc.11 incl. free-core remediation; spec count 108 -> 110 - BACKLOG.md: drop done rows (Remediation tab, specter 100%-all-tiers, -p 1 -> -p 4) - scan_remaining_work.md: Phase 7 first-slice shipped banner; remaining = licensed track - SESSION_LOG.md: 2026-06-20 entry (rc.11 cut, bundle mechanics, gotchas)
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.
Conditional approval (A-keep): free-core remediation auto-approves
Implements the A-keep ADR (PR #604). Free-core single-rule remediation no longer requires a separate human approval, so a single operator can request and Fix a finding directly — removing the self-review deadlock (you could request a fix but never approve your own request, getting a 409
self_review).Change
remediation.Request(…, requiresApproval bool):false(free core) — inserts the request directly inapproved(reviewed_at set, reviewed_by NULL, an auto-approved review_note) and emitsremediation.requested+remediation.approved. The operator clicks Fix; no approval step.true(licensed bulk/auto track) — insertspending_approvaland goes through Approve/Reject with separation of duties, exactly as before.false.Retained for the licensed track
The whole governance machinery (request → approve/reject, self-review guard, the endpoints, the frontend approve/reject UI) is unchanged — it's what the OpenWatch+ bulk/auto track will use.
No migration, no frontend change
The request
statusdrives the UI, which already rendersapproved → Fixand keeps thepending_approval/approve UI for the licensed track. The hook's source-inspection tests are unaffected.Tests
AC-01now covers both auto-approve (free core) and the approval-required path.AC-05/AC-06seed apending_approvalrequest directly (the free-core POST auto-approves) to keep exercising the approve endpoint + the pending-execute 409 path.Verified locally
Full
remediation+worker+serversuite green (exit 0); Specter 110 specs valid, 100% structural coverage; gofmt clean.