Problem/Motivation

Orchestra staffs a human task from roles or from named users. There is no way to offer a step to the members of a group, which is how an organisation that already models its teams in Group expects to route work.

The assignment API anticipates exactly this. AssignmentInterface says so in its own docblock: "A new assignable audience (a group, an org unit, a custom rule) is just a new plugin minting its own token type on both sides, with no change to storage or the query."

Proposed resolution

Add an orchestra_group submodule with a Groups assignment plugin that mints a group:GID candidate token per configured group, and, for a given account, the same token per group that account is a member of. Candidacy is evaluated live, so joining or leaving is reflected without touching the run. No storage change and no query change, as the interface promises.

The dimension is membership, not permission. A group role in the outsider or insider scope is derived from a global role and applies to every group of its type, including groups the account has never joined, so it cannot be enumerated from an account the way a viewer token has to be. Only a real membership names a group here, and the class says so where somebody would try to add it.

Two things make a token unmatched, and the recovery sweep should tell them apart: the group has been deleted, or it still exists and has no active member left. Both mean the step is waiting on nobody.

Notification fan-out is capped exactly as RoleAudienceBase caps it, and the cap matters more here: a role pool is bounded by site configuration, while group membership is user data and can grow without anybody revisiting the workflow. Blocked accounts are excluded, matching the status condition the role dimension uses.

A group ID that names no group is a validation error, where an unheld role is only a warning. The asymmetry is deliberate: a role machine name may be about to be created, but a numeric group ID that resolves to nothing is a typo or a deleted group and will never fill. A group that exists but has no members still only warns.

A consequence worth stating

Under the AUDIENCE read scope, pooling a step to a group opens the run to everyone in that group, including people who join afterwards. That is what an audience is, and the scope documentation already warns the same thing about roles. It is worth saying again for groups, because group membership is routinely delegated to group administrators, so the set of people who can widen a run's readership is larger than it is for roles.

Remaining tasks

  • Kernel and functional test coverage.
  • A variable-driven twin, Groups by variable, so a run about group-owned content can read the group from a process variable. Follow-up, not this issue.

AI-Generated: Yes (Claude Code was used to help draft this issue summary and to write the code on the merge request. I reviewed the work and exercised the plugin against real groups and memberships before posting it.)

Issue fork orchestra-3624219

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • mably committed 66bf6546 on 1.x
    feat: #3624219 Add an Orchestra Group submodule that staffs tasks from...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.