/home/yeff/public_html/devon/panel/assets/js/panel.js:18:  observable_evidence:   'Filesystem and runtime observable evidence',
/home/yeff/public_html/devon/panel/assets/js/panel.js:26:  sel: { phaseId: null, catId: null, bucket: null }
/home/yeff/public_html/devon/panel/assets/js/panel.js:31:    const [hub, host, docker, runtime, progress] = await Promise.all([
/home/yeff/public_html/devon/panel/assets/js/panel.js:33:      fetch('data/host_runtime.json').then(r => r.json()).catch(() => null),
/home/yeff/public_html/devon/panel/assets/js/panel.js:34:      fetch('data/docker_runtime.json').then(r => r.json()).catch(() => null),
/home/yeff/public_html/devon/panel/assets/js/panel.js:35:      fetch('data/runtime_status.json').then(r => r.json()).catch(() => null),
/home/yeff/public_html/devon/panel/assets/js/panel.js:36:      fetch('data/project_progress.json').then(r => r.json()).catch(() => null)
/home/yeff/public_html/devon/panel/assets/js/panel.js:40:    G.data = { host, docker, runtime, progress };
/home/yeff/public_html/devon/panel/assets/js/panel.js:41:    renderTree();
/home/yeff/public_html/devon/panel/assets/js/panel.js:42:    renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:43:    renderFooter();
/home/yeff/public_html/devon/panel/assets/js/panel.js:62:function renderTree() {
/home/yeff/public_html/devon/panel/assets/js/panel.js:85:            const bkActive = G.sel.catId === cat.id && G.sel.bucket === bk ? ' bk-active' : '';
/home/yeff/public_html/devon/panel/assets/js/panel.js:102:      if (G.openPhases.has(id)) { G.openPhases.delete(id); G.openCats.clear(); G.sel.catId = null; G.sel.bucket = null; }
/home/yeff/public_html/devon/panel/assets/js/panel.js:105:      renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:112:      if (G.openCats.has(id)) { G.openCats.delete(id); G.sel.bucket = null; }
/home/yeff/public_html/devon/panel/assets/js/panel.js:116:      G.sel.bucket = null;
/home/yeff/public_html/devon/panel/assets/js/panel.js:117:      renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:125:      G.sel.bucket = el.dataset.bk;
/home/yeff/public_html/devon/panel/assets/js/panel.js:126:      renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:133:function renderDetail() {
/home/yeff/public_html/devon/panel/assets/js/panel.js:135:  if (!G.sel.phaseId) { el.innerHTML = renderSummary(); return; }
/home/yeff/public_html/devon/panel/assets/js/panel.js:137:  if (!G.sel.catId) { el.innerHTML = renderPhaseOverview(ph); return; }
/home/yeff/public_html/devon/panel/assets/js/panel.js:139:  if (!G.sel.bucket) { el.innerHTML = renderCatOverview(ph, cat); return; }
/home/yeff/public_html/devon/panel/assets/js/panel.js:140:  el.innerHTML = renderBucketDetail(ph, cat, G.sel.bucket);
/home/yeff/public_html/devon/panel/assets/js/panel.js:143:function renderSummary() {
/home/yeff/public_html/devon/panel/assets/js/panel.js:144:  const pp = G.data.progress;
/home/yeff/public_html/devon/panel/assets/js/panel.js:145:  const pct = Math.round(pp?.progress_pct ?? pp?.global_pct ?? 0);
/home/yeff/public_html/devon/panel/assets/js/panel.js:152:    <div class="sum-sub">Select a phase in the tree to navigate. Canon leads. Runtime validates. UI renders.</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:162:function renderPhaseOverview(ph) {
/home/yeff/public_html/devon/panel/assets/js/panel.js:164:  const cards = cats.map(c => `<div class="cat-card" data-ph="${ph.id}" data-cat="${c.id}">
/home/yeff/public_html/devon/panel/assets/js/panel.js:165:    <div class="cat-card-title">${c.title}</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:166:    <div class="cat-card-sub">${c.sub || ''}</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:174:    <div class="ph-ov-cats">${cards}</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:178:function renderCatOverview(ph, cat) {
/home/yeff/public_html/devon/panel/assets/js/panel.js:179:  const bkCards = BUCKETS.map((bk, i) => `<div class="bk-card" data-ph="${ph.id}" data-cat="${cat.id}" data-bk="${bk}">
/home/yeff/public_html/devon/panel/assets/js/panel.js:180:    <span class="bk-card-num">${String(i+1).padStart(2,'0')}</span>
/home/yeff/public_html/devon/panel/assets/js/panel.js:181:    <span class="bk-card-name">${bk}</span>
/home/yeff/public_html/devon/panel/assets/js/panel.js:182:    <span class="bk-card-desc">${BUCKET_DESC[bk]}</span>
/home/yeff/public_html/devon/panel/assets/js/panel.js:197:function renderBucketDetail(ph, cat, bucket) {
/home/yeff/public_html/devon/panel/assets/js/panel.js:199:  const bkIdx = BUCKETS.indexOf(bucket);
/home/yeff/public_html/devon/panel/assets/js/panel.js:205:    return `<div class="item-card ${cls}">
/home/yeff/public_html/devon/panel/assets/js/panel.js:220:    <span class="det-bc">${ph.step} / ${cat.title} / <b>${bucket}</b></span>
/home/yeff/public_html/devon/panel/assets/js/panel.js:221:    <div class="det-pills"><span class="pl pl-v">${ph.step}</span><span class="pl pl-bk">${bucket}</span></div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:226:    <div class="det-sub">${BUCKET_DESC[bucket]}</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:228:  <div class="det-progress">
/home/yeff/public_html/devon/panel/assets/js/panel.js:229:    <div class="prog-card">
/home/yeff/public_html/devon/panel/assets/js/panel.js:234:    <div class="prog-card">
/home/yeff/public_html/devon/panel/assets/js/panel.js:237:      <div class="prog-nums">${bucket}</div>
/home/yeff/public_html/devon/panel/assets/js/panel.js:247:  const rows = G.data.runtime?.rows || G.data.runtime?.runtime_rows || [];
/home/yeff/public_html/devon/panel/assets/js/panel.js:251:    (r.label || r.subcategory || r.component || '').toLowerCase().includes(name)
/home/yeff/public_html/devon/panel/assets/js/panel.js:263:function renderFooter() {
/home/yeff/public_html/devon/panel/assets/js/panel.js:282:    G.sel.catId = null; G.sel.bucket = null;
/home/yeff/public_html/devon/panel/assets/js/panel.js:283:    renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:308:  const cc = e.target.closest('.cat-card');
/home/yeff/public_html/devon/panel/assets/js/panel.js:312:    G.sel.bucket = null;
/home/yeff/public_html/devon/panel/assets/js/panel.js:315:    renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.js:317:  const bc = e.target.closest('.bk-card');
/home/yeff/public_html/devon/panel/assets/js/panel.js:321:    G.sel.bucket = bc.dataset.bk;
/home/yeff/public_html/devon/panel/assets/js/panel.js:324:    renderTree(); renderDetail();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:5:    projectDonut: document.getElementById("project-donut"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:7:    stageNav: document.getElementById("stage-nav"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:10:    stageOrderBadge: document.getElementById("stage-order-badge"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:11:    selectedStageName: document.getElementById("selected-stage-name"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:12:    selectedStageDesc: document.getElementById("selected-stage-desc"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:13:    selectedStageTotal: document.getElementById("selected-stage-total"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:14:    selectedStageDonut: document.getElementById("selected-stage-donut"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:15:    selectedRuntimeBadge: document.getElementById("selected-runtime-badge"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:19:    hostRuntimeGrid: document.getElementById("host-runtime-grid"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:20:    dockerRuntimeGrid: document.getElementById("docker-runtime-grid"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:21:    pipelineRuntimeCount: document.getElementById("pipeline-runtime-count"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:22:    pipelineRuntimeBoard: document.getElementById("pipeline-runtime-board"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:29:    btnOpenRuntime: document.getElementById("btn-open-runtime"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:40:    runtimeStatus: null,
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:107:  function donutMarkup(pct, label) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:113:      '<div class="donut">',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:118:      '<div class="donut-center">',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:120:      '<span>' + (label || "progress") + '</span>',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:127:    return donutMarkup(0, label || "missing");
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:145:  function runtimeStatusOf(row) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:148:      row.runtime_status ??
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:156:  function stageRows(stageKey) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:157:    const snapshot = ((state.runtimeStatus && state.runtimeStatus.runtime_snapshot) || []);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:159:      return normStageKey(row.deployment_stage) === normStageKey(stageKey);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:163:  function stageRollup(stageKey) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:164:    return stageRows(stageKey).find(function (row) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:165:      return String(row.row_kind || "") === "stage_rollup";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:169:  function renderGlobal() {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:170:    const snapshot = ((state.runtimeStatus && state.runtimeStatus.runtime_snapshot) || []);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:172:      const s = runtimeStatusOf(row);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:187:    const gp = state.projectProgress && state.projectProgress.global_project_progress;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:189:      if (gp && typeof gp.progress_pct === "number") {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:190:        els.projectDonut.innerHTML = donutMarkup(Math.round(gp.progress_pct), "project completion");
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:197:  function renderNav() {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:198:    if (!els.stageNav) return;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:200:      .filter(function (item) { return !!item.stage_key; })
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:205:    els.stageNav.innerHTML = "";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:208:      const stageKey = normStageKey(item.stage_key);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:211:      btn.className = "stage-btn";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:212:      btn.dataset.stageKey = stageKey;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:220:        selectStage(stageKey);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:222:      els.stageNav.appendChild(btn);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:226:  function renderHostRuntime() {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:245:  function renderDockerRuntime() {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:246:    const runtime = (state.dockerRuntime && state.dockerRuntime.runtime_snapshot) || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:247:    setBadge(els.dockerStatusBadge, runtime.overall_status || "MISSING", safeUpper(runtime.overall_status || "MISSING"));
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:249:    const engine = runtime.docker_engine || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:250:    const compose = runtime.compose || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:251:    const images = runtime.images || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:252:    const volumes = runtime.volumes || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:253:    const networks = runtime.networks || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:254:    const containers = Array.isArray(runtime.containers) ? runtime.containers : [];
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:266:  function renderPipelineBoard() {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:267:    const items = ((state.runtimeStatus && state.runtimeStatus.runtime_snapshot) || []);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:269:      els.pipelineRuntimeCount.textContent = items.length + " runtime rows";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:273:      els.pipelineRuntimeBoard.innerHTML = '<div class="pipeline-item"><h4>No runtime rows</h4><p>Status is MISSING.</p></div>';
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:277:      const status = runtimeStatusOf(item);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:280:        '<h4>' + titleize(item.deployment_stage || "runtime") + ' / ' + titleize(item.technology || item.subcategory || "item") + '</h4>',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:281:        '<p>Kind: ' + titleize(item.row_kind || "runtime_row") + '</p>',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:284:        '<span class="pill">' + valueOrDash(item.progress_pct, "%") + '</span>',
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:291:  function renderSelectedPipeline(stageKey, rollup) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:294:    const contract = pipelines[stageKey] || {};
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:317:  function selectStage(stageKey) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:318:    state.selectedStage = normStageKey(stageKey);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:321:      return normStageKey(item.stage_key) === state.selectedStage;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:323:    const rollup = stageRollup(state.selectedStage);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:324:    const pct = rollup && typeof rollup.progress_pct === "number" ? Math.round(rollup.progress_pct) : 0;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:329:      els.heroSubtitle.textContent = "Runtime-backed stage view. Contract and runtime data are rendered from panel exports only.";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:331:    if (els.stageOrderBadge) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:332:      els.stageOrderBadge.textContent = navItem ? ("ORDER " + navItem.deployment_order) : "—";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:338:      els.selectedStageDesc.textContent = "Stage completion is read from runtime_status stage_rollup.progress_pct.";
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:343:        : 'MISSING stage rollup<br>in runtime';
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:346:      els.selectedStageDonut.innerHTML = donutMarkup(pct, "stage completion");
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:349:      setBadge(els.selectedRuntimeBadge, rollup ? runtimeStatusOf(rollup) : "MISSING", rollup ? runtimeStatusOf(rollup) : "MISSING");
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:352:    renderSelectedPipeline(state.selectedStage, rollup);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:354:    document.querySelectorAll(".stage-btn").forEach(function (btn) {
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:355:      btn.classList.toggle("active", btn.dataset.stageKey === state.selectedStage);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:365:      ["Runtime Status", els.btnOpenRuntime, state.runtimeStatus]
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:383:        getJsonOptional("subcategory_pipelines.json"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:384:        getJsonOptional("project_progress.json"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:385:        getJsonOptional("host_runtime.json"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:386:        getJsonOptional("docker_runtime.json"),
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:387:        getJsonOptional("runtime_status.json")
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:397:      state.runtimeStatus = core[7];
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:399:      renderGlobal();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:400:      renderNav();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:401:      renderHostRuntime();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:402:      renderDockerRuntime();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:403:      renderPipelineBoard();
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:406:        return !!item.stage_key;
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:410:        selectStage(firstItem.stage_key);
/home/yeff/public_html/devon/panel/assets/js/panel.runtime.fix.20260408_1.js:417:        selectStage: selectStage
