diff --git a/docs/groomer-close-policy.md b/docs/groomer-close-policy.md new file mode 100644 index 00000000..84f600d3 --- /dev/null +++ b/docs/groomer-close-policy.md @@ -0,0 +1,27 @@ +# Groomer Close Policy + +**Status:** issue #1069 v1 decision. No additional automatic close classes are approved. + +## V1 decision + +The hosted groomer may close an issue only as `already_done`, with high confidence, no material uncertainty, and current repository evidence pinned to a SHA that grounds every acceptance criterion of that issue. A related PR or issue may corroborate the conclusion, but cannot establish it by itself; a merged PR alone is insufficient. + +`duplicate` and `superseded` remain recommendations only. No machine deduplication, implementation child, UI override, or force path is approved. A human who decides to close an issue must close it manually in GitHub, choosing the target and reason; this is not a groomer close. + +Recommendations are persisted in `GroomingRun.mutationPlan`, not surfaced in the UI. Operators can inspect an individual run through the authorized `GET /api/groomer/runs/[id]` detail API. + +## Boundaries + +No comment, label, duplicate marker, or other timeline event is sufficient human authority for automatic closure. Similar titles, bodies, labels, and citations do not establish duplicate identity. A superseded issue can qualify as `already_done` only when pinned repository evidence independently grounds that issue's own acceptance. + +A merged PR that references the issue is corroboration only, in part because an open issue may have been reopened after the merge. The remaining risk is a live regression while the cited code remains present: verbatim excerpts can still pass grounding even when behavior is broken. [#1113](https://github.com/misospace/dispatch/issues/1113) tracks that guardrail. + +## Gate for any separately approved extension + +Any proposed extension needs a separate design and explicit approval, including: + +- **Bound authority:** define and verify the permitted actor and source; distinguish human action from automation and quoted text. +- **Live target check:** bind the exact target and verify its identity and current state immediately before acting. +- **Regression fixtures:** cover the source-specific authority and target boundaries, including behavior regressing while the cited excerpt remains unchanged. + +Until such an extension is approved, duplicate and superseded outcomes remain recommendations only. diff --git a/docs/hosted-groomer.md b/docs/hosted-groomer.md index 86c57b91..067f09ec 100644 --- a/docs/hosted-groomer.md +++ b/docs/hosted-groomer.md @@ -150,6 +150,8 @@ Other rules the validator enforces: ### Close policy +The approved scope is limited to the existing deterministic `already_done` policy below. Duplicate and superseded outcomes remain recommendations for human review; see [Groomer Close Policy](./groomer-close-policy.md). + An `already_done` plan closes the issue, the highest-impact write the groomer makes. It validates only when all of these hold: - the close has reason `already_done`, verdict confidence is `high`, and no material uncertainty remains; @@ -225,7 +227,7 @@ Every run captures its own snapshot, so the key only recurs when the issue, its Dry runs use the same preconditions, diff and policies without writing: `mutationPlan.applyOutcome` is `dry_run`, `stale` or `unverifiable` (with `preconditionFailures`), or `would_replay` when the key was already applied. A dry run never claims a key, so it never reports `busy`, and it never writes a backoff. -Out of scope here, and still to come: worker admission gating on these results (#1065), child issue creation (#1066), semantic duplicate/superseded closes (design gate #1069), and UI exposure of the new history fields (#1067). +Out of scope here, and still to come: worker admission gating on these results (#1065), child issue creation (#1066), and UI exposure of the new history fields (#1067). ## History and Audit