feat(telegram): audit monitoring alert coverage
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 2m8s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 2m8s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
This commit is contained in:
@@ -280,6 +280,47 @@ type TelegramPostApplyVerifierPayload = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
type TelegramMonitoringCoveragePayload = {
|
||||
status?: string | null;
|
||||
active_blockers?: string[] | null;
|
||||
operator_answer?: {
|
||||
all_known_telegram_egress_routes_controlled?: boolean | null;
|
||||
all_known_telegram_egress_routes_have_db_or_log_receipt?: boolean | null;
|
||||
all_verified_ai_alert_context_receipts_reusable_by_ai_agent?: boolean | null;
|
||||
all_monitoring_inventory_surfaces_have_accepted_live_receipt?: boolean | null;
|
||||
manual_default_terminal_state_allowed?: boolean | null;
|
||||
} | null;
|
||||
summary?: {
|
||||
monitoring_surface_count?: number | null;
|
||||
monitoring_live_evidence_received_count?: number | null;
|
||||
monitoring_live_receipt_gap_count?: number | null;
|
||||
known_direct_send_gap_count?: number | null;
|
||||
db_or_log_receipt_ready_surface_count?: number | null;
|
||||
ai_route_ready_surface_count?: number | null;
|
||||
controlled_queue_ready_surface_count?: number | null;
|
||||
ai_alert_card_delivery_total?: number | null;
|
||||
ai_alert_card_learning_writeback_ready_total?: number | null;
|
||||
runtime_alert_operation_log_total_7d?: number | null;
|
||||
runtime_telegram_sent_event_count_7d?: number | null;
|
||||
runtime_km_converted_event_count_7d?: number | null;
|
||||
runtime_playbook_draft_event_count_7d?: number | null;
|
||||
verified_context_receipt_count?: number | null;
|
||||
verified_target_count?: number | null;
|
||||
source_contract_ready?: boolean | null;
|
||||
runtime_db_readback_ok?: boolean | null;
|
||||
ai_alert_card_db_readback_ok?: boolean | null;
|
||||
full_coverage_ready?: boolean | null;
|
||||
} | null;
|
||||
operation_boundaries?: {
|
||||
telegram_send_performed?: boolean | null;
|
||||
bot_api_call_performed?: boolean | null;
|
||||
runtime_write_performed?: boolean | null;
|
||||
raw_alert_payload_stored?: boolean | null;
|
||||
secret_value_read?: boolean | null;
|
||||
github_api_used?: boolean | null;
|
||||
} | null;
|
||||
};
|
||||
|
||||
type PanelMode = "full" | "compact";
|
||||
type Tone = "ok" | "warn" | "neutral";
|
||||
type WorkFilter = "all" | "completed" | "active" | "pending" | "blocked";
|
||||
@@ -421,6 +462,23 @@ async function fetchTelegramPostApplyVerifier(): Promise<TelegramPostApplyVerifi
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchTelegramMonitoringCoverage(): Promise<TelegramMonitoringCoveragePayload | null> {
|
||||
const controller = new AbortController();
|
||||
const timeout = window.setTimeout(() => controller.abort(), 12_000);
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/api/v1/agents/telegram-alert-monitoring-coverage-readback`, {
|
||||
cache: "no-store",
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!response.ok) return null;
|
||||
return (await response.json()) as TelegramMonitoringCoveragePayload;
|
||||
} catch {
|
||||
return null;
|
||||
} finally {
|
||||
window.clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
export function AutonomousRuntimeReceiptPanel({
|
||||
mode = "full",
|
||||
}: {
|
||||
@@ -432,6 +490,7 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
const [priorityPayload, setPriorityPayload] = useState<PriorityWorkOrderPayload | null>(null);
|
||||
const [consumerPayload, setConsumerPayload] = useState<LogConsumerReadbackPayload | null>(null);
|
||||
const [telegramVerifierPayload, setTelegramVerifierPayload] = useState<TelegramPostApplyVerifierPayload | null>(null);
|
||||
const [telegramCoveragePayload, setTelegramCoveragePayload] = useState<TelegramMonitoringCoveragePayload | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(false);
|
||||
const [updatedAt, setUpdatedAt] = useState<Date | null>(null);
|
||||
@@ -439,16 +498,18 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const [next, priority, consumer, telegramVerifier] = await Promise.all([
|
||||
const [next, priority, consumer, telegramVerifier, telegramCoverage] = await Promise.all([
|
||||
fetchRuntimeControl(),
|
||||
fetchPriorityWorkOrder(),
|
||||
fetchLogConsumerReadback(),
|
||||
fetchTelegramPostApplyVerifier(),
|
||||
fetchTelegramMonitoringCoverage(),
|
||||
]);
|
||||
setPayload(next);
|
||||
setPriorityPayload(priority);
|
||||
setConsumerPayload(consumer);
|
||||
setTelegramVerifierPayload(telegramVerifier);
|
||||
setTelegramCoveragePayload(telegramCoverage);
|
||||
setError(next === null);
|
||||
setUpdatedAt(next ? new Date() : null);
|
||||
setLoading(false);
|
||||
@@ -464,6 +525,7 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
const hasPriorityReadback = priorityPayload !== null;
|
||||
const hasConsumerReadback = consumerPayload !== null;
|
||||
const hasTelegramVerifierReadback = telegramVerifierPayload !== null;
|
||||
const hasTelegramCoverageReadback = telegramCoveragePayload !== null;
|
||||
const readback = payload?.runtime_receipt_readback;
|
||||
const ledger = readback?.autonomous_execution_loop_ledger;
|
||||
const traceLedger = readback?.trace_ledger;
|
||||
@@ -485,11 +547,17 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
const consumerBlockers = consumerPayload?.active_blockers ?? [];
|
||||
const telegramVerifierRollups = telegramVerifierPayload?.rollups ?? {};
|
||||
const telegramVerifierBlockers = telegramVerifierPayload?.active_blockers ?? [];
|
||||
const telegramCoverageSummary = telegramCoveragePayload?.summary ?? {};
|
||||
const telegramCoverageAnswers = telegramCoveragePayload?.operator_answer ?? {};
|
||||
const telegramCoverageBlockers = telegramCoveragePayload?.active_blockers ?? [];
|
||||
const consumerReady = consumerRollups.controlled_consumer_readback_ready === true
|
||||
|| consumerPayload?.status === "controlled_writeback_consumer_readback_ready";
|
||||
const telegramPostApplyVerifierReady =
|
||||
telegramVerifierRollups.telegram_alert_learning_context_post_apply_verifier_ready === true
|
||||
|| telegramVerifierPayload?.status === "telegram_alert_learning_context_post_apply_verified";
|
||||
const telegramMonitoringCoverageReady =
|
||||
telegramCoverageSummary.full_coverage_ready === true
|
||||
|| telegramCoveragePayload?.status === "telegram_alert_monitoring_coverage_ready";
|
||||
const runtimeTargetWritePerformed = consumerRollups.runtime_target_write_performed === true
|
||||
|| consumerPayload?.controlled_consume?.runtime_target_write_performed === true
|
||||
|| consumerPayload?.operation_boundaries?.runtime_target_write_performed === true
|
||||
@@ -1056,6 +1124,140 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
: telegramVerifierBlockers.length > 0 ? "warn" as Tone : "ok" as Tone,
|
||||
},
|
||||
];
|
||||
const telegramCoverageCards = [
|
||||
{
|
||||
key: "status",
|
||||
label: t("monitoringCoverage.status"),
|
||||
value: !hasTelegramCoverageReadback
|
||||
? t("states.loading")
|
||||
: telegramMonitoringCoverageReady
|
||||
? t("states.closed")
|
||||
: t("states.open"),
|
||||
detail: t("monitoringCoverage.statusDetail"),
|
||||
icon: ShieldCheck,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: telegramMonitoringCoverageReady ? "ok" as Tone : "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "direct",
|
||||
label: t("monitoringCoverage.direct"),
|
||||
value: readbackNumber(
|
||||
telegramCoverageSummary.known_direct_send_gap_count,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
detail: t("monitoringCoverage.directDetail", {
|
||||
ready: telegramCoverageAnswers.all_known_telegram_egress_routes_controlled
|
||||
? t("proof.ok")
|
||||
: t("states.open"),
|
||||
}),
|
||||
icon: Send,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: toNumber(telegramCoverageSummary.known_direct_send_gap_count) === 0
|
||||
? "ok" as Tone
|
||||
: "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "monitoring",
|
||||
label: t("monitoringCoverage.monitoring"),
|
||||
value: readbackRatio(
|
||||
telegramCoverageSummary.monitoring_live_evidence_received_count,
|
||||
telegramCoverageSummary.monitoring_surface_count,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
detail: t("monitoringCoverage.monitoringDetail", {
|
||||
gap: readbackNumber(
|
||||
telegramCoverageSummary.monitoring_live_receipt_gap_count,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
}),
|
||||
icon: Bell,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: toNumber(telegramCoverageSummary.monitoring_live_receipt_gap_count) === 0
|
||||
? "ok" as Tone
|
||||
: "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "delivery",
|
||||
label: t("monitoringCoverage.delivery"),
|
||||
value: readbackRatio(
|
||||
telegramCoverageSummary.ai_alert_card_learning_writeback_ready_total,
|
||||
telegramCoverageSummary.ai_alert_card_delivery_total,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
detail: t("monitoringCoverage.deliveryDetail"),
|
||||
icon: Database,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: telegramCoverageSummary.ai_alert_card_db_readback_ok === true
|
||||
&& toNumber(telegramCoverageSummary.ai_alert_card_learning_writeback_ready_total) > 0
|
||||
? "ok" as Tone
|
||||
: "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "verifier",
|
||||
label: t("monitoringCoverage.verifier"),
|
||||
value: readbackRatio(
|
||||
telegramCoverageSummary.verified_target_count,
|
||||
6,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
detail: t("monitoringCoverage.verifierDetail", {
|
||||
receipts: readbackNumber(
|
||||
telegramCoverageSummary.verified_context_receipt_count,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
}),
|
||||
icon: Bot,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: telegramCoverageAnswers.all_verified_ai_alert_context_receipts_reusable_by_ai_agent
|
||||
? "ok" as Tone
|
||||
: "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "logs",
|
||||
label: t("monitoringCoverage.logs"),
|
||||
value: readbackNumber(
|
||||
telegramCoverageSummary.runtime_alert_operation_log_total_7d,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
detail: t("monitoringCoverage.logsDetail", {
|
||||
telegram: readbackNumber(
|
||||
telegramCoverageSummary.runtime_telegram_sent_event_count_7d,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
km: readbackNumber(
|
||||
telegramCoverageSummary.runtime_km_converted_event_count_7d,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
playbook: readbackNumber(
|
||||
telegramCoverageSummary.runtime_playbook_draft_event_count_7d,
|
||||
hasTelegramCoverageReadback
|
||||
),
|
||||
}),
|
||||
icon: Activity,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: telegramCoverageSummary.runtime_db_readback_ok === true ? "ok" as Tone : "warn" as Tone,
|
||||
},
|
||||
{
|
||||
key: "blockers",
|
||||
label: t("monitoringCoverage.blockers"),
|
||||
value: readbackNumber(telegramCoverageBlockers.length, hasTelegramCoverageReadback),
|
||||
detail: !hasTelegramCoverageReadback
|
||||
? t("states.loading")
|
||||
: telegramCoverageBlockers.length > 0
|
||||
? telegramCoverageBlockers[0]
|
||||
: t("monitoringCoverage.noBlockers"),
|
||||
icon: TriangleAlert,
|
||||
tone: !hasTelegramCoverageReadback
|
||||
? "neutral" as Tone
|
||||
: telegramCoverageBlockers.length > 0 ? "warn" as Tone : "ok" as Tone,
|
||||
},
|
||||
];
|
||||
const visibleWorkItems = orderedWorkItems.filter((item) => matchesWorkFilter(item, workFilter));
|
||||
const orderedCompleted = orderedWorkItems.filter((item) => item.status === "completed").length;
|
||||
const orderedActive = orderedWorkItems.filter((item) => (
|
||||
@@ -1249,6 +1451,54 @@ export function AutonomousRuntimeReceiptPanel({
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
data-testid="telegram-alert-monitoring-coverage-readback"
|
||||
className="border-t border-[#e0ddd4] bg-white"
|
||||
>
|
||||
<div className="flex flex-wrap items-start justify-between gap-3 px-4 py-3">
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<Bell className="h-4 w-4 text-[#87867f]" aria-hidden="true" />
|
||||
<h4 className="text-sm font-semibold text-[#141413]">{t("monitoringCoverage.title")}</h4>
|
||||
</div>
|
||||
<p className="mt-1 text-xs leading-5 text-[#5f5b52]">
|
||||
{t("monitoringCoverage.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<span className={cn("inline-flex border px-2 py-0.5 text-xs font-semibold", toneClass(
|
||||
!hasTelegramCoverageReadback
|
||||
? "neutral"
|
||||
: telegramMonitoringCoverageReady ? "ok" : "warn"
|
||||
))}>
|
||||
{!hasTelegramCoverageReadback
|
||||
? t("states.loading")
|
||||
: telegramCoveragePayload?.status ?? "--"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid gap-px border-t border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-3 xl:grid-cols-7">
|
||||
{telegramCoverageCards.map((card) => {
|
||||
const Icon = card.icon;
|
||||
return (
|
||||
<div key={card.key} className="bg-white px-4 py-3">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<p className="text-xs font-semibold text-[#77736a]">{card.label}</p>
|
||||
<p className="mt-2 truncate font-mono text-lg font-semibold text-[#141413]">
|
||||
{card.value}
|
||||
</p>
|
||||
</div>
|
||||
<span className={cn("flex h-8 w-8 shrink-0 items-center justify-center border", toneClass(card.tone))}>
|
||||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 line-clamp-2 text-xs leading-5 text-[#5f5b52]">
|
||||
{card.detail}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-px bg-[#e0ddd4] md:grid-cols-5 xl:grid-cols-12">
|
||||
|
||||
Reference in New Issue
Block a user