Skip to content

feat(automations): GROUP_HAS_TAG condition — match when any group member carries a tag #2255

Description

@nitrobass24

Problem

Automation conditions can reason about a torrent's group membership (GROUP_SIZE, IS_GROUPED, scoped per-condition via groupId), but tag conditions only see the torrent's own tags (FieldTags in internal/services/automations/evaluator.go). There is no way to express "any member of this torrent's group already carries tag X."

This matters for cross-seed workflows: state applied to one copy of a release (e.g. a processed/archived tag) is invisible to its group-mates. When the cross-seed engine later adds a new copy of that same release, the new torrent has no tags of its own, re-qualifies for the same rules, and gets re-processed — per-torrent tag state can never converge at the release level.

Proposal

New condition field GROUP_HAS_TAG:

  • Semantics: true when any member of the torrent's resolved group (including itself) carries the given tag; supports the existing string operators where sensible (equals/contains against the member tag sets).
  • Group resolution follows the existing pattern: honor the condition's groupId, falling back to the rule's active/default group (resolveConditionGroupIndex).
  • Implementation sketch: in the evaluator, MembersForHash(hash) → look up each member in the run's torrentByHash → check tag membership. All the needed indexes already exist in the eval context; this is a small addition alongside FieldGroupSize/FieldIsGrouped (evaluator.go:517,606).
  • Negation composes via the existing condition tree (NOT GROUP_HAS_TAG = "no member of this group has been marked"), which is the primary use: run an action at most once per release group even as new members appear over time.

Example rule this unlocks

Tag torrents for archival review only when their release group hasn't been handled yet:
IS_GROUPED AND NOT GROUP_HAS_TAG("archived") → add tag review

Today the equivalent rule re-fires every time the cross-seed engine adds another copy of an already-handled release.

Notes

  • Ambiguous-group safety (verify_overlap on contentPath-keyed groups) should apply the same way it does for group-aware delete expansion, so a flat-layout false group can't leak tag state across unrelated torrents.
  • Pairs naturally with group-scoped tag actions (separate issue) but is independently useful for read-only conditions.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions