{
  "createdAt": "2026-10-19T02:27:01.300060+00:00",
  "pullRequest": "https://github.com/OpenHands/OpenHands/pull/18641",
  "title": "Status colors: same colors, named classes",
  "productRevisions": {
    "before": "83c9b64af66fae23a64aa07de6a3706cdab1144c",
    "after": "6e93317744f6bbd07ab0c7af7512a9d452c2603e"
  },
  "verificationHarness": {
    "beforeCommit": "743f204fd4c845a93d11fff3f8b973c65ecd6ade",
    "afterCommit": "6e93317744f6bbd07ab0c7af7512a9d452c2603e",
    "note": "The before harness includes only a verification launcher memory-accounting repair. Product source is identical to 83c9b64af6; the default 2000 MB guard was retained with no override."
  },
  "captureSetup": {
    "app": "Real production Agent Canvas builds",
    "backend": "Local Agent Server 1.55.1",
    "sdk": "1.55.1",
    "automation": "1.20.1",
    "browser": "Google Chrome through control-openhands browser record",
    "viewport": {
      "width": 1440,
      "height": 1000
    },
    "themesShown": [
      "OpenHands-Neutral",
      "Light+"
    ],
    "fixture": "Disposable qa-lint-status git repository, actual README diff +3/-1"
  },
  "movie": {
    "seconds": 26.08,
    "size": {
      "width": 1280,
      "height": 720
    },
    "videoCodec": "H.264",
    "audioCodec": "AAC",
    "pixelFormat": "yuv420p",
    "streaming": "faststart"
  },
  "chapters": [
    {
      "chapter": "Diff counts",
      "phase": "Before",
      "input": "before-diff-counts.mp4",
      "sourceStartSeconds": 0,
      "sourceCrop": {
        "x": 1172,
        "y": 48,
        "width": 260,
        "height": 140
      },
      "outputScale": {
        "width": 780,
        "height": 420
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "e17c198f4a2fcef8c1e6ecb30bb00db55c06eb4589c9e0e5034720a131dfd138"
    },
    {
      "chapter": "Diff counts",
      "phase": "After",
      "input": "after-diff-counts.mp4",
      "sourceStartSeconds": 0,
      "sourceCrop": {
        "x": 1172,
        "y": 48,
        "width": 260,
        "height": 140
      },
      "outputScale": {
        "width": 780,
        "height": 420
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "46a6bee36ae5151a75604354bf371a8907c08f84554b987668a2a25c346bfeac"
    },
    {
      "chapter": "Error toast",
      "phase": "Before",
      "input": "before-toast-neutral.mp4",
      "sourceStartSeconds": 0.7,
      "sourceCrop": {
        "x": 1008,
        "y": 0,
        "width": 424,
        "height": 150
      },
      "outputScale": {
        "width": 848,
        "height": 300
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "637faa51ec20355f265171b05f8104f1be73f3cd1443f57beab9b015427012bb"
    },
    {
      "chapter": "Error toast",
      "phase": "After",
      "input": "after-missing-conversation-toast.mp4",
      "sourceStartSeconds": 0.7,
      "sourceCrop": {
        "x": 1008,
        "y": 0,
        "width": 424,
        "height": 150
      },
      "outputScale": {
        "width": 848,
        "height": 300
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "28f48ec7602924622e527938ec1d17a1a72850b640c54dfff919a291678083cd"
    },
    {
      "chapter": "Connection error",
      "phase": "Before",
      "input": "before-disconnected-banner.mp4",
      "sourceStartSeconds": 2,
      "sourceCrop": {
        "x": 344,
        "y": 766,
        "width": 344,
        "height": 60
      },
      "outputScale": {
        "width": 860,
        "height": 150
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "5e89332e1aae39efd3e818dcee7a43d6c674584d80cc009e283e488f45b36f79"
    },
    {
      "chapter": "Connection error",
      "phase": "After",
      "input": "after-disconnected-banner.mp4",
      "sourceStartSeconds": 19,
      "sourceCrop": {
        "x": 344,
        "y": 766,
        "width": 344,
        "height": 60
      },
      "outputScale": {
        "width": 860,
        "height": 150
      },
      "durationSeconds": 3.5,
      "note": "Actual recorded UI pixels, cropped and scaled; final recorded frame held as necessary. Text outside the crop labels the evidence.",
      "sourceSha256": "72fcc27b57871ec0c1c10b520ab305941517cd5a660f8047273746b7e9047c4f"
    }
  ],
  "music": {
    "kind": "Original synthesized quiet ambience; no sampled or third-party track",
    "method": "48kHz stereo PCM, normalized three-note sine triads C3/E3/G3 then C3/F3/A3 with 0.09 Hz phase modulation, 0.004 amplitude, two-second fade in/out; AAC export",
    "measuredMeanDbfs": -56.3,
    "measuredMaxDbfs": -47.9
  },
  "observations": {
    "neutralDiff": {
      "additions": "+3",
      "deletions": "-1",
      "beforeAfterSuccessColor": "rgb(31, 189, 83)",
      "beforeAfterErrorColor": "rgb(255, 104, 78)"
    },
    "neutralErrorToast": {
      "beforeAfterErrorColor": "rgb(255, 104, 78)"
    },
    "lightErrorToastAndDisconnectedBanner": {
      "beforeAfterErrorColor": "rgb(209, 52, 56)"
    },
    "styleDelivery": "BEFORE uses inline var(--oh-status-*) colors. AFTER resolves the identical theme/host variables through text-status-error/success classes.",
    "inlineStyleWarningsRemoved": 4
  },
  "authenticity": "Every UI crop comes from an actual control-openhands recording on the corresponding product source. Only cropping/scaling, recorded-frame holds, captions and original music were added. Title cards/captions label the evidence and do not purport to be Canvas UI.",
  "limits": [
    "The film shows Neutral diff counts and an actual 404 toast, plus a Light+ actual connection-loss error icon. It does not claim a five-theme live audit or a contrast redesign.",
    "Separate real screenshots also cover Light+ 404 toast and phone toast/error-icon rendering. The existing phone overview is hidden; no visible phone diff-count pass is claimed.",
    "The baseline model remained running when the backend was deliberately stopped; no model response success is claimed. Zero ActionEvents were observed among 4 events. The after run encountered an unrelated SDK CacheableResult import failure; no SDK fix is included.",
    "An existing Thinking pill overlaps part of the baseline phone banner text. The film uses the unobscured desktop icon/message region and excludes that pill. No broad mobile-layout pass is claimed.",
    "After-head +0/-0 frames following a reload are excluded from actual +3/-1 diff proof.",
    "Full source runs were stopped and all their owned ports verified closed. Credentials were read only by the preset setup through a private key file and are absent from published pixels and metadata."
  ],
  "assets": [
    {
      "name": "status-classes-before-after.mp4",
      "sha256": "558f01b0eeb8ed0f337a0bc4eaf47d64494449fe2a60c2d5bc57471b7ea03ae7",
      "bytes": 532251
    },
    {
      "name": "status-classes-before-after.gif",
      "sha256": "9a44da0b00d7a034515e6ed2b3b1057c905a1044ecb9fae516f0f0b862b6fa42",
      "bytes": 362907
    },
    {
      "name": "status-classes-poster.png",
      "sha256": "e89d994c7d69d480f196d36aea6bc31f182d4b9380d9fe2742cd2d46bdaf10d6",
      "bytes": 115612
    },
    {
      "name": "status-classes-captions.vtt",
      "sha256": "0dd18a5061cb4038ffb4f35b09b3c1862502ee5a38ba99df6f0b797820e476f8",
      "bytes": 651
    }
  ],
  "captureManifests": {
    "before": {
      "name": "before-source.json",
      "sha256": "ac5d9a2609b63f09c952e69447d59e32589c4429ca9be4956f7245e902b20027"
    },
    "afterHistorical": {
      "name": "after-source.json",
      "sha256": "afe8be94758330c48407028da1d82a6a3863813ee9310428e4534b3887970fe7",
      "note": "The earlier after-only manifest retains its capture-time memory blocker; this combined manifest records the completed matching baseline."
    }
  },
  "cleanup": {
    "beforeRunStopped": true,
    "afterRunStopped": true,
    "allOwnedRunPortsClosed": true
  }
}
