Layer 1 Schema

Layer 1 of the design is regarding the description of a single atom of computation.

(Refer to the Design chapter if further contextualization is required.)


The key concepts at Layer 1 are the Formula and the RunRecord.

# Recall we have the following types
#  already defined from Layer 0:
#  - AbsPath
#  - WareID
#  - PackType
#  - PackFilter

# You may think of a Formula as a
# fully-curried function.
# It has zero unbound arguments,
# and is ready to invoke.
# Evaluating a Formula yields a RunRecord.
struct Formula = {
    inputs {AbsPath:WareID}
    action struct = {
        exec [string]
        cwd optional string
        userinfo optional struct = {
            uid optional int
            gid optional int
            username optional string
            homedir optional AbsPath
    outputs {AbsPath:OutputSpec}

struct OutputSpec = {
    packtype PackType
    filter optional PackFilter

struct RunRecord = {
    guid string
    time int
    formulaID string
    exitcode int
    results {AbsPath:WareID}

example formula

This is a concrete example of a formula, in JSON format:

  "formula": {
    "inputs": {
      "/": "tar:6q7G4hWr283FpTa5Lf8heVqw9t97b5VoMU6AGszuBYAz9EzQdeHVFAou7c4W9vFcQ6"
    "action": {
      "exec": ["/bin/mkdir", "-p", "/task/out/beep"]
    "outputs": {
      "/task/out": {"packtype": "tar"}
  "context": {
    "fetchUrls": {
      "/": [

As you can see, this Formula has only a single input, and lists a single output. The output will be packed into a tar format, and when we evaluate the formula, we’ll expect the resultant RunRecord to contain one value in the results map corresponding to this output we requests.

This is the RunRecord that should be produced:

    "guid": "cyrw3c3f-k9hag7xm-53wcy9b5",
    "time": 1544875520,
    "formulaID": "9mb9Nixx2M5FoxVJgQtYzn1QvtQdM1TZjZeC4QGSjUCXbHVdAD3v91JWPjZXGkTKD6",
    "exitCode": 0,
    "results": {
        "/task/out": "tar:729LuUdChuu7traKQHNVAoWD9AjmrdCY4QUquhU6sPeRktVKrHo4k4cSaiQ523Nn4D"

Note that since there are no "saveUrls" specified in the context, no tar file was actually emitted; the data was only hashed (and then effectively routed to /dev/null). You can add a context.saveUrls map to change this.