Skip to content

fix(purchase): route AutoPurchase steps to approval when RequireDifferentApprover is on #1771

Closed

Description

@cristim

Split from the #348 tracker (A05-003). Confirmed on main 0015bea.

enforceFourEyesPolicy (internal/purchase/approvals.go:232) says it's the single choke point for RequireDifferentApprover, but only ApproveAndExecute calls it (approvals.go:424). The scheduler's auto path skips it entirely: the cron sweep and SQS (executableByScheduler, internal/purchase/manager.go:887-915, then claimAndExecuteWithin and executeAndFinalize). So with dual control on, an armed AutoPurchase plan still buys with no second person.

Decision (fleet coordinator, recorded on #348, comment 6657724378; the owner can override): with RequireDifferentApprover on, an AutoPurchase plan must not auto-execute. Its due step goes to the approval queue, the same pending/notified state and approval email a non-auto plan gets. It must not be refused silently. Document this at the gate.

Test: a real-path test runs the flag on, with an armed plan and a due step, through the scheduler entry point. The row ends awaiting approval, the purchaser is never called, and an approval by a different user then runs it. With the flag off, the auto path is unchanged. A mutation that skips the new check must fail it.

Activity

  1. cristim commented on Nov 5, 2026

    @cristim
    MemberAuthor

    Claimed by claude-qa-ui-3: queued right after #348 F6 (in progress). Next step: read the scheduler auto path and the approval routing, then write a plan with a plan review before any code.

  2. cristim commented on Nov 5, 2026

    @cristim
    MemberAuthor

    Recorded decision (fleet coordinator, 2026-11-05; the owner can override):

    • Option (a): under 4-eyes, a plan-step root pre-created through the admin API key fails closed. It has no recorded creator and isn't system-created, so enforceFourEyesPolicy denies every approver. Such a step waits in the queue, then expires about 7 days after its date; a human then recreates the plan. This will be documented in the PR and the RequireDifferentApprover doc comment.
    • Approved: the plan-step email under 4-eyes, and for manual plans, keeps its totals sentence but ends "once approved" with "approve it in the approval queue" (the existing Review & Edit deep link), instead of "unless canceled" and "before automatic execution".
    • Option (b), not chosen: treat API-key-created roots like system-created ones, so any identified human may approve. The owner can switch to it.
  3. cristim commented on Nov 5, 2026

    @cristim
    MemberAuthor

    Claimed by claude-qa-ui-3: PR #1793 is open (head 658a922) and waiting for 2 cold reviews.

  4. added a commit that references this issue on Nov 5, 2026
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