agentic examples

The Cancel Drill

The Cancel Drill: structured concurrency's core promise is that cancellation is PROMPT - stop means stop, not "finish everything and then agree you'd stopped". Three drills measure what each cancel path actually delivers. In round 10 this drill caught plan-wide cancel billing for every canceled task; the round-11 release fixed it, and this file is the acceptance test that keeps it fixed.

Testing & Verification Round 10 Samuel Williams exit 0

source on github

bundle exec ruby examples/cancel_drill.rb

a real captured run

CANCEL DRILL (6 jobs of 100ms, 2 lanes; full plan = 300ms)

  drill 1 - cancel ONE in-flight task (at 30ms):
    5 completed, 1 canceled; plan finished in 311ms
    the proof the lane was freed is WHEN the next job started:
    job2 began at 41ms - on the canceled fiber's lane,
    immediately - not at 100ms when that job would have finished.

  drill 2 - cancel ONE pending task:
    5 completed, 1 canceled; agents actually ran: 5/6
    the canceled job never started and never billed. queued work
    canceled is money returned.

  drill 3 - cancel_plan at 30ms:
    status flipped to :canceled by 35ms, the plan returned in 35ms,
    and only 2/6 agents ever ran (6 canceled) - the two that
    were mid-flight when the order came. before round 11 this row
    read "301ms, 6/6 agents executing": every task reported
    :canceled while every agent ran to completion and billed.

  the drill's verdict, updated: all three cancel paths now keep
  the structured-concurrency promise. the round-11 fix stops the
  fibers instead of the reactor handle - and does its bookkeeping
  FIRST, because stopping a fiber frees its slot and synchronously
  admits the next waiter, which must already read as canceled in
  that instant. cancellation is a race against your own scheduler;
  this drill is the finish-line camera, and it stays in the repo
  so the race gets re-run on every change.

source

# frozen_string_literal: true

# The Cancel Drill: structured concurrency's core promise is that
# cancellation is PROMPT - stop means stop, not "finish everything
# and then agree you'd stopped". Three drills measure what each
# cancel path actually delivers. In round 10 this drill caught
# plan-wide cancel billing for every canceled task; the round-11
# release fixed it, and this file is the acceptance test that keeps
# it fixed.
#
#   bundle exec ruby examples/cancel_drill.rb
#
# Runs offline; every claim below is a measurement.

require class="s">"bundler/setup"
require class="s">"agentic"
require class="s">"async"

Agentic.logger.level = class="y">:fatal

JOB = 0.1

def build(count, agent_runs)
  orchestrator = Agentic:class="y">:PlanOrchestrator.new(concurrency_limit: 2)
  epoch = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC)
  tasks = count.times.map { |i|
    Agentic:class="y">:Task.new(description: class="s">"job#{i}", agent_spec: {class="s">"name" => class="s">"w", class="s">"instructions" => class="s">"w"})
  }
  tasks.each do |task|
    orchestrator.add_task(task, agent: ->(_t) {
      agent_runs << [task.description, Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC) - epoch]
      sleep(JOB)
      class="y">:ok
    })
  end
  [orchestrator, tasks]
end

def states(orchestrator)
  orchestrator.instance_variable_get(:@execution_state).transform_values(&class="y">:size)
    .reject { |_, v| v.zero? }.map { |k, v| class="s">"#{v} #{k}" }.join(class="s">", ")
end

puts class="s">"CANCEL DRILL (6 jobs of #{(JOB * 1000).to_i}ms, 2 lanes; full plan = 300ms)"
puts

# --- drill 1: surgical cancel of one IN-FLIGHT task ---------------------------
runs = []
orchestrator, tasks = build(6, runs)
elapsed = nil
Sync do
  runner = Async { orchestrator.execute_plan }
  Async do
    sleep(0.03) # job0 and job1 are mid-sleep
    orchestrator.cancel_task(tasks[0].id)
  end
  started = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC)
  runner.wait
  elapsed = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC) - started
end
third_start = (runs[2][1] * 1000).round
puts class="s">"  drill 1 - cancel ONE in-flight task (at 30ms):"
puts class="s">"    #{states(orchestrator)}; plan finished in #{(elapsed * 1000).round}ms"
puts class="s">"    the proof the lane was freed is WHEN the next job started:"
puts class="s">"    #{runs[2][0]} began at #{third_start}ms - on the canceled fiber's lane,"
puts class="s">"    immediately - not at 100ms when that job would have finished."
puts

# --- drill 2: surgical cancel of one PENDING task ------------------------------
runs2 = []
orchestrator2, tasks2 = build(6, runs2)
Sync do
  runner = Async { orchestrator2.execute_plan }
  Async do
    sleep(0.03)
    orchestrator2.cancel_task(tasks2[5].id) # still queued behind the lanes
  end
  runner.wait
end
puts class="s">"  drill 2 - cancel ONE pending task:"
puts class="s">"    #{states(orchestrator2)}; agents actually ran: #{runs2.size}/6"
puts class="s">"    the canceled job never started and never billed. queued work"
puts class="s">"    canceled is money returned."
puts

# --- drill 3: cancel_plan mid-flight -------------------------------------------
runs3 = []
orchestrator3, = build(6, runs3)
flip_ms = wall = nil
Sync do
  started = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC)
  runner = Async { orchestrator3.execute_plan }
  Async do
    sleep(0.03)
    orchestrator3.cancel_plan
    flip_ms = ((Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC) - started) * 1000).round
  end
  runner.wait
  wall = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC) - started
end
puts class="s">"  drill 3 - cancel_plan at 30ms:"
puts class="s">"    status flipped to class="y">:canceled by #{flip_ms}ms, the plan returned in #{(wall * 1000).round}ms,"
puts class="s">"    and only #{runs3.size}/6 agents ever ran (#{states(orchestrator3)}) - the two that"
puts class="s">"    were mid-flight when the order came. before round 11 this row"
puts class="s">"    read \"301ms, 6/6 agents executing\class="s">": every task reported"
puts class="s">"    class="y">:canceled while every agent ran to completion and billed."
puts
puts class="s">"  the drill's verdict, updated: all three cancel paths now keep"
puts class="s">"  the structured-concurrency promise. the round-11 fix stops the"
puts class="s">"  fibers instead of the reactor handle - and does its bookkeeping"
puts class="s">"  FIRST, because stopping a fiber frees its slot and synchronously"
puts class="s">"  admits the next waiter, which must already read as canceled in"
puts class="s">"  that instant. cancellation is a race against your own scheduler;"
puts class="s">"  this drill is the finish-line camera, and it stays in the repo"
puts class="s">"  so the race gets re-run on every change."