Add explicit close_pr capability resolution and gated PR close path #216

Closed
opened 2026-07-05 16:03:26 -05:00 by jcwalker3 · 1 comment
Owner

Problem

The author workflow needed to close contaminated PR #205, but gitea_resolve_task_capability(close_pr) was reported as unknown. The agent closed the PR through gitea_edit_pr(state=closed) under explicit operator directive.

This worked, but it means PR closure is not represented as a first-class capability task. Agents may use broader edit paths to close PRs without a specific close capability proof.

Observed evidence

  • gitea_resolve_task_capability(task="close_pr", remote="prgs")Unknown task/action: 'close_pr' (fail closed) (correct fail-closed resolver behavior, but no legitimate path exists).
  • Fallback used: gitea_edit_pr(pr_number=205, state="closed") under jcwalker3 / prgs-author — succeeded with no close-specific capability proof; the edit path does not distinguish closing from retitling.

Required wall

PR closure must have an explicit resolver task and gated tool path.

Required behavior

  • gitea_resolve_task_capability(close_pr) must resolve to the exact allowed operation required to close a PR.
  • Closing a PR through gitea_edit_pr(state=closed) must require the same explicit close capability.
  • Reports must distinguish PR comment, PR edit, and PR close capabilities.
  • If close_pr is unknown, the agent must fail closed unless the operator explicitly authorizes the fallback and the fallback is audited.

Acceptance criteria

  • Add resolver coverage for close_pr.
  • Add tests where close_pr is requested under author profile and reviewer profile.
  • Add tests where gitea_edit_pr(state=closed) is attempted without close capability; expected result: blocked.
  • Add tests where a contaminated PR is closed under explicit operator directive with the correct capability; expected result: allowed and audited.

Related

  • Origin incident: PR #205 closure (invalid-provenance cleanup; replacement PR #213).
  • #183 — same resolver-gap family (mark_issue unknown to TASK_MAP); this issue adds close_pr and the edit-path capability split.
  • #191 — exact mutation capability proof in final reports; a distinct gitea.pr.close operation makes that proof possible for closures.
### Problem The author workflow needed to close contaminated PR #205, but `gitea_resolve_task_capability(close_pr)` was reported as unknown. The agent closed the PR through `gitea_edit_pr(state=closed)` under explicit operator directive. This worked, but it means PR closure is not represented as a first-class capability task. Agents may use broader edit paths to close PRs without a specific close capability proof. ### Observed evidence - `gitea_resolve_task_capability(task="close_pr", remote="prgs")` → `Unknown task/action: 'close_pr' (fail closed)` (correct fail-closed resolver behavior, but no legitimate path exists). - Fallback used: `gitea_edit_pr(pr_number=205, state="closed")` under `jcwalker3 / prgs-author` — succeeded with no close-specific capability proof; the edit path does not distinguish closing from retitling. ### Required wall PR closure must have an explicit resolver task and gated tool path. ### Required behavior * `gitea_resolve_task_capability(close_pr)` must resolve to the exact allowed operation required to close a PR. * Closing a PR through `gitea_edit_pr(state=closed)` must require the same explicit close capability. * Reports must distinguish PR comment, PR edit, and PR close capabilities. * If `close_pr` is unknown, the agent must fail closed unless the operator explicitly authorizes the fallback and the fallback is audited. ### Acceptance criteria * Add resolver coverage for `close_pr`. * Add tests where `close_pr` is requested under author profile and reviewer profile. * Add tests where `gitea_edit_pr(state=closed)` is attempted without close capability; expected result: blocked. * Add tests where a contaminated PR is closed under explicit operator directive with the correct capability; expected result: allowed and audited. ### Related * Origin incident: PR #205 closure (invalid-provenance cleanup; replacement PR #213). * #183 — same resolver-gap family (`mark_issue` unknown to `TASK_MAP`); this issue adds `close_pr` and the edit-path capability split. * #191 — exact mutation capability proof in final reports; a distinct `gitea.pr.close` operation makes that proof possible for closures.
jcwalker3 added the status:in-progress label 2026-07-05 16:06:00 -05:00
Author
Owner

Implementation up as PR #219 (feat/issue-216-close-pr-capability, based on current master).

  • close_pr resolver task → gitea.pr.close (author-side); lookalike task names still fail closed.
  • gitea_edit_pr(state="closed") gated on the same gitea.pr.close — blocked closes fail before any auth/API call with a structured permission_report; permitted closes are audited as a distinct close_pr action carrying required_permission: gitea.pr.close.
  • Edits/reopen remain ungated (comment / edit / close capability split), invalid state values rejected.
  • Acceptance-criteria tests in tests/test_close_pr_capability.py + resolver tests; full suite 744 passed / 6 skipped.

Issue stays status:in-progress until PR #219 merges (tracker cleanup releases it automatically).

Implementation up as PR #219 (`feat/issue-216-close-pr-capability`, based on current `master`). - `close_pr` resolver task → `gitea.pr.close` (author-side); lookalike task names still fail closed. - `gitea_edit_pr(state="closed")` gated on the same `gitea.pr.close` — blocked closes fail before any auth/API call with a structured `permission_report`; permitted closes are audited as a distinct `close_pr` action carrying `required_permission: gitea.pr.close`. - Edits/reopen remain ungated (comment / edit / close capability split), invalid `state` values rejected. - Acceptance-criteria tests in `tests/test_close_pr_capability.py` + resolver tests; full suite 744 passed / 6 skipped. Issue stays `status:in-progress` until PR #219 merges (tracker cleanup releases it automatically).
sysadmin removed the status:in-progress label 2026-07-05 16:22:24 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#216