Skip to content

plugin-approvals: ApprovalService.recall's docblock opens "(submitter only)" and contradicts itself 12 lines later, where the #3424 override is stated correctly #15643

Description

@claude

Filed out of scope from #14670 by the os-dev seat working that card (session session_01G4138K1EG7kQ81FNba5Kp4), dispatched by the domain:spec PM seat. Observation only; unassigned; domain:*, type and grading are triage's.

#14670 corrects the spec side of this: IApprovalService.recall's docstring claimed "Only the submitter (or a system context) may recall", which omits the #3424 admin override. The implementation's own docblock, in the domain:services lane, opens with the same false-exhaustive claim — and then contradicts it 12 lines later.

Measured

packages/plugins/plugin-approvals/src/approval-service.ts, on origin/main d30ccb9bd963942d33072443f680a32664087346, read 2026-09-05:

line text
:2933 * Withdraw a pending request (submitter only). Finalises the row as
:2945 * The #3424 privileged override reaches a PENDING request only (#12775,
:2946 * maintainer ruling 2026-09-02). On returned an override actor is refused

So the summary sentence says the submitter is the only actor, and the third paragraph of the same block says an override actor reaches a pending request. The code below settles it in the third paragraph's favour — :2987:

const overrideAdmits = raw.status === 'pending'
  && this.isOverrideActor(context, raw.organization_id ?? null);

and isOverrideActor's own docblock (:944-:952) names the levers outright: "approve, reject, reassign it to a real approver, or recall it".

Severity: low, and stated honestly

Unlike the spec-side defect, this block does correct itself before the reader leaves it, so nobody reading the whole docblock is misled. What is wrong is the summary line — the part that shows in an editor's hover and in any one-line extraction. It is the same class #14670 exists to fix, one surface over.

Why it is filed rather than fixed

#14670's fence is packages/spec only; plugin-approvals is the domain:services lane's single-owner surface. The one-word fix (drop (submitter only), or widen it to match :2945) is not mine to make.

Suggested shape

Make the summary line agree with the block it heads, e.g. "Withdraw an undecided request." with the actor rules left to the paragraphs that already state them correctly — the same structural move #14670 makes on the spec side, where status became the axis instead of a general rule plus corrections.

Not a duplicate

Checked against the 366 most recently created open issues via the repo-scoped REST list plus a local grep, with a control probe confirming the listing was live. #15439 is the nearest neighbour and is a different surface (ApprovalDecisionResult's docblock, the #13807 stranded-decision facts); #15336 groups the #13937 contract-review residues, not this.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions