Skip to content
This repository was archived by the owner on Jun 25, 2026. It is now read-only.
This repository was archived by the owner on Jun 25, 2026. It is now read-only.

feat(campaigns): orchestrate multi-run maintenance campaigns with progress tracking and bulk controls #164

Description

@rtzll

Related: #120
Related: #128

Summary

Rascal is good at one-off runs and issue/PR-driven follow-ups, but large maintenance work often needs coordinated batches: dependency rollouts, repository hygiene sweeps, migration follow-ups, or repeated remediation across many targets.

This issue adds a first-class campaign layer that groups many runs under one operator-visible objective with progress tracking, pause/resume controls, failure summaries, and bulk retry behavior.

Outcome

Operators can create a campaign that fans out a bounded set of Rascal runs, monitor aggregate progress, pause or cancel the batch safely, and inspect which items succeeded, failed, were skipped, or still need attention.

Goals

  • Make repetitive multi-run work manageable without external scripts.
  • Reuse the existing run/task/scheduler machinery rather than inventing a separate executor.
  • Give operators a single object to watch and control during large maintenance efforts.
  • Keep campaign behavior safe, bounded, and inspectable.
  • Leave room for both single-repo and multi-repo use cases.

Non-goals

Scope

Implement V1 campaigns with the following pieces.

  1. Campaign model
  • Add persistent campaign records with at least:
    • id
    • name
    • description
    • state (draft, running, paused, completed, canceled, failed)
    • execution policy
    • created/updated timestamps
  • Add campaign-item records representing planned or realized runs.
  • Each item should capture at least:
    • repo
    • task template or resolved task text
    • base branch override if any
    • backend/profile override if any
    • item state (pending, queued, running, review, succeeded, failed, skipped, canceled)
    • linked task/run ids when created
    • skip/failure reason when relevant
  1. Campaign creation sources
  • Support creating a campaign from one of:
    • inline item definitions
    • a YAML/JSON manifest file
    • future repo-registry query results
  • Keep the manifest format small and explicit.
  • V1 should allow repeated tasks across one repo or multiple repos.
  1. Execution policy
  • Add campaign-level controls such as:
    • max concurrent items
    • stop after N failures
    • continue on failure
    • skip items when an open Rascal PR already exists
    • dry-run validation before enqueueing
  • Default to conservative behavior.
  1. Bulk controls
  • Add CLI management such as:
    • rascal campaign create
    • rascal campaign list
    • rascal campaign view
    • rascal campaign start
    • rascal campaign pause
    • rascal campaign resume
    • rascal campaign cancel
    • rascal campaign retry-failed
  • Operators must not need direct DB edits.
  1. Progress and reporting
  • Surface aggregate campaign progress, including counts by item state.
  • Persist a campaign summary artifact or API view showing:
    • total items
    • active items
    • successes
    • failures
    • skipped items and reasons
    • linked PRs and runs
  • Make the summary inspectable while the campaign is still running.
  1. Scheduler integration
  • Campaign items should enqueue ordinary Rascal runs.
  • Campaign logic should respect existing scheduler bounds and repo/task serialization.
  • The campaign layer must not bypass the existing control plane invariants.

Suggested implementation approach

  1. Keep campaigns declarative.
  • A campaign is a managed set of item intents plus progress metadata.
  • Item execution should still flow through normal run creation and scheduling.
  1. Start with independent items only.
  • V1 should not support arbitrary dependency graphs.
  • If ordering is needed, allow a simple list order with bounded concurrency.
  1. Reuse existing repo/run policy resolution.
  1. Make dry-run validation first-class.
  • Validate manifest shape, repo references, and policy constraints before starting work.
  • Prefer early rejection over half-started campaigns.
  1. Keep campaign state separate from task state.
  • The campaign is an operator-facing batch object.
  • Tasks and runs remain the execution-facing objects underneath it.

Acceptance criteria

  • Operators can create, inspect, start, pause, resume, cancel, and retry campaigns from the CLI.
  • Campaign items persist explicit state and link to created tasks/runs.
  • Campaign execution respects bounded concurrency and normal Rascal admission rules.
  • Operators can inspect aggregate progress and per-item outcomes.
  • Dry-run validation exists before starting a campaign.
  • Tests cover manifest parsing, state transitions, pause/resume/cancel behavior, and aggregate reporting.

Suggested test plan

  • Unit tests for campaign manifest validation and item expansion.
  • Unit tests for campaign state transitions and policy evaluation.
  • Integration tests for start, pause, resume, cancel, and retry-failed flows.
  • Scheduler-adjacent tests proving campaign items do not bypass run admission rules.
  • Regression tests for failure-threshold stop behavior and open-PR skip behavior.

Implementation notes

  • Keep V1 focused on controlled batch execution, not general workflow orchestration.
  • This should remove the need for ad hoc shell loops while preserving Rascal’s existing reliability properties.
  • A boring, inspectable campaign layer is the right first step.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions