{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lwilko.com/schemas/agent-run/v1.json",
  "title": "Agent Run",
  "description": "A single episode in which an autonomous system was set a goal in an environment and left to pursue it. The second `case_type` payload. It exists because four essays recorded episodes that are cases in the ordinary sense, with actors, instruments and an outcome, but which have no jurisdiction, no policy domain and no wave of technocratic thought, and so cannot be filed under the governance payload without emptying that schema of meaning. Sources, professions and record metadata are referenced from the governance schema rather than restated, so both payloads count against one vocabulary.",
  "type": "object",
  "required": [
    "id",
    "name",
    "system",
    "environment",
    "episode",
    "outcome",
    "sources"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Must equal the file's slug. The validator enforces this, since a schema cannot see the filename.",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "aliases": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "uniqueItems": true
    },
    "summary": {
      "type": "string"
    },
    "system": {
      "type": "object",
      "description": "What was under test. Recorded separately from the environment because the same model is run against several environments and the same environment against several models; conflating the two is what makes benchmark results unreproducible.",
      "additionalProperties": false,
      "required": [
        "model"
      ],
      "properties": {
        "model": {
          "type": "string",
          "description": "The model as released, with its version. 'Claude' is not a model; 'Claude Opus 4.6' is."
        },
        "model_confidence": {
          "type": "string",
          "description": "How firmly the run is attributed to that exact version. Separate from the name because a source often identifies the family without the version.",
          "enum": [
            "stated",
            "inferred",
            "unknown"
          ],
          "default": "stated"
        },
        "scaffold": {
          "type": "array",
          "description": "Project slugs for the apparatus the model acted through. The distinction this whole type exists to preserve: apparatus that produced the evidence is not a source that was read.",
          "items": {
            "$ref": "https://lwilko.com/schemas/okf-envelope/v1.json#/$defs/slug"
          },
          "uniqueItems": true
        },
        "tools_available": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "description": "Count of tools exposed to the model. Null where not recorded."
        },
        "memory": {
          "type": "string",
          "description": "How the system carried state across the point where its context was compacted. The single largest measured effect in the CivBench pilot, which is why it is a field rather than a note.",
          "enum": [
            "context-only",
            "external-diary",
            "retrieval",
            "none",
            "other",
            "unknown"
          ]
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "environment": {
      "type": "object",
      "description": "What the system acted on.",
      "additionalProperties": false,
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string"
        },
        "scenario": {
          "type": "string"
        },
        "configuration": {
          "type": "string",
          "description": "Free text for settings that materially change difficulty: speed, map, opponent count, ruleset."
        },
        "seed": {
          "type": [
            "string",
            "null"
          ]
        },
        "harness": {
          "type": "array",
          "description": "Project slugs for the orchestration that ran the episode, as distinct from the scaffold the model acted through.",
          "items": {
            "$ref": "https://lwilko.com/schemas/okf-envelope/v1.json#/$defs/slug"
          },
          "uniqueItems": true
        },
        "deterministic": {
          "type": "boolean",
          "description": "Whether re-running with the same seed reproduces the episode. Usually false, and stating it stops a single run being read as a repeatable result."
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "episode": {
      "type": "object",
      "description": "The extent of the run. Length is recorded in the environment's own unit as well as wall-clock, because neither alone is comparable across environments.",
      "additionalProperties": false,
      "properties": {
        "date": {
          "type": "string",
          "format": "date"
        },
        "steps": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "description": "Length in the environment's native unit."
        },
        "step_unit": {
          "type": "string",
          "description": "What a step is: turns, episodes, messages, commits.",
          "examples": [
            "turns",
            "messages",
            "episodes"
          ]
        },
        "wall_clock_hours": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0
        },
        "tool_calls": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0
        },
        "interventions": {
          "type": "array",
          "description": "Points at which a human altered the run. An unattended run records an empty array, which is a claim, not an omission.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "description"
            ],
            "properties": {
              "at_step": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "description": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              }
            }
          }
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "objective": {
      "type": "object",
      "description": "What the system was asked to do, and what it decided to do about it. Kept apart because the gap between the two is frequently the finding.",
      "additionalProperties": false,
      "properties": {
        "given": {
          "type": "string"
        },
        "strategy_chosen": {
          "type": "string"
        },
        "strategy_source": {
          "type": "string",
          "enum": [
            "specified",
            "model-selected",
            "mixed",
            "unknown"
          ]
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "outcome": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "verdict"
      ],
      "properties": {
        "verdict": {
          "type": "string",
          "description": "'environment-defective' is a distinct verdict rather than a species of failure: a run in which the apparatus prevented an action is evidence about the apparatus, and pooling it with genuine agent failure inflates the failure rate.",
          "enum": [
            "objective-achieved",
            "objective-missed",
            "aborted",
            "environment-defective",
            "inconclusive",
            "ongoing"
          ]
        },
        "verdict_reasoning": {
          "type": "string"
        },
        "terminal_state": {
          "type": "string"
        },
        "margin": {
          "type": "string",
          "description": "How close the run came, in the environment's terms. Free text, because the unit differs by environment."
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "failures": {
      "type": "array",
      "description": "What went wrong, classified so that runs can be compared. The vocabulary is deliberately short: a taxonomy invented ahead of the runs that would populate it is a guess.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "kind",
          "description"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "plan-not-executed",
              "attention-narrowed",
              "context-lost",
              "tool-unavailable",
              "environment-defect",
              "objective-misread",
              "unsafe-action",
              "other"
            ]
          },
          "description": {
            "type": "string"
          },
          "at_step": {
            "type": [
              "integer",
              "null"
            ]
          },
          "evidence": {
            "type": "string",
            "description": "Preferably the system's own words. A failure asserted without them is an interpretation."
          },
          "attributable_to": {
            "type": "string",
            "description": "Whether the fault lies with the system under test or with the apparatus around it. Recording 'unclear' is preferred to resolving it by assumption.",
            "enum": [
              "system",
              "environment",
              "harness",
              "objective",
              "unclear"
            ]
          }
        }
      }
    },
    "produced_findings": {
      "type": "array",
      "description": "Finding slugs this run contributed to. A run is not itself a measurement; the measurement is the Finding, and this records the relationship rather than duplicating the number.",
      "items": {
        "$ref": "https://lwilko.com/schemas/okf-envelope/v1.json#/$defs/slug"
      },
      "uniqueItems": true
    },
    "related_cases": {
      "type": "array",
      "description": "Other case slugs, of any case_type. Referenced from the governance payload rather than restated, on the same rule as sources and record_meta: the relationship vocabulary is defined once, so a reader comparing an agent run with a governance case is comparing like with like.",
      "items": {
        "$ref": "https://lwilko.com/schemas/technocracy-case-study/v1.json#/$defs/relatedCase"
      }
    },
    "contested_claims": {
      "type": "array",
      "description": "Points on which the record's own sources disagree, or on which the author's reading is open to challenge. Same purpose as the governance payload's field of the same name.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "claim"
        ],
        "properties": {
          "claim": {
            "type": "string"
          },
          "note": {
            "type": "string"
          }
        }
      }
    },
    "sources": {
      "type": "array",
      "description": "Where the record's claims come from. At least one required, on the same principle as the governance payload: an incomplete record is acceptable, an unsourced one is not.",
      "minItems": 1,
      "items": {
        "$ref": "https://lwilko.com/schemas/technocracy-case-study/v1.json#/$defs/source"
      }
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "uniqueItems": true
    },
    "record_meta": {
      "$ref": "https://lwilko.com/schemas/technocracy-case-study/v1.json#/$defs/recordMeta"
    }
  },
  "additionalProperties": false
}
