/** * One query, explained in the order it met the pipeline. * * This is the body of the detail surface, with no route in it, because two * surfaces show it: the persisted detail page, which fetched the row by id, and * a live row, whose provenance arrived in the stream frame and which SQLite may * not have written yet. The related actions are links into routes, so the * caller passes them in already built. */ import type { ReactNode } from "react"; import * as stylex from "@stylexjs/stylex"; import { formatMicros, formatTime } from "@/lib/format"; import type { PolicyReason, Provenance } from "@/lib/types"; import { clientLabel, useClientNames } from "@/features/clients/clientNames"; import { policyActionLabel, policyReasonLabel, qclassName, rcodeName, routeKindLabel, } from "@/features/provenance/provenanceCopy"; import { qtypeName } from "@/features/provenance/qtype"; import { styles as shared } from "@/ui/styles"; import { colors } from "@/ui/tokens.stylex"; const styles = stylex.create({ heading: { marginTop: "0.5rem", fontSize: "1.5rem", lineHeight: "2rem", fontWeight: 600, wordBreak: "break-all", }, subtitle: { marginTop: "0.25rem", color: colors.textSecondary, }, /** The recorded facts, fenced off from the live links below them. */ record: { marginTop: "1rem", maxWidth: "48rem", borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.border, backgroundColor: colors.surfaceRaised, padding: "1rem", }, recordNote: { fontSize: "0.8125rem", lineHeight: "1.25rem", color: colors.textMuted, }, section: { marginTop: "1rem", borderTopWidth: { default: 1, ":first-of-type": 0 }, borderTopStyle: "solid", borderTopColor: colors.border, paddingTop: { default: "1rem", ":first-of-type": 0 }, }, sectionHeading: { fontSize: "0.75rem", lineHeight: "1rem", fontWeight: 600, letterSpacing: "0.05em", textTransform: "uppercase", color: colors.textMuted, }, facts: { marginTop: "0.5rem", marginBottom: 0, display: "grid", gap: "0.375rem 1rem", gridTemplateColumns: { default: "auto", "@media (min-width: 640px)": "max-content 1fr", }, fontSize: "0.875rem", lineHeight: "1.25rem", }, term: { color: colors.textMuted, }, value: { margin: 0, wordBreak: "break-all", }, muted: { color: colors.textMuted, }, related: { marginTop: "1.5rem", maxWidth: "48rem", }, relatedHeading: { fontSize: "1.125rem", lineHeight: "1.75rem", fontWeight: 600, }, relatedNote: { marginTop: "0.25rem", fontSize: "0.875rem", lineHeight: "1.25rem", color: colors.textMuted, }, relatedList: { marginTop: "0.5rem", display: "flex", flexWrap: "wrap", gap: "0.75rem", fontSize: "0.875rem", lineHeight: "1.25rem", }, link: { color: colors.primaryOnSurface, }, }); /** The look of one related action, so every caller's links match. */ export const provenanceRelatedLink = styles.link; function Section({ title, children }: { title: string; children: ReactNode }) { return (
{formatTime(request.time)} — {policyActionLabel(policy.action)} {/* The verdict alone reads as a success; a non-NOERROR answer says otherwise. */} {response.rcode !== 0 && ` — ${rcodeName(response.rcode)}`}
What was recorded when this query was answered. Group and blocklist names are the ones in force at that moment; they may have been renamed or deleted since. {persistedId === null && " This is the event as it was streamed; the query log may not have written it yet."}
These read the current configuration, which may no longer be the one that decided this query.
{currentClient !== null && (
{currentClient.learned ? (
<>
Reverse DNS currently resolves