{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://standards.rootblocks.com/schemas/evidence/evidence.v1.schema.json",
  "title": "RootBlocks Evidence v1.7",
  "$comment": "Additive minor evolution (v1 -> v1.7). The wire compatibility contract is the MAJOR version: `schemaVersion` stays const 'rootblocks.evidence/v1' across every v1.x minor, so consumers pin the major and existing evidence keeps validating. Minors evolve ONLY additively — new OPTIONAL properties and WIDENED enums, never a new required field or a narrowed constraint — which keeps the closed `additionalProperties:false` shape while every document valid under an earlier v1.x stays valid here (each new field is declared, so it is no longer 'additional'). v1.1 adds the optional `assurance` field. v1.2 completes the process-plane `provenance` block into the full seven-link provenance chain and widens `operationType` with `code.merge`. v1.3 adds `auditRefs`, v1.4 adds `profileRefs`, v1.5 adds `sourceAuditRefs` plus generated-source audit artifact kinds, and v1.6 adds optional `extensionRefs` for private component extension usage. v1.7 widens `operationType` with `attest` (metric-attestation receipts: a signed statement that a published metric was measured, by whom and how) and adds two OPTIONAL provenance fields for it — `attestor_datta_dv` (the Datta DV of the human/org making the attestation) and `subject` (the attested claim: metric, value, source system, method, scope, measurement date); both additive, so every v1.0–v1.6 document stays valid. See schemas/evidence/README.md for the fields and the evolution mechanism.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "evidenceId",
    "operationType",
    "status",
    "standard",
    "actor",
    "startedAt",
    "finishedAt",
    "artifacts",
    "checks",
    "redaction"
  ],
  "properties": {
    "schemaVersion": {
      "const": "rootblocks.evidence/v1"
    },
    "evidenceId": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
    },
    "operationType": {
      "enum": [
        "validate",
        "compile",
        "run",
        "debug",
        "regression-run",
        "regression-debug",
        "package",
        "sign",
        "publish",
        "cache-refresh",
        "compat-check",
        "release",
        "infra-plan",
        "infra-apply",
        "cicd-run",
        "code.merge",
        "attest"
      ]
    },
    "status": {
      "enum": ["passed", "failed", "inconclusive", "skipped", "stale", "blocked"]
    },
    "assurance": {
      "description": "Additive in v1.1 (optional; absent = unspecified, which keeps every v1.0 document valid). The strength-of-assurance seal this evidence carries — the four RootBlocks seals, in ascending order: 'observed' (the operation ran and was observed), 'proven' (a deterministic check/regression proved the property), 'traced' (backed by an auditable execution trace / provenance chain), 'enforced' (a gate actively enforced the property, blocking on failure).",
      "enum": ["observed", "proven", "traced", "enforced"]
    },
    "standard": {
      "$ref": "#/$defs/standardRef"
    },
    "actor": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "id"],
      "properties": {
        "type": {
          "enum": ["human", "agent", "tool", "system"]
        },
        "id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        }
      }
    },
    "startedAt": {
      "type": "string",
      "format": "date-time"
    },
    "finishedAt": {
      "type": "string",
      "format": "date-time"
    },
    "artifacts": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/artifact"
      }
    },
    "checks": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/check"
      }
    },
    "traceRefs": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/traceRef"
      }
    },
    "provenance": {
      "description": "Process-plane provenance chain (additive, optional — DEC-007 / ARC-002 §5 row 4). Records how a governed change reached this evidence as the seven-link chain of the YC deck: intent -> decision -> slice -> change -> policy -> review/merge -> agent. Every sub-field is OPTIONAL, so a bare {}, a v1.0/v1.1 block (sliceId/commitSha/sessionRef), and runtime evidence with no provenance all stay valid; process R-rules decide which links are required for slice-emitted evidence. The 'decision' link is the sibling top-level `decisionRefs` (the DEC-007 P5 'decision' category), referenced rather than duplicated here.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "intent": {
          "description": "Link 1 — intent. The business/OKR objective this change serves (the 'why').",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "okrId": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            },
            "objective": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500
            },
            "businessRef": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          }
        },
        "sliceId": {
          "description": "Link 3 — slice (plan). The SliceOps slice this evidence was emitted inside.",
          "$ref": "#/$defs/sliceId"
        },
        "repo": {
          "description": "Link 4 — change (repo). The source repository the change landed in, e.g. 'Rootblocks/rootblocks-standard'.",
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "commitSha": {
          "description": "Link 4 — change (commit). The commit the change produced.",
          "type": "string",
          "pattern": "^[a-f0-9]{7,40}$"
        },
        "pullRequest": {
          "description": "Link 4 — change (PR). The review/merge request reference — a URL or 'org/repo#number'.",
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "policyHash": {
          "description": "Link 5 — execution (policy). Hash of the policy / Standard bundle actually enforced during the operation, pinning the ruleset the change ran under.",
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        },
        "review": {
          "description": "Link 6 — review/merge. Who reviewed the change and how it was merged.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "reviewer": {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            },
            "decision": {
              "enum": ["approved", "changes-requested", "merged", "auto-merged"]
            },
            "reviewedAt": {
              "type": "string",
              "format": "date-time"
            },
            "mergeCommitSha": {
              "type": "string",
              "pattern": "^[a-f0-9]{7,40}$"
            }
          }
        },
        "agent": {
          "description": "Link 7 — agent. The agent identity and model that authored the change — distinct from the operation `actor`, which is the immediate runner of THIS operation.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            },
            "model": {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            }
          }
        },
        "sessionRef": {
          "description": "The authoring session pointer (retained from v1.0).",
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "cost": {
          "description": "Governed-run cost (additive, optional — SPEC-030 / BL-05.SL-013). tokensIn/tokensOut = accumulated model token usage; usd = the agent's own reported price (cache-aware, not re-derived from tokens). Billing/metering input, carried inside the signed bytes so it is tamper-evident for billing.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "tokensIn": { "type": "integer", "minimum": 0 },
            "tokensOut": { "type": "integer", "minimum": 0 },
            "usd": { "type": "number", "minimum": 0 }
          }
        },
        "attestor_datta_dv": {
          "description": "Additive in v1.7. The Datta DV of the human or organization making an attestation (operationType 'attest') — e.g. a founder's personal DV-P or an org DV-B. Mirrors the attest receipt's top-level `actor.id`, kept in the provenance chain as the explicit attestor link. NOTE: the DV<->signing-key binding is INTERIM in v1.7 — the receipt's detached ed25519 signature proves control of the publishing key (whose public half is published out-of-band); the formal DV<->key binding recorded at Datta is a later increment.",
          "type": "string",
          "pattern": "^DV-[0-9A-Z-]{3,64}$"
        },
        "subject": {
          "description": "Additive in v1.7. The claim an `attest` receipt attests: a published metric, its value, the system it was measured in, the method used, the scope, and when it was measured. Metadata only (no source/code payloads); every field is optional and the shape is closed.",
          "$ref": "#/$defs/attestSubject"
        }
      }
    },
    "decisionRefs": {
      "description": "Process-plane decision linkage (additive, optional — DEC-007). Closes the P5 'decision' category: DEC/INS ids this evidence supports or was produced alongside.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/decisionRef"
      }
    },
    "auditRefs": {
      "description": "Additive in v1.3. Structured audit events emitted by validator, packager, signer, distribution, cache, release, RootBlocks Console, BuilderX, or governed agents that support this evidence.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/auditRef"
      }
    },
    "profileRefs": {
      "description": "Additive in v1.4. Architecture profiles used by structured generation or validation without embedding profile payloads.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/profileRef"
      }
    },
    "sourceAuditRefs": {
      "description": "Additive in v1.5. Generated source audit reports and sub-artifacts that connect source manifests, zone manifests, coverage, drift, build trace, and evidence without embedding source.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/sourceAuditRef"
      }
    },
    "extensionRefs": {
      "description": "Additive in v1.6. Private organization, project, or personal component extensions used by this operation.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/extensionRef"
      }
    },
    "redaction": {
      "type": "object",
      "additionalProperties": false,
      "required": ["status", "rules"],
      "properties": {
        "status": {
          "enum": ["applied", "not-needed", "failed"]
        },
        "rules": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    }
  },
  "$defs": {
    "standardRef": {
      "type": "object",
      "additionalProperties": false,
      "required": ["bundleId", "version", "hash"],
      "properties": {
        "bundleId": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "version": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[A-Za-z0-9.-]+)?(\\+[A-Za-z0-9.-]+)?$"
        },
        "hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        }
      }
    },
    "artifact": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "id", "hash"],
      "properties": {
        "kind": {
          "enum": ["project", "workflow", "component", "buildpack", "buildpack-project", "private-extension", "template", "architecture-profile", "compiler-instruction", "structured-project-output", "structured-source-project", "generated-source", "source-audit-report", "source-manifest", "zone-manifest", "source-map-coverage", "regression-coverage", "build-trace", "drift-result", "regression-suite", "source-map", "bundle", "evidence", "infra", "cicd"]
        },
        "id": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "path": {
          "type": "string"
        },
        "hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        }
      }
    },
    "check": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "status", "severity"],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "status": {
          "enum": ["passed", "failed", "warning", "skipped", "blocked"]
        },
        "severity": {
          "enum": ["info", "warning", "error", "critical"]
        },
        "message": {
          "type": "string",
          "maxLength": 1000
        }
      }
    },
    "traceRef": {
      "type": "object",
      "additionalProperties": false,
      "required": ["executionId", "traceHash"],
      "properties": {
        "executionId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "traceHash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        }
      }
    },
    "sliceId": {
      "type": "string",
      "pattern": "^BL-[0-9]{2,}(\\.SEC-[0-9]{2,})?\\.SL-[0-9]{3}[a-z]?$"
    },
    "decisionRef": {
      "type": "string",
      "pattern": "^(DR-[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9][a-z0-9-]*|[A-Z]{2,6}-[0-9]{1,6})$"
    },
    "attestSubject": {
      "description": "The attested claim carried by an `attest` receipt (v1.7). Metadata only — a description of what was measured, never the measured data itself. Closed shape; every field optional so the schema permits partial subjects, while a producer/rule can require the disclosure fields (`method`, `sourceSystem`) for a metric attestation.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "metric": {
          "description": "Machine name of the metric being attested, e.g. 'people_served_unique_individuals'.",
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "value": {
          "description": "The attested value. A number for counts/amounts, or a string for non-numeric values.",
          "type": ["number", "string"]
        },
        "unit": {
          "description": "Optional unit for `value`, e.g. 'individuals', 'transactions', 'USD'.",
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "sourceSystem": {
          "description": "The system of record the value was measured in, e.g. 'insttantt-db-prod (Azure SQL)'. Named so a reader knows WHERE the number came from.",
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "method": {
          "description": "The method used to obtain the value, disclosed so the measurement is reproducible — e.g. a SQL statement or a described counting procedure.",
          "type": "string",
          "minLength": 1,
          "maxLength": 4000
        },
        "scope": {
          "description": "Optional boundary of the measurement — what is included/excluded, e.g. 'since 2020, excludes Hubbec 2016-2019'.",
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "measuredAt": {
          "description": "When the value was measured — an RFC 3339 date ('2026-07-23') or date-time.",
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2}))?$"
        }
      }
    },
    "auditRef": {
      "type": "object",
      "additionalProperties": false,
      "required": ["auditEventId", "operationId"],
      "properties": {
        "auditEventId": {
          "type": "string",
          "pattern": "^audit-event-[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "operationId": {
          "type": "string",
          "pattern": "^op-[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "eventPath": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_./@-]+$"
        },
        "eventHash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        }
      }
    },
    "profileRef": {
      "type": "object",
      "additionalProperties": false,
      "required": ["profileId", "version", "path", "hash"],
      "properties": {
        "profileId": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "version": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[A-Za-z0-9.-]+)?(\\+[A-Za-z0-9.-]+)?$"
        },
        "path": {
          "type": "string",
          "pattern": "^profiles/architecture/.+\\.json$"
        },
        "hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        }
      }
    },
    "sourceAuditRef": {
      "type": "object",
      "additionalProperties": false,
      "required": ["auditId", "path", "hash", "status"],
      "properties": {
        "auditId": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "path": {
          "type": "string",
          "pattern": "^(evidence/.+\\.source-audit\\.(json|yaml|yml)|builderx/(inventory|coverage|drift)/.+\\.(json|yaml|yml))$"
        },
        "hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        },
        "status": {
          "enum": ["passed", "failed", "blocked", "stale"]
        }
      }
    },
    "extensionRef": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "extensionId",
        "scope",
        "ownerId",
        "visibility",
        "version",
        "hash",
        "manifestPath",
        "targetGlobalStandard"
      ],
      "properties": {
        "extensionId": {
          "type": "string",
          "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
        },
        "scope": {
          "enum": ["organization", "project", "personal"]
        },
        "ownerId": {
          "type": "string",
          "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.:-]{1,127}$"
        },
        "visibility": {
          "enum": ["organization-private", "project-local", "personal-private", "shared", "public-candidate"]
        },
        "version": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[A-Za-z0-9.-]+)?(\\+[A-Za-z0-9.-]+)?$"
        },
        "hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64,128}$"
        },
        "manifestPath": {
          "type": "string",
          "pattern": "^golden/extensions/.+\\.private-extension-manifest\\.v1\\.example\\.json$|^extensions/.+\\.private-extension\\.(json|yaml|yml)$"
        },
        "targetGlobalStandard": {
          "$ref": "#/$defs/standardRef"
        },
        "componentHashes": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["componentId", "hash"],
            "properties": {
              "componentId": {
                "type": "string",
                "pattern": "^[a-z0-9][a-z0-9.-]{2,127}$"
              },
              "hash": {
                "type": "string",
                "pattern": "^[a-f0-9]{64,128}$"
              }
            }
          }
        }
      }
    }
  }
}
