{
  "$id": "https://datapce.com/readout-v0.schema.json",
  "title": "datapce readout v0",
  "description": "One readout = what coding agents did in one period on one contributor's machines, as counts, enums, labels and short checked sentences. No command text, no source code, no personal data. Each field description starts with its use: H = harness eval, M = model label or feature, P = public aggregate. Intake (PLANNED) will be a pull request that adds one readout file; not by e-mail.",
  "type": "object",
  "required": [
    "readout_version",
    "id",
    "created",
    "contributor",
    "scope",
    "claims",
    "privacy"
  ],
  "additionalProperties": false,
  "properties": {
    "readout_version": {
      "description": "H M P. Schema version.",
      "const": "0"
    },
    "id": {
      "description": "H M P. Random ID that the contributor makes. Must not hold a name, a host or a repo.",
      "type": "string",
      "pattern": "^[a-z0-9-]{8,64}$"
    },
    "created": {
      "description": "P. Date the readout was made (UTC).",
      "type": "string",
      "format": "date"
    },
    "contributor": {
      "description": "P. Terms of the contribution. No e-mail, no person name, no employer name.",
      "type": "object",
      "required": [
        "license",
        "aggregate_ok"
      ],
      "additionalProperties": false,
      "properties": {
        "handle": {
          "description": "P. Optional pseudonym, lower case.",
          "type": "string",
          "pattern": "^[a-z0-9-]{2,32}$"
        },
        "license": {
          "description": "P. License of the readout data. One value only (intake design, gap G2).",
          "enum": [
            "CDLA-Permissive-2.0"
          ]
        },
        "aggregate_ok": {
          "description": "P. true = the project may publish this readout in public aggregates. A public aggregate cell shows a value only when 5 or more contributors give to it; else it shows nothing.",
          "type": "boolean"
        },
        "uses": {
          "description": "P. Optional uses of the readout. Each is false unless the contributor sets it to true (intake design, gap G1).",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "train": {
              "description": "P. true = the project may train its models on this readout.",
              "type": "boolean",
              "default": false
            },
            "publish_weights": {
              "description": "P. true = the project may publish weights trained on this readout.",
              "type": "boolean",
              "default": false
            },
            "hosted_api": {
              "description": "P. true = the project may send this readout to a hosted model API.",
              "type": "boolean",
              "default": false
            },
            "show_handle": {
              "description": "P. true = the project may show the handle next to this readout in public aggregates.",
              "type": "boolean",
              "default": false
            }
          }
        }
      }
    },
    "scope": {
      "description": "H P. What the readout covers.",
      "type": "object",
      "required": [
        "period",
        "agents",
        "developers"
      ],
      "additionalProperties": false,
      "properties": {
        "period": {
          "$ref": "#/$defs/period"
        },
        "agents": {
          "description": "H P. Agent products and versions, for example claude-code 2.1.301.",
          "type": "array",
          "minItems": 1,
          "maxItems": 10,
          "items": {
            "type": "object",
            "required": [
              "name"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "pattern": "^[a-z0-9.-]{1,40}$"
              },
              "version": {
                "type": "string",
                "maxLength": 40,
                "pattern": "^v?[0-9][0-9A-Za-z.+_-]*$"
              }
            }
          }
        },
        "models": {
          "description": "H M. Model IDs that the agents used.",
          "type": "array",
          "maxItems": 20,
          "items": {
            "type": "string",
            "maxLength": 60,
            "pattern": "^(?!.*[A-Za-z0-9-]\\.[A-Za-z]{2,})(?!.*\\b[0-9]{1,3}(?:\\.[0-9]{1,3}){3}\\b)[A-Za-z0-9][A-Za-z0-9._:-]*$"
          }
        },
        "developers": {
          "description": "P. Number of developers in the period.",
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "claims": {
      "description": "H P. Each statement of the readout, with its evidence label. The readout shows a fact, a derived number with its formula, or an empty state. It never estimates.",
      "type": "array",
      "minItems": 1,
      "maxItems": 50,
      "items": {
        "$ref": "#/$defs/claim"
      }
    },
    "decisions": {
      "description": "H P. Permission decisions on record, as counts.",
      "type": "object",
      "required": [
        "tool_calls",
        "on_record",
        "rule_recorded",
        "evidence"
      ],
      "additionalProperties": false,
      "properties": {
        "tool_calls": {
          "description": "H P. Tool calls in the period.",
          "type": "integer",
          "minimum": 0
        },
        "on_record": {
          "description": "H P. Calls with a decision on record (rejected, denied or asked), by decision source.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "person": {
              "type": "integer",
              "minimum": 0
            },
            "classifier": {
              "type": "integer",
              "minimum": 0
            },
            "rule": {
              "type": "integer",
              "minimum": 0
            },
            "hook": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "rule_recorded": {
          "description": "H P. Decisions on record that name the deciding rule.",
          "type": "integer",
          "minimum": 0
        },
        "evidence": {
          "$ref": "#/$defs/evidence",
          "unevaluatedProperties": false
        }
      }
    },
    "links": {
      "description": "H P. Change-chain link counts: commit -> agent session -> policy -> deployment -> review.",
      "type": "object",
      "required": [
        "commits",
        "commit_session",
        "session_policy",
        "evidence"
      ],
      "additionalProperties": false,
      "properties": {
        "commits": {
          "description": "H P. Commits in the population.",
          "type": "integer",
          "minimum": 0
        },
        "commit_session": {
          "$ref": "#/$defs/link_counts"
        },
        "session_policy": {
          "$ref": "#/$defs/link_counts"
        },
        "commit_deployment": {
          "$ref": "#/$defs/link_counts"
        },
        "commit_review": {
          "$ref": "#/$defs/link_counts"
        },
        "evidence": {
          "$ref": "#/$defs/evidence",
          "unevaluatedProperties": false
        }
      }
    },
    "tasks": {
      "description": "M H. One row per agent task, with an outcome label. Rows feed the outcome and next-action models.",
      "type": "array",
      "maxItems": 1000,
      "items": {
        "$ref": "#/$defs/task"
      }
    },
    "privacy": {
      "description": "H P. Intake gate. A readout with any other value is rejected.",
      "type": "object",
      "required": [
        "command_text",
        "source_code",
        "personal_data",
        "third_party_data",
        "ids"
      ],
      "additionalProperties": false,
      "properties": {
        "command_text": {
          "const": false
        },
        "source_code": {
          "const": false
        },
        "personal_data": {
          "const": false
        },
        "third_party_data": {
          "const": false
        },
        "ids": {
          "description": "How session, task and commit IDs were removed or replaced.",
          "enum": [
            "none-included",
            "random",
            "salted-hash"
          ]
        }
      }
    }
  },
  "$defs": {
    "date": {
      "type": "string",
      "format": "date"
    },
    "period": {
      "description": "H P. First and last day, UTC.",
      "type": "object",
      "required": [
        "start",
        "end"
      ],
      "additionalProperties": false,
      "properties": {
        "start": {
          "$ref": "#/$defs/date"
        },
        "end": {
          "$ref": "#/$defs/date"
        }
      }
    },
    "label": {
      "description": "H P. Status of the check behind the claim (evidence-labels skill).",
      "enum": [
        "PASS",
        "FAIL",
        "PARTIAL",
        "BLOCKED",
        "INCONCLUSIVE",
        "STALE",
        "ASSUMED",
        "N/A",
        "WAIVED"
      ]
    },
    "evidence": {
      "description": "H P. Evidence for one claim or one block.",
      "type": "object",
      "required": [
        "label",
        "basis",
        "source",
        "as_of",
        "reviewed"
      ],
      "properties": {
        "label": {
          "$ref": "#/$defs/label"
        },
        "basis": {
          "description": "H P. measured = counted from records; derived = formula on other claims; reported = copied from an earlier readout or file; synthetic = made by a simulation; illustrative = not data.",
          "enum": [
            "measured",
            "derived",
            "reported",
            "synthetic",
            "illustrative"
          ]
        },
        "source": {
          "description": "H P. Which records and which tool, in words. No path, no host. No slash, command flag, address or shell sign.",
          "type": "string",
          "maxLength": 200,
          "pattern": "^(?!(?:.*\\s)?--?[A-Za-z])(?!.*[A-Za-z0-9-]\\.[A-Za-z]{2,})(?!.*\\b[0-9]{1,3}(?:\\.[0-9]{1,3}){3}\\b)(?!.*[/\\\\~@`$])[^\\n\\r\\t]+$"
        },
        "as_of": {
          "$ref": "#/$defs/date"
        },
        "reviewed": {
          "description": "H P. none = only the tool that made it; self = the contributor checked it; independent = a second person or model checked it.",
          "enum": [
            "none",
            "self",
            "independent"
          ]
        }
      }
    },
    "claim": {
      "type": "object",
      "required": [
        "id",
        "text",
        "label",
        "basis",
        "source",
        "as_of",
        "reviewed"
      ],
      "unevaluatedProperties": false,
      "allOf": [
        {
          "$ref": "#/$defs/evidence"
        },
        {
          "if": {
            "properties": {
              "basis": {
                "const": "derived"
              }
            }
          },
          "then": {
            "required": [
              "formula",
              "value"
            ]
          }
        }
      ],
      "properties": {
        "id": {
          "description": "H P. c1, c2 and so on.",
          "type": "string",
          "pattern": "^c[0-9]{1,3}$"
        },
        "text": {
          "description": "P. The claim in one sentence. No slash, command flag, path, host, address or shell sign.",
          "type": "string",
          "maxLength": 280,
          "pattern": "^(?!(?:.*\\s)?--?[A-Za-z])(?!.*[A-Za-z0-9-]\\.[A-Za-z]{2,})(?!.*\\b[0-9]{1,3}(?:\\.[0-9]{1,3}){3}\\b)(?!.*[/\\\\~@`$])[^\\n\\r\\t]+$"
        },
        "value": {
          "description": "H P. Main number of the claim.",
          "type": "number"
        },
        "unit": {
          "description": "P. Unit of value. No slash: write per.",
          "type": "string",
          "maxLength": 30,
          "pattern": "^(?!.*[A-Za-z0-9-]\\.[A-Za-z]{2,})(?!.*\\b[0-9]{1,3}(?:\\.[0-9]{1,3}){3}\\b)[A-Za-z0-9%][A-Za-z0-9 %.-]*$"
        },
        "formula": {
          "description": "H P. Formula over other claims or fields. Required when basis is derived. Write division with spaces: a / b.",
          "type": "string",
          "maxLength": 200,
          "pattern": "^(?!.*\\.(?:com|org|net|io|dev|ai|app|co|uk|de|eu|local|internal|lan|home|corp|me|info|edu|gov)\\b)(?!.*\\b[0-9]{1,3}(?:\\.[0-9]{1,3}){3}\\b)(?!.*[A-Za-z0-9_)]/)(?!.*/[A-Za-z0-9_(])[A-Za-z0-9_ ().,+*/<>=%-]+$"
        },
        "period": {
          "$ref": "#/$defs/period"
        }
      }
    },
    "link_counts": {
      "description": "H P. Commits by link label (change-chain).",
      "type": "object",
      "required": [
        "ESTABLISHED",
        "INFERRED",
        "MISSING"
      ],
      "additionalProperties": false,
      "properties": {
        "ESTABLISHED": {
          "type": "integer",
          "minimum": 0
        },
        "INFERRED": {
          "type": "integer",
          "minimum": 0
        },
        "MISSING": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "task": {
      "type": "object",
      "required": [
        "date",
        "agent",
        "tool_calls",
        "errors",
        "outcome",
        "outcome_by"
      ],
      "additionalProperties": false,
      "properties": {
        "date": {
          "$ref": "#/$defs/date"
        },
        "agent": {
          "description": "H M. Agent name from scope.agents.",
          "type": "string",
          "pattern": "^[a-z0-9.-]{1,40}$"
        },
        "task_type": {
          "description": "M H. Router task class.",
          "enum": [
            "explore",
            "review",
            "generate",
            "debug",
            "other"
          ]
        },
        "tier": {
          "description": "M H. Model tier that ran the task.",
          "type": "string",
          "maxLength": 30,
          "pattern": "^[a-z][a-z0-9-]*$"
        },
        "tool_calls": {
          "description": "M. Feature.",
          "type": "integer",
          "minimum": 0
        },
        "errors": {
          "description": "M. Feature: tool calls that returned an error.",
          "type": "integer",
          "minimum": 0
        },
        "actions": {
          "description": "M. Optional action shape, one letter per tool call: R read, S search, E edit, B shell, W web, A agent spawn, O other. No arguments.",
          "type": "string",
          "pattern": "^[RSEBWAO]{0,500}$"
        },
        "votes": {
          "description": "M. Rule voters that fired, each with its vote.",
          "type": "object",
          "propertyNames": {
            "enum": [
              "commit",
              "tests",
              "next_positive",
              "next_negative",
              "interrupted",
              "tail_errors",
              "repeated"
            ]
          },
          "additionalProperties": {
            "enum": [
              "success",
              "partial",
              "fail"
            ]
          }
        },
        "outcome": {
          "description": "M H. Outcome label.",
          "enum": [
            "success",
            "partial",
            "fail",
            "unknown"
          ]
        },
        "outcome_by": {
          "description": "M. Who set the outcome: person = gold label; judge = an LLM judge; rules = rule voters only; none = no label.",
          "enum": [
            "person",
            "judge",
            "rules",
            "none"
          ]
        },
        "judge_confidence": {
          "description": "M. Confidence of the judge, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      }
    }
  },
  "$comment": "Gaps G1 (contributor.uses), G2 (licence enum narrowed to CDLA-Permissive-2.0) and G3 (pull request intake only, not by e-mail) applied on 2026-10-21. Owner approval of G1-G3 is pending (readout RECOMMENDATION, decision 12). No $schema key: build.py allows only datapce.com URLs."
}
