{
  "scope": "Independent browser-duration arithmetic and UI semantic review. No Site edits, browser interactions, CALMET runs, source tuning, or physical validation.",
  "allChecksPassed": true,
  "terminalState": {
    "numericalVerifier": "exit 0",
    "uiSemanticVerifier": "exit 0"
  },
  "checkCounts": {
    "numericalAndHelpers": 258,
    "uiSemantics": 62,
    "combined": 320
  },
  "failedChecks": [],
  "htmlSha256": "b37db2808efeee8b2ffcd6a6f600091663b6d2599a89dc3b0cddd105efcac6b2",
  "engineSha256": "ecec70ed2c1c308dd201360fd8058417eadadb4265d4cd301e10bd0e0031719f",
  "workerSha256": "d550883d8dd76f867adc1c001fadb774e5743b31ad7a1104d063eaa1d7e137c4",
  "originalHtmlSha256": "f9dab30409de4e642f042f390233605b308ca9d1af18ff4f507e52ce84ce11dc",
  "acceptancePlanSha256": "194cae03dc3154f35ed75e326edcdd095f70382d02810e0d96fea2c6e22533ac",
  "engineAndWorkerByteIdenticalToBefore": true,
  "syntheticCases": 10,
  "sourceRateRows": 12,
  "largestIntegrationMassBalanceRelativeError": 6.785119203702798e-15,
  "noClippedMass": true,
  "closed14hUnitRate": {
    "totalEmittedG": 50400,
    "meanMass1hG": 1800,
    "meanMass24hG": 35700,
    "maximumHourlyMeanMassG": 50400,
    "earliestMaximumHourlyStartSeconds": 50400
  },
  "offHourStepSensitivity": {
    "elapsedSeconds": 51300,
    "comparisonElapsedSeconds": 86400,
    "maxDtSeconds": 17,
    "meaning": "A selected non-hour time can split an explicit integration step. This is numerical step partition sensitivity, not a change to the full averaging window.",
    "averageDiffs": [
      {
        "durationSeconds": 3600,
        "maxAbsolute": 0,
        "maxRelative": 0,
        "finite": true,
        "nonnegative": true
      },
      {
        "durationSeconds": 86400,
        "maxAbsolute": 2.7689666239893995e-06,
        "maxRelative": 3.714765389218331e-08,
        "finite": true,
        "nonnegative": true
      }
    ],
    "hourlyMaxDifference": {
      "maxAbsolute": 1.8777290051730233e-06,
      "maxRelative": 5.318625757969354e-08,
      "finite": true,
      "nonnegative": true
    }
  },
  "issuesResolved": [
    "The worker-completion caption was overwritten immediately by drawMap. The final drawMap is the single caption writer.",
    "Full-event mass now says scheduled mass and separately gives emitted mass through the selected snapshot.",
    "Custom-duration completed results now retain an explicit custom-duration label, independent of newer live input settings."
  ],
  "sourceLocators": {
    "horizon": [
      {
        "line": 1403,
        "text": "const integrationHorizonSeconds = Math.max(elapsedSeconds, hourlyBlockCount * 3600, ...averagingWindowsSeconds);"
      }
    ],
    "sourceStopStepSplit": [
      {
        "line": 1480,
        "text": "if (releaseSeconds > t + 1e-8) dt = Math.min(dt, releaseSeconds - t);"
      }
    ],
    "sourceMassIncrement": [
      {
        "line": 1497,
        "text": "const released = rate * Math.max(0, Math.min(t + dt, releaseSeconds) - Math.min(t, releaseSeconds));"
      }
    ],
    "averageDenominator": [
      {
        "line": 1463,
        "text": "for (let i = 0; i < n; i++) values[i] = timeIntegral[i] * 1e6 / duration;"
      }
    ],
    "hourlyBlockDenominator": [
      {
        "line": 1471,
        "text": "const mean = hourlyIntegral[i] * 1e6 / 3600;"
      }
    ],
    "trapezoidTimeIntegral": [
      {
        "line": 1506,
        "text": "const dose = 0.5 * dt * (conc[i] + mass[i] / volume[i]);"
      }
    ],
    "selectedSnapshotBudget": [
      {
        "line": 1458,
        "text": "selectedMass = mass.slice(); selectedBudget = { emittedG, escapedG, depositedG, airborneG: sum(mass), clippedMassG };"
      },
      {
        "line": 1516,
        "text": "if (!selectedMass) { selectedMass = mass.slice(); selectedBudget = { emittedG, escapedG, depositedG, airborneG: sum(mass), clippedMassG }; }"
      }
    ],
    "workerWindows": [
      {
        "line": 1599,
        "text": "const opts={elapsedSeconds:config.elapsedSeconds,releaseSeconds:config.releaseSeconds,sourceHeightAGL:config.sourceHeightAGL,emissionRateGs:1,horizontalDiffusivity:10,verticalDiffusivity:config.inversionHeight===null?3:1,inversionMixingFraction:config.inversionHeight===null?1:.03,averagingWindowsSeconds:[3600,86400],hourlyBlockCount:24};"
      }
    ],
    "sourceRates": [
      {
        "line": 1641,
        "text": "function sourceRates(profile){if(profile==='unit')return {PM25:1,NOx:1,CO:1,VOC:1};const s=profileSource(profile);return Object.fromEntries(Object.keys(kinds).map(k=>[k,s[k+'_t_per_day']*1e6/(s.max_hours_per_day*3600)]));}"
      }
    ],
    "resultCaption": [
      {
        "line": 1710,
        "text": "$('run-caption').textContent=`${profileLabel} \u00b7 ${runConfig.scenario.replaceAll('-',' ')} \u00b7 ${timing} \u00b7 ${formatMinutes(runConfig.releaseSeconds/60)} release. Fixed weather over the 24-hour calculation. ${Math.round(output.grid.dx)} m cells; wind trails show selected-layer horizontal flow. Layer means, not 2 m breathing-height predictions.`;"
      }
    ],
    "emissionCaption": [
      {
        "line": 1758,
        "text": "$('emission-caption').textContent='Fixed rates, scheduled total mass and emitted mass through the snapshot: '+Object.entries(sourceRates(runConfig.profile)).map(([k,v])=>kinds[k].label+' '+v.toPrecision(5)+' g/s; scheduled '+kg(v*runConfig.releaseSeconds/1000)+', emitted '+kg(v*resultFor(k).emittedG/1000)).join(' \u00b7 ')+'. Prescribed injection altitude: '+Math.round(output.sourceAltitude)+' m above sea level. Historical heat and equivalent stack geometry are not used by this browser plume-rise assumption.';"
      }
    ],
    "profileSwitch": [
      {
        "line": 1847,
        "text": "function applyProfile(){const minutes=defaultDuration($('profile').value);$('duration').value=minutes;$('time').value=Math.max(60,minutes);markDirty();}"
      }
    ],
    "queryProfile": [
      {
        "line": 1934,
        "text": "const requestedProfile=new URLSearchParams(window.location.search).get('profile');"
      }
    ],
    "PM24hMean": [
      {
        "line": 1664,
        "text": "if(kind==='PM25'){const a=r.averages.find(a=>a.endSeconds===86400);return {values:a.groundLayerMeanUgM3,rate,limit:25,label:'PM\u2082.\u2085 \u00b7 24-hour mean',period:'0\u201324 h after release began',status:'B.C. objective'};}"
      }
    ],
    "COHourlyBlocks": [
      {
        "line": 1666,
        "text": "if(kind==='CO')return {values:r.groundMaxHourlyUgM3,rate,limit:14300,label:'CO \u00b7 maximum hourly mean',period:'maximum of 24 one-hour blocks',status:'B.C. legacy reference level'};"
      }
    ],
    "customInputWording": [
      {
        "line": 1635,
        "text": "$('profile-note').textContent=profile==='unit'?'Reference rate: 1 g/s of each displayed constituent. Selected duration: '+formatMinutes(duration)+'.':duration===standard?'Uniform reconstruction from the 2014 design inventory. Historical duration: '+formatMinutes(standard)+'.':'Custom duration: '+formatMinutes(duration)+' at the fixed 2014 reconstructed rate. Total mass differs from the historical '+formatMinutes(standard)+' case.';"
      }
    ],
    "gridLimitation": [
      {
        "line": 1148,
        "text": "<details><summary>Evidence needed for a prediction</summary><table class=\"table table-sm\"><thead><tr><th>Input or check</th><th>Current evidence gap</th></tr></thead><tbody><tr><td>Current flare source</td><td>Verified tip geometry, event emissions and heat release missing</td></tr><tr><td>Local transport and inversion</td><td>Source-site hourly winds and vertical temperature/wind profiles missing</td></tr><tr><td>Community exposure</td><td>Breathing-height concentrations, chemistry and background not validated</td></tr><tr><td>Illustrative plume solver</td><td>Grid-refinement check failed; AERMOD reference tests do not validate this browser calculation</td></tr></tbody></table></details>"
      }
    ]
  },
  "limitations": [
    "Small synthetic cases check arithmetic, not Woodfibre plume validity or production-worker performance.",
    "Parent owns browser rendering, loading/error/lifecycle and publication checks.",
    "2014 LPCF is a uniform daily-inventory reconstruction over listed 14 maximum operating hours, not a measured event trace, typical operation, or current design.",
    "Fixed prescribed browser weather over 24 h; no saved CALMET wind is used by this solver.",
    "Existing grid-refinement failure, layer-mean, source-height, chemistry, background and unvalidated-flow limitations remain."
  ]
}
