From 5a650c8b1bde764cbd776d3cee800a4b78da36cf Mon Sep 17 00:00:00 2001 From: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com> Date: Thu, 18 Jun 2026 14:19:47 -0600 Subject: [PATCH 1/2] fix(proof): decouple supplied label from nudges --- dashboard/worker.ts | 20 +++----------------- docs/pr-proof-triage-dashboard.md | 10 ++++------ docs/proof-nudges.md | 9 ++++----- docs/repair/auto-update-prs.md | 2 +- src/clawsweeper.ts | 20 ++++---------------- src/repair/replacement-labels.ts | 4 +++- test/proof-nudge-policy.test.ts | 6 +++--- test/repair/replacement-labels.test.ts | 2 ++ test/review-prompt-policy.test.ts | 11 ++++------- 9 files changed, 28 insertions(+), 56 deletions(-) diff --git a/dashboard/worker.ts b/dashboard/worker.ts index 1e39aa094a..3eca3a0867 100644 --- a/dashboard/worker.ts +++ b/dashboard/worker.ts @@ -133,7 +133,6 @@ const GITHUB_APP_TOKEN_DEFAULT_TTL_MS = 50 * 60_000; const PR_PROOF_LABEL_NAMES = [ "triage: needs-real-behavior-proof", "triage: mock-only-proof", - "proof: supplied", "proof: sufficient", "proof: override", "mantis: telegram-visible-proof", @@ -207,16 +206,9 @@ const PR_PROOF_VIEWS = [ }, { id: "missing-proof", - title: "No proof supplied", - description: "Proof is requested, but no supplied, sufficient, or override label is present.", + title: "Needs proof review", + description: "Proof is requested, but ClawSweeper has not marked it sufficient or overridden.", allLabels: ["triage: needs-real-behavior-proof"], - withoutLabels: ["proof: supplied", "proof: sufficient", "proof: override"], - }, - { - id: "supplied-awaiting-review", - title: "Supplied, needs review", - description: "Proof has been supplied, but ClawSweeper has not marked it sufficient.", - allLabels: ["proof: supplied"], withoutLabels: ["proof: sufficient", "proof: override"], }, { @@ -2547,7 +2539,6 @@ function proofStateFromLabels(labels) { return "Sufficient + needs label"; } if (has("proof: sufficient")) return "Sufficient"; - if (has("proof: supplied")) return "Supplied, needs review"; if (has("triage: mock-only-proof")) return "Mock-only proof"; if (has("triage: needs-real-behavior-proof")) return "Needs proof"; if (has("mantis: telegram-visible-proof")) return "Telegram proof"; @@ -4546,12 +4537,7 @@ function prProofTriagePageConfig() { metrics: [ { label: "Proof triage PRs", view: "proof-triage", detail: "proof-related labels" }, { label: "Needs proof", view: "needs-proof", detail: "real behavior proof requested" }, - { label: "No proof supplied", view: "missing-proof", detail: "most stuck bucket" }, - { - label: "Supplied, needs review", - view: "supplied-awaiting-review", - detail: "waiting on sufficiency decision", - }, + { label: "Needs proof review", view: "missing-proof", detail: "most stuck bucket" }, { label: "Proof sufficient", view: "sufficient-proof", diff --git a/docs/pr-proof-triage-dashboard.md b/docs/pr-proof-triage-dashboard.md index 169e1aa237..ecafd6f2e1 100644 --- a/docs/pr-proof-triage-dashboard.md +++ b/docs/pr-proof-triage-dashboard.md @@ -19,7 +19,6 @@ The worker reads a fixed set of proof-related labels from the target repository: - `triage: needs-real-behavior-proof` - `triage: mock-only-proof` -- `proof: supplied` - `proof: sufficient` - `proof: override` - `mantis: telegram-visible-proof` @@ -30,16 +29,15 @@ The focused views are derived from high-signal label combinations: | ------------------------ | -------------------------------------------------------------------------------------------------------- | | Proof triage | any configured proof-related label | | Needs proof | `triage: needs-real-behavior-proof` | -| No proof supplied | `triage: needs-real-behavior-proof` without `proof: supplied`, `proof: sufficient`, or `proof: override` | -| Supplied, needs review | `proof: supplied` without `proof: sufficient` or `proof: override` | +| Needs proof review | `triage: needs-real-behavior-proof` without `proof: sufficient` or `proof: override` | | Proof sufficient | `proof: sufficient` | | Mock-only proof | `triage: mock-only-proof` | | Telegram proof | `mantis: telegram-visible-proof` | | Sufficient + needs label | `triage: needs-real-behavior-proof` and `proof: sufficient` | The API queries each proof view directly so the main stuck buckets are not -undercounted by a broad first-page snapshot. The `No proof supplied` and -`Supplied, needs review` views load up to `PR_PROOF_ITEMS_PER_VIEW`; the default +undercounted by a broad first-page snapshot. The `Needs proof review` view loads +up to `PR_PROOF_ITEMS_PER_VIEW`; the default is 500, with an upper bound of 1,000 because GitHub Search only exposes the first 1,000 results for a query. Broader summary views load fewer rows while still using GitHub's `total_count`, so the metric cards stay accurate without @@ -80,6 +78,6 @@ Keep this dashboard read-only: - no repair dispatch A later phase could add contributor reminders for PRs that remain in the -`No proof supplied` view for a maintainer-defined period, or route selected PRs +`Needs proof review` view for a maintainer-defined period, or route selected PRs to maintainers who can validate behavior in Crabbox. That should be a separate opt-in workflow with clear wording, cooldowns, and maintainer control. diff --git a/docs/proof-nudges.md b/docs/proof-nudges.md index 619156d031..8a3d480e4a 100644 --- a/docs/proof-nudges.md +++ b/docs/proof-nudges.md @@ -4,7 +4,7 @@ Read when changing the ClawSweeper lane that reminds pull request authors to add ## Scope -The proof-nudge lane is read-mostly triage hygiene. It can post a polite reminder comment on open pull requests that are stuck on `triage: needs-real-behavior-proof`, but it does not close pull requests, merge pull requests, change labels, request reviews, or modify review records. +The proof-nudge lane is read-mostly triage hygiene. It can post a polite reminder comment when the latest ClawSweeper review still requires real behavior proof, but it does not close pull requests, merge pull requests, change labels, request reviews, or modify review records. The lane uses the latest ClawSweeper review report plus the live pull request state. It does not scrape the visible review comment for policy. @@ -13,14 +13,13 @@ The lane uses the latest ClawSweeper review report plus the live pull request st A pull request is eligible only when all of these are true: - The live item is an open pull request. -- The live pull request still has `triage: needs-real-behavior-proof`. - The latest report still says real behavior proof blocks merge. - The report head SHA matches the live pull request head SHA. - The pull request is past the first-nudge age gate, defaulting to 5 days. - The author has not commented recently and the head commit is not recent. - There is no same-head proof nudge inside the cooldown window, defaulting to 7 days. -The lane skips maintainer-authored, bot-authored, security-sensitive, and release-style pull requests. It also skips pull requests with `proof: supplied`, `proof: sufficient`, or `proof: override`, because those need review or policy handling rather than another contributor reminder. +The lane skips maintainer-authored, bot-authored, security-sensitive, and release-style pull requests. It also skips pull requests with `proof: sufficient` or `proof: override`, because those need review or policy handling rather than another contributor reminder. OpenClaw's `triage: needs-pr-context` label is separate contributor-body hygiene and does not decide real-proof sufficiency. ## Bot-Owned Proof Handling @@ -33,8 +32,8 @@ The bot-owned lane is status-only unless an approved Mantis proof suggestion is available. It is eligible only when the live PR is open and not draft, the author is the ClawSweeper GitHub App, the latest ClawSweeper review says real behavior proof blocks merge, and that review head -SHA still matches the live head SHA. It must skip PRs with `proof: supplied`, -`proof: sufficient`, or `proof: override`. +SHA still matches the live head SHA. It must skip PRs with `proof: sufficient` +or `proof: override`. When the review includes an approved Mantis-style proof suggestion, the lane posts a durable Mantis proof request comment. Otherwise it updates one durable diff --git a/docs/repair/auto-update-prs.md b/docs/repair/auto-update-prs.md index a87773aa8a..48acfe5e41 100644 --- a/docs/repair/auto-update-prs.md +++ b/docs/repair/auto-update-prs.md @@ -299,7 +299,7 @@ status contains `clawsweeper_self_rebase` or `conflict_self_heal`. Replacement PR labels must describe the replacement PR, not stale lifecycle state from a source PR. Replacement creation filters source labels so it does not copy `close:*`, `stale`, `rating:*`, `status:*`, `proof:*`, -`triage: needs-real-behavior-proof`, `merge-risk:*`, `size:*`, or `P*` +`triage: needs-real-behavior-proof`, `triage: needs-pr-context`, `merge-risk:*`, `size:*`, or `P*` priority labels. Use the cleanup command to inspect existing open ClawSweeper replacement PRs diff --git a/src/clawsweeper.ts b/src/clawsweeper.ts index 60f8cda71f..9d72b0133c 100644 --- a/src/clawsweeper.ts +++ b/src/clawsweeper.ts @@ -829,7 +829,6 @@ type ProofNudgeAction = | "proof_nudge_planned" | "skipped_not_pull_request" | "skipped_not_open" - | "skipped_missing_label" | "skipped_policy_exempt" | "skipped_stale_report_head" | "skipped_recent_author_activity" @@ -1099,8 +1098,6 @@ const UNCONFIRMED_PRODUCT_DIRECTION_EXEMPT_LABELS = new Set([ ]); const PROOF_OVERRIDE_LABEL = "proof: override"; const PROOF_SUFFICIENT_LABEL = "proof: sufficient"; -const PROOF_SUPPLIED_LABEL = "proof: supplied"; -const REAL_BEHAVIOR_PROOF_REQUIRED_LABEL = "triage: needs-real-behavior-proof"; const PROOF_NUDGE_MARKER_PREFIX = "