Skip to content

Deliver issues in waves the graph computes, and take the next one

Validate the plan, read the execution waves the dependency graph yields, see which issues are ready and which are blocked on what, and take the one issue a worker should do now.

guaranteed Parallel workersintermediatemaintaineragentwrites state

Situation

A plan with twenty issues and a handful of dependencies has an order in it that nobody wrote down. Workers pick what looks interesting, two of them take issues that touch the same files, and the dependency somebody forgot surfaces as a rebase.

What you run

  • plan validate: the model, references, DAG and status consistency
  • plan waves, plan ready, plan blocked: the order the graph implies, and what is waiting on what
  • plan next: the one issue to take
  • start <task> --scope <paths>: the task under the issue’s scope, with overlap reported at start

Scenario

setup: plan-model
given:
  - 'installed, with a canonical project model carrying one milestone and two issues'
steps:
  - id: validate
    run: ['plan', 'validate']
    note: 'schemas, references, the DAG and status consistency; a cycle or a dependency on a missing issue is refused by name'
    expect:
      exit: 0
      stdout_contains: ['0 failure']
  - id: waves
    run: ['plan', 'waves']
    note: 'topological execution waves; issues in one wave that touch the same paths are reported as serialised'
    expect:
      exit: 0
      stdout_contains: ['^Wave 0', 'I0001 +READY', '^Wave 1', 'I0002 +BLOCKED']
  - id: ready
    run: ['plan', 'ready']
    note: 'issues whose dependencies are all satisfied'
    expect:
      exit: 0
      stdout_contains: ['I0001']
      stdout_not_contains: ['I0002']
  - id: blocked
    run: ['plan', 'blocked']
    note: 'issues waiting on a dependency, and on which one'
    expect:
      exit: 0
      stdout_contains: ['I0002']
  - id: next
    run: ['plan', 'next']
    note: 'the one issue a worker should take now'
    expect:
      exit: 0
      stdout_contains: ['^I0001 ', 'scope:', 'next: majordomus plan start I0001']
  - id: take-it
    run: ['start', 'I0001', '--scope', 'src/I0001']
    note: 'the task under the scope the issue names; overlap with other worktrees is computed on claimed paths'
    expect:
      exit: 0
      stdout_contains: ['t-']
then:
  - 'status is derived from recorded facts and stored nowhere'
  - 'two issues in one wave with overlapping paths are named as serialised'
  - 'the task started carries the scope the issue claims'

Outcome

The order is computed, not remembered. Parallel issues that would collide are named before anyone starts them, and the issue a worker takes is the one the graph says is next.

The scenario

Executed against the real tool, in a repository prepared by plan-model, every time this site is generated. What follows is not a description of what should happen; it is what happened.

given

  • installed, with a canonical project model carrying one milestone and two issues

when

  1. 1majordomus plan validate
  2. 2majordomus plan waves
  3. 3majordomus plan ready
  4. 4majordomus plan blocked
  5. 5majordomus plan next
  6. 6majordomus start I0001 --scope src/I0001

then

  • status is derived from recorded facts and stored nowhere
  • two issues in one wave with overlapping paths are named as serialised
  • the task started carries the scope the issue claims

What the tool did

Evidence of the run this page was generated from: pass, 6 step(s). Output is normalised: the repository's path, timestamps, ids and durations are placeholders; nothing else is edited.

Tested by test/cases/94_use_cases.sh, which runs every scenario and refuses a step whose recorded output is not what it produced.

  1. schemas, references, the DAG and status consistency; a cycle or a dependency on a missing issue is refused by name

    plan validate: 1 milestone(s), 2 issue(s), 0 failure(s), 0 warning(s)
    • exit 0
    • stdout_contains /0 failure/
  2. topological execution waves; issues in one wave that touch the same paths are reported as serialised

    Wave 0
      I0001   READY     Issue I0001
    Wave 1
      I0002   BLOCKED   Issue I0002
    • exit 0
    • stdout_contains /^Wave 0/
    • stdout_contains /I0001 +READY/
    • stdout_contains /^Wave 1/
    • stdout_contains /I0002 +BLOCKED/
  3. issues whose dependencies are all satisfied

    I0001   w0   Issue I0001
        scope: src/I0001
    • exit 0
    • stdout_contains /I0001/
    • stdout_not_contains /I0002/
  4. issues waiting on a dependency, and on which one

    I0002   w1   Issue I0002
        waiting on: I0001
    • exit 0
    • stdout_contains /I0002/
  5. the one issue a worker should take now

    I0001 — Issue I0001
    objective: Do the bounded piece of work called I0001.
    scope:     src/I0001
    profile:   implementation
    
    next: majordomus plan start I0001
    • exit 0
    • stdout_contains /^I0001 /
    • stdout_contains /scope:/
    • stdout_contains /next: majordomus plan start I0001/
  6. the task under the scope the issue names; overlap with other worktrees is computed on claimed paths

    started t-<id>  profile=implementation  scope=src/I0001
    next: majordomus context; checkpoint every 15m; majordomus check before claiming anything
    • exit 0
    • stdout_contains /t-/

Why the tool knows this

The chain from this page to the code: the use case names commands, rules and claims; each rule is dispatched from the registry and each claim names the test that proves it; the scenario above executed the commands. Nothing in this chain is prose about intent.

The rules that make it hold

Guarantees exercised

Related use cases

Computed from what they share: claims, rules, commands, category, applications. Nobody maintains this list.

The moments this answers

Searches the titles and descriptions of every page this site publishes.