Skip to content

feat(worker): deterministic publication gates + policy modes for review findings (#11)#53

Merged
BunsDev merged 1 commit into
mainfrom
feat/issue-11-publication-gates
Jul 7, 2026
Merged

feat(worker): deterministic publication gates + policy modes for review findings (#11)#53
BunsDev merged 1 commit into
mainfrom
feat/issue-11-publication-gates

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 7, 2026

Copy link
Copy Markdown
Member

Closes #11 — the correctness-lane capstone.

What was already true on main

What this PR adds — the missing findings pipeline

Findings validated but never rendered; now they pass a deterministic, adapter-owned gate chain (crates/worker/src/findings.rs) and publish:

  1. Scope gate — files the session never consulted (∉ reviewed ∪ supporting ∪ PR changed set) are speculative → withheld
  2. Severity threshold[review] min_severity policy (global + per-repo override)
  3. Dedup — identical (file, line, title) collapse

The digest is bounded (<48 KB) and honest: withheld counts + reasons always stated.

Publish modes ([review] publish, per-repo overridable, doctor-validated):

  • check_run (default) — digest on the Check Run output
  • advisory_comment — additionally appended to the marker-backed status comment
  • request_changes — submits a blocking PR review (REQUEST_CHANGES when findings exist, COMMENT otherwise) using post-gate publication authority (the Split agent read auth from publication write auth #4 boundary; proven by auth-header assertion)

Contract note: a confidence axis is specified for headless contract v3; v2 findings carry severity only — filtering is severity-based, documented in the module.

Verification

  • 9 findings-module unit tests (scope/threshold/dedupe/ordering/honest rendering/boundedness)
  • 3 wiremock end-to-end proofs: withheld findings never reach the check run; request_changes posts the verdict with the publication token; advisory digest rides the status comment
  • config accessor + doctor-validation tests
  • 188 tests green · clippy -D warnings clean · python gates green · demo 21/21

…view findings (#11)

Closes #11.

Findings now pass an adapter-owned gate chain before any GitHub surface
sees them (crates/worker/src/findings.rs):

- scope: files the session never consulted (not reviewed, supporting, or in
  the PR changed set) are withheld as speculative
- severity threshold: repo policy min_severity (info..critical) filters
  below-threshold findings
- duplicates: identical (file, line, title) findings collapse

The rendered digest is bounded and honest — withheld counts and reasons are
always stated, so a quiet report is distinguishable from a filtered one.

A new [review] publish policy routes the gated digest: check_run (default),
advisory_comment (also on the marker-backed status comment), or
request_changes (a blocking PR review verdict submitted with post-gate
publication authority — REQUEST_CHANGES when findings exist, COMMENT
otherwise). Doctor rejects unknown policy values.

Together with what already shipped, this completes #11's gate chain:
off-schema envelopes are rejected (contract v2 validation), stale refs are
withheld pre-publish (#8), secret redaction covers every published field,
and memory writes are approval-gated (#6). A findings confidence axis is
specified for headless contract v3; v2 carries severity only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Val Alexander <bunsthedev@gmail.com>
Copilot AI review requested due to automatic review settings July 7, 2026 05:33
@BunsDev BunsDev merged commit eadaea3 into main Jul 7, 2026
2 checks passed
@BunsDev BunsDev deleted the feat/issue-11-publication-gates branch July 7, 2026 05:37

Copilot AI 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.

Pull request overview

This PR completes the “review findings publication” pipeline in the coven-github worker by adding adapter-owned, deterministic gates over structured review findings and routing the gated digest to different GitHub surfaces based on repo policy.

Changes:

  • Introduce crates/worker/src/findings.rs to gate findings by scope, severity threshold, and deduplication, then render a bounded digest.
  • Extend worker publication (crates/worker/src/lib.rs) to append the gated digest to the Check Run summary and optionally publish it as an advisory status comment append or as a blocking PR review verdict.
  • Add configuration and validation for [review] min_severity and [review] publish (global + per-repo overrides), with example config docs and test updates.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Documents the new deterministic findings publication gates and publish modes.
crates/worker/src/lib.rs Wires gated findings digest into Check Run output and optional advisory/review verdict publication paths; adds E2E tests.
crates/worker/src/findings.rs Implements scope/severity/dedupe gates and digest rendering for findings.
crates/webhook/src/routes.rs Updates review-lane tests to include new review policy fields.
crates/github/src/pr.rs Adds API helper to submit PR reviews for request_changes publish mode.
crates/config/src/lib.rs Adds review policy fields, per-repo overrides, and doctor validation for closed-enum policy values.
config/example.toml Documents new [review] policy knobs and allowed values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/config/src/lib.rs
Comment on lines +199 to 211
pub fn min_severity_for(&self, repo: &str) -> Option<String> {
self.overrides(repo)
.and_then(|o| o.min_severity.clone())
.or_else(|| self.min_severity.clone())
}

/// Findings publication mode for `repo` (raw string; issue #11).
pub fn publish_for(&self, repo: &str) -> Option<String> {
self.overrides(repo)
.and_then(|o| o.publish.clone())
.or_else(|| self.publish.clone())
}
}
Comment thread crates/worker/src/lib.rs
Comment on lines +438 to +440
let report = findings::render(&outcome);
check_summary = format!("{check_summary}\n\n{report}");
match config.review.publish_for(&repo_key).as_deref() {
Comment on lines +84 to +87
outcome
.published
.sort_by_key(|f| std::cmp::Reverse(rank(f.severity.clone())));
outcome
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.

Add structured review output and deterministic publication gates

2 participants