Skip to content

plugin-approvals: a field or position approver step has no "not the submitter" guard, so a manager who submits their own request can approve it #25446

Closed as duplicate

Description

@marchtian

Ruled: 6377888641 · batch #9 item 1 (#25496, 6377842908) · letter B · 2026-10-24T00:43:45Z (step option excludeSubmitter, default off; empty set escalates per ADR-0042 or reroutes to the fallback)

Filed from the objectstack-ai/hotsrm v0.1 platform evaluation, 2026-10-23, spec 18.0.0.

What was measured

  • A two-level admission approval: step 1 approver field (the category manager on the record), step 2 position (procurement director). Both resolve and work.
  • When the category manager submits the admission themselves, step 1 resolves to the same person and they approve their own submission. Nothing in the step declaration excludes the submitter.
  • Every procurement control framework (SOX-style segregation of duties, Chinese SOE procurement rules T/CFLP 0016) treats self-approval as a finding, so an app has to add it by hand: an expression approver, or a validation rule blocking "submitter == approver" before entry. Both are easy to forget and are per-flow.

Wanted

  • A step-level option (excludeSubmitter: true, or a flow-level default) that removes the submitter from the resolved approver set and, when the set becomes empty, escalates per ADR-0042 or reroutes to the step's fallback, instead of silently letting the request through.
  • The approval record should show when the exclusion changed the route.

Acceptance

With the option on, a request whose resolved approver is its submitter is routed to the fallback or escalated, never approved by the submitter; with the option off, behaviour is unchanged.

Dedupe words: approvals self-approval submitter excluded approver segregation of duties excludeSubmitter fallback.

Activity

  1. added
    area:workflowApprovals and automation — the work that runs without a person driving it
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:awaiting-maintainerAwaiting a manual maintainer action — ruling already given; no dispatch, no machine exit
    on Oct 23, 2026
  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    Contributor

    State · director · pm:awaiting-maintainer → pm:queue · priority:p2 → priority:p1 · ruling 6377731715 letter B, default off · 2026-10-24T00:58Z

    Director seat, summon #49 (session session_0162wFwDdLFGhaSvDdSnZ9Sx, account os-zhuang; written as objectstack-fleet[bot] through the relay; ledger #12708). Ruling of record: 6377731715 on #25496 (batch #388 item 4, maintainer 「同意」 on the seat's letters). This card carried pm:awaiting-maintainer with no Maintainer-action: line while its decision was pending; the ruling is the action it waited on, so the label leaves in this act (duty 3 exit).

    What the lane builds (letter B): a step-level option excludeSubmitter: true that removes the submitter from the resolved approver set of a field or position (or any) approver step. An emptied set takes the node's existing onEmptyApprovers fallback (packages/spec/src/automation/approval.zod.ts:107) and otherwise ADR-0042 escalation — never a silent pass. The approval record shows when the exclusion changed the route. Off (the default), behaviour is unchanged; excludeSubmitter has 0 hits on origin/main today. Not taken: C (default on — it would silently reroute every existing approval). Protocol addition: spec first, then plugin-approvals. Level p1. Workload S–M.


    Generated by Claude Code

  3. os-elon-musk commented on Oct 24, 2026

    @os-elon-musk
    Collaborator

    Ruling: batch #9 item 1 (#25496) · letter B · maintainer 「#9 同意」 2026-10-24T00:43:45Z

    B = 步骤选项 excludeSubmitter(默认关):把提交人从解析出的审批人集合里去掉;集合为空时按 ADR-0042 升级或走步骤的兜底,不静默放行;审批记录显示排除改了路由。默认开(C)不采,因为会改所有现有审批的行为。工作量 S–M。与 #25481(谁能启动)是四眼原则的两半,互不替代。总裁决:#25496 评论 6377842908。

    维护者动作已完成:摘 pm:awaiting-maintainer,回 pm:queue;分级按协议变更口径由分诊定(协议新增 p1);裁不派。


    Generated by Claude Code

  4. added
    pm:queueReady for the PM dispatch loop
    priority:p1High: required for production / M2
    and removed
    pm:awaiting-maintainerAwaiting a manual maintainer action — ruling already given; no dispatch, no machine exit
    on Oct 24, 2026
  5. added and removed
    priority:p1High: required for production / M2
    on Oct 24, 2026
  6. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    Contributor

    Closed 2026-10-24T01:34Z. Superseded by #25573 — the same card ("a field or position approver step has no "not the submitter" guard"), re-filed as objectstack-fleet[bot] with this body and these labels. This card was written off the fleet relay, under the maintainer's personal account, by a project-thread session through GitHub MCP, which pm-dispatch does not allow for content writes. The thread above stays here for reference; the queue continues on #25573.

    Instruction: the maintainer 田騏, in the Objectstack project thread, 2026-10-24T01:19:49Z: 「我看到有一些使用个人账户而不是车队账户提交的issue,应该严格按照 pm-dispatch 的规则处理」
    Session: session_018fnREjMeK9XQeHDwkJXKMW

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:workflowApprovals and automation — the work that runs without a person driving itdomain:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions