anchor.diff:  }
   ....
   
  -The `status` field records the state of the state machine (below) the
  -slot is in.
  +The `status` field records the state the slot is in.
   
   The `externalID` field contains the Oozie ID of the corresponding
   Oozie workflow execution if the slot is running, successful, or failed
  
positive.code: defineWordCountWorkflow("lax");
  ....
  
  A Celos workflow consists of a number of configurable parts:
  
  * The workflow's *schedule* determines the points in time (called *slots*) at which the workflow should run, and is expressed with a `cron`-like syntax.
  
  * For each slot, the workflow's *trigger* determines whether the slot is ready to run.  For example, it can check for the existence of a file in HDFS, or the success of another workflow.  Triggers can also be combined with AND, OR, and NOT.  We'll see examples shortly.
  
  * The workflow's *scheduling strategy* determines when and in which order the ready slots of the workflow should be executed.
  
  image::etc/images/slots.png[Celos concepts]
  
  Celos workflows are defined with JavaScript, and there are expressions
  for creating schedules, triggers, and scheduling strategies.
  
  Here are two examples of schedules:
  
  [source,javascript]
  ....
  // A workflow using this schedule will run every hour
  var hourlySchedule = celos.cronSchedule("0 0 * * * ?");
  // A workflow using this schedule will run every day
  var dailySchedule = celos.cronSchedule("0 0 0 * * ?");
  ....
  
  Triggers form a kind of DSL:
  
  [source,javascript]
  ....
  // A workflow using this trigger will wait for a file /foo in HDFS
  var simpleTrigger = celos.hdfsCheckTrigger("/foo");
  
  // A workflow using this trigger will wait for a file of the form /logs/YYYY-MM-DD/HH-00/_READY in HDFS
  var logsReadyTrigger = celos.hdfsCheckTrigger("/logs/${year}-${month}-${day}/${hour}-00/_READY");
  
  // We can combine triggers with AND, so the workflow will wait for both:
  var multipleFilesReadyTrigger = celos.andTrigger(simpleTrigger, logsReadyTrigger);
  
  // We can wait for the success of another workflow:  A workflow using this trigger will wait until foo becomes succesful
  var fooTrigger = celos.successTrigger("foo");
  
  // A workflow using this trigger will run if workflow foo is not successful after one hour:
  var alertTrigger = celos.andTrigger(celos.delayTrigger(60 * 60),
                                      celos.notTrigger(fooTrigger));
  
  // A workflow using this trigger will wait for this hour's and the next hour's logs
  var twoHoursTrigger = celos.andTrigger(logsReadyTrigger,
                                         celos.offsetTrigger(60 * 60, logsReadyTrigger));
  ....
  
  There's only one scheduling strategy at the moment,
  celos.serialSchedulingStrategy, which executes slots oldest first,
  with a configurable concurrency level.
  
  [source,javascript]
  ....
  // A workflow using this scheduling strategy will execute three slots in parallel:
  var strat = celos.serialSchedulingStrategy(3);
  ....
  
  === How it works
  
negative.code: 
  We're proud that in the years of use, not a single bug in Celos has
  caused any downtime, which is attributable to the small codebase
  (about 2500 non-blank, non-comment lines of code for core Celos, as
  measured by link:http://cloc.sourceforge.net/[cloc] 1.56) and the
  rigorous test suite (hundreds of unit tests and an extensive
  integration test).
  
  == Building & Running Celos
  
  