Skip to content

Structured Output Schema

For: developers and analysts consuming the JSON output.

The pipeline emits two machine-readable documents:

  • audit.filled.json — the evidence and judgments for one run.
  • scores.json — the deterministic result.

Schemas:

The scorer is the executable validator; the JSON Schemas describe the contract for downstream tools. If the two disagree, fix the scorer and the schema together.

Versioning

Field Meaning
schema_version Shape of the audit/scores document (2.0)
rubric_version Meaning of the checks and weights (2.0.0)
collector_version Collector that produced the run
scorer_version Scorer that produced scores.json
run_id Immutable run identifier (YYYY-MM-DDTHHMM)

A schema change that breaks consumers requires a major version. A weight change requires a minor rubric version. Wording-only changes can be a patch.

audit.filled.json

{
  "schema_version": "2.0",
  "framework": "revenue-leak",
  "meta": {
    "client": "Example Co.",
    "slug": "example",
    "url": "https://example.com/",
    "date": "2026-10-26",
    "city": "San Diego, CA",
    "service": "plumbing",
    "run_id": "2026-10-26T1000",
    "run_timestamp": "2026-10-26T10:00:00Z",
    "rubric_version": "2.0.0",
    "collector_version": "2.0.0",
    "configuration": {
      "preferredLanguages": ["en"],
      "optionalChecks": {
        "language_access": false,
        "sms": false,
        "chat_callback": false,
        "after_hours": true,
        "licensing": true
      },
      "excludedChecks": []
    }
  },
  "checks": {
    "RL-UND-01": {
      "score": 2,
      "evidence": ["M-01: hero names the brand but not the service."],
      "confidence": "verified",
      "applicable": true
    },
    "RL-UND-08": {
      "score": null,
      "evidence": [],
      "confidence": "not_applicable",
      "applicable": false,
      "na_reason": "multilingual access not configured for this market"
    }
  },
  "caps": {
    "no_contact": false,
    "primary_contact_broken": false,
    "form_unusable": false,
    "booking_failure": false,
    "mobile_unusable": false,
    "https_failure": false,
    "malicious_redirect": false,
    "unclear_offer": false
  },
  "topLeaks": [
    {
      "title": "No observable immediate acknowledgement",
      "confidence": "strong_signal",
      "checkId": "RL-RSP-01",
      "stage": "response"
    }
  ],
  "ownerData": []
}

checks[]

Every rubric item appears exactly once.

Field Type Notes
score integer or null Must be in the item's allowed set when applicable; null when N/A
evidence array of strings Required when applicable; screenshot IDs, source citations, path traces
confidence string verified or strong_signal when applicable; not_applicable when N/A
applicable boolean Must agree with the configuration
na_reason string Required when N/A
needs_review boolean Must not be true in a delivered filled audit

topLeaks[]

Optional but recommended. Used by the report and verifier.

Field Type Notes
title string Contractor-facing
confidence string verified, strong_signal, owner_data_required, not_applicable
checkId string Present for verified/strong-signal leaks
ownerDataId string Present for owner-data leaks
stage string Journey stage ID

ownerData[]

Optional notes from the owner. The full question library lives in the rubric. Owner-data notes never affect the score.

scores.json

{
  "schema_version": "2.0",
  "framework": "revenue-leak",
  "rubric_version": "2.0.0",
  "scorer_version": "2.0.0",
  "meta": {"client": "Example Co.", "date": "2026-10-26"},
  "categories": [
    {
      "id": "A",
      "name": "Understand",
      "earned": 13,
      "max": 20,
      "applicable_max": 18,
      "normalized": 14.44,
      "applicable": true,
      "percent": 72.2
    }
  ],
  "checks": [
    {
      "id": "RL-UND-01",
      "title": "Service clarity",
      "category": "A",
      "stage": "understanding",
      "max": 4,
      "score": 2,
      "applicable": true,
      "confidence": "verified",
      "evidence": ["M-01"],
      "evaluation": "model_judgment",
      "severity": "critical",
      "serviceMapping": "revenue_recovery"
    }
  ],
  "findings": [],
  "verifiedFindings": [],
  "strongSignals": [],
  "ownerDataRequired": [],
  "journey": [],
  "coverage": [],
  "topLeaks": [],
  "normalization": {"method": "applicability_aware_category_normalization", "applicable_weight": 100, "raw_total": 68.14, "na_checks": []},
  "total": 68.1,
  "final": 68.1,
  "display": 68,
  "total_max": 100,
  "percent": 68.1,
  "cap": 100,
  "cap_active": false,
  "cap_binding": false,
  "caps": [],
  "band": "C",
  "band_label": "Average",
  "recoverable": []
}

Key fields

Field Meaning
total Normalized score before caps, one decimal
final Score after caps, one decimal
display Integer shown in the report; bands use this
categories[].earned Raw points earned in the category
categories[].applicable_max Raw points available after N/A exclusions
categories[].normalized Category weight × earned ÷ applicable max
normalization.applicable_weight Sum of category weights with applicable checks
normalization.na_checks IDs excluded because the module is not applicable
ownerDataRequired Owner-data questions; never scored
journey Stage status and observable score
coverage Check → stage → revenue-leak category → evidence → evaluation → applicability → severity → recommended intervention → service mapping
recoverable Applicable checks with lost points, sorted by lost points
cap_binding True only when the cap actually reduced the score

Evidence format

Evidence is an array of strings. Each string should be one of:

  • A screenshot ID plus a short observation: M-01: the hero names the brand but not the service.
  • A source citation: title: "Example Plumbing"; meta: "Plumbing in Example City".
  • A DOM fact: form fields: 9 visible; no labels.
  • A path trace: book: scheduler empty; no appointment selected.
  • A Lighthouse fact: mobile LCP median 3.1 s across 3 runs.

Do not put vague claims in evidence. If a human cannot verify the statement from the cited artifact, it is not evidence.

content.json (report prose)

The renderer owns tables and placeholders; the model writes prose in content.json.

Field Purpose
client, url, trade, market, date Report identity
verdict One sentence the owner will repeat
leaks[] title, stage, what, evidence, why, fix, confidence
strengths[] What is already working
fixes[] fix, checks[], points, effort
fixNote Short note on the first fixes
journey[] stage, status, summary for the full report
journeyOnePage[] Optional shorter journey table for the one-pager
ownerData[] Selected owner-data opportunities (title, stage, why, questions)
findings[] id, observed, fix for the full report table
executiveSummary[] Full-report bullets
evidenceNote What evidence exists and what is synthetic/limited
fullReportLink Relative link from the one-pager to the full report (default full-report.md)
footer Attribution and method note

Downstream use

A downstream tool can consume scores.json to:

  • render a report,
  • load a live teardown,
  • prioritize fixes,
  • map findings to a service offering,
  • compare runs by rubric version.

It must not treat owner-data questions as website failures. It must not compare a V1 score with a V2 score.


Next: Development — tests, checks, and extension points.