ab.appendChild(el("div", "drawer-label", "Prüfkette (" + (data.audit ? data.audit.length : 0) + " Einträge)")); const chain = el("div", "chain"); (data.audit || []).forEach(e => { const row = el("div", "chain-row"); row.appendChild(el("div", "chain-seq", String(e.seq))); row.appendChild(el("div", "chain-type", e.eventType)); row.appendChild(el("div", "chain-detail", compactDetail(e.detail))); chain.appendChild(row); }); ab.appendChild(chain); const verify = el("div", "chain-verify " + (data.auditVerified ? "ok" : "bad")); verify.innerHTML = (data.auditVerified ? ICON_CHECK : ICON_HANDOFF) + "" + (data.auditVerified ? "Kette verifiziert" : "Kette NICHT verifiziert") + ""; ab.appendChild(verify); // Signing status, stated honestly per answer. Signed only when the server carries a signature: the // page never claims "signiert" over a chain the server merely hashed. const sig = el("div", "chain-sig" + (data.auditSignature ? " signed" : "")); if (data.auditSignature) { const head = el("div", "sig-head"); head.innerHTML = ICON_CHECK + "Ed25519-signiert · seq " + data.auditSignature.seq + ""; sig.appendChild(head); sig.appendChild(el("div", "sig-body", data.auditSignature.signature.slice(0, 32) + "…")); sig.appendChild(el("div", "sig-note", "Kopf der Kette signiert, mit öffentlichem Schlüssel allein prüfbar.")); } else { sig.appendChild(el("div", "sig-note", "SHA-256-verkettet, nicht signiert.")); } ab.appendChild(sig); inner.appendChild(ab); drawer.appendChild(inner); return drawer; } function addAnswer(pending, data) { const body = pending.querySelector(".agent-body"); body.innerHTML = ""; // A run that filed a human-handoff ticket is escalated even when its answer shipped grounded: a // customer asking for a human produces a shippable acknowledgment (blocked=false, handoffCount=1). // design.md lists "der Kunde hat einen Menschen angefragt" as an amber trigger, so the seal keys off // the handoff too and never shows green "belegt & auditiert" over an answer that queued a person. const escalated = data.blocked || data.handoffCount > 0; const ans = el("div", "agent-answer" + (escalated ? " escalated-text" : ""), data.answer); body.appendChild(ans); const row = el("div", "status-row"); const seal = el("div", "seal " + (escalated ? "escalated" : "grounded")); seal.innerHTML = '' + (escalated ? ICON_HANDOFF : ICON_CHECK) + "" + (escalated ? "an einen Menschen übergeben" : "belegt & auditiert") + ""; row.appendChild(seal); row.appendChild(el("div", "steps", data.steps + (data.steps === 1 ? " Schritt" : " Schritte"))); const drawer = buildDrawer(data); const toggle = el("button", "evidence-toggle"); toggle.type = "button";