@mark1russell7/kind 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"judge-C6XgY2Pk.js","names":["medianInterval","intervalOfMedian","time","medianInterval","time"],"sources":["../src/bands.ts","../src/names.ts","../src/stats.ts","../src/observe.ts","../src/reconnects.ts","../src/verdict.ts","../src/record.ts","../src/report.ts","../src/schema.ts"],"sourcesContent":["import type { Quantity } from \"@mark1russell7/quantity\";\nimport { valueIn } from \"@mark1russell7/quantity\";\nimport type { BacklogTerm, Band } from \"./cell.ts\";\n\n/** This module makes and prints the bands of the predictions. It imports only the amounts. */\n\n/** This function gives a time in seconds as a quantity. */\nexport const seconds = (value: number): Quantity => ({ value, unit: \"s\" });\n\n/** This function gives a band from its two ends in seconds. */\nexport const bandOf = (lo: number, hi: number): Band => ({ lo: seconds(lo), hi: seconds(hi) });\n\n/** This function gives the two ends of a band as numbers of seconds, for arithmetic. */\nexport const secondsOf = (band: Band): { readonly lo: number; readonly hi: number } => ({\n lo: valueIn(band.lo, \"s\"),\n hi: valueIn(band.hi, \"s\"),\n});\n\n/** This function gives a band in a short form for a name or a table: `[28, 49] s`. */\nexport const showBand = (band: Band): string => {\n const { lo, hi } = secondsOf(band);\n return `[${lo}, ${hi}] s`;\n};\n\n/** This function rounds a time to the microsecond, thus a band has no float residue. */\nconst us = (value: number): number => Math.round(value * 1e6) / 1e6;\n\n/**\n * This function gives the largest time after the band end at which the window of n sessions closes,\n * in seconds. Each session drains in d, thus it is n × d.hi. With `slowest` (SYS-45), one of the n\n * sessions can drain up to that time, thus it is (n − 1) × d.hi + the larger of `slowest` and d.hi.\n */\nconst closingOf = (term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, sessions: number): number => {\n const hi = valueIn(term.drain.hi, \"s\");\n if (term.slowest === undefined || sessions < 1) return sessions * hi;\n return (sessions - 1) * hi + Math.max(valueIn(term.slowest, \"s\"), hi);\n};\n\n/**\n * This function gives the end band of a window with the backlog term (`BacklogTerm`). It adds n × d\n * to each end of `end`, the end band without the term. The value n is the sessions on the target.\n * A term with `slowest` (SYS-45) adds (n − 1) × d.hi + `slowest` to the high end instead.\n */\nexport const backlogEnd = (end: Band, term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, sessions: number): Band => {\n const ends = secondsOf(end);\n const drain = secondsOf(term.drain);\n return bandOf(us(ends.lo + sessions * drain.lo), us(ends.hi + closingOf(term, sessions)));\n};\n\n/**\n * This function gives the band of the start of the last failed request of a window with the backlog\n * term, from the band end (the high end of `end`). This is the overshoot of a run. Its high end is\n * the high end of `backlogEnd`. Without `early`, its low end is n × d.lo (SYS-42). With `early`\n * (SYS-45), the last failed request can start up to one turn before the window closes. Its low end\n * is then the low end of `end` plus n × d.lo. The end band opens one turn before the band end.\n */\nexport const overshootBand = (end: Band, term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\" | \"early\">>, sessions: number): Band => {\n const ends = secondsOf(end);\n const closes = secondsOf(backlogEnd(end, term, sessions));\n const drain = secondsOf(term.drain);\n const lo = term.early === true ? closes.lo - ends.hi : sessions * drain.lo;\n return bandOf(us(lo), us(closes.hi - ends.hi));\n};\n\n/** A count band is a range of counts of requests. */\nexport interface CountBand {\n readonly lo: number;\n readonly hi: number;\n}\n\n/** This function gives a count rounded to six places, thus 10 s / 20 ms gives 500 and not 499.99999. */\nconst counted = (value: number): number => Math.round(value * 1e6) / 1e6;\n\n/** This function gives the turn of a session in seconds: the mean period of a client times its sessions. */\nconst turnOf = (mean: Quantity, connections: number): number => {\n const turn = valueIn(mean, \"s\") * connections;\n if (!(turn > 0)) throw new RangeError(`a turn of ${turn} s cannot count requests`);\n return turn;\n};\n\n/**\n * This function gives the drain failures of one session on the target (SYS-43). A session fails a\n * request each turn until the window closes. With n sessions on the target, the window closes up to\n * n × d.hi after the band end (`backlogEnd`). Thus one session fails 0 to ceil(n × d.hi / turn)\n * requests in the drain. The turn is the mean period of a client (`mean`) times its sessions\n * (`connections`). The term r is not in this band. With `slowest` (SYS-45), the window closes up to\n * (n − 1) × d.hi + `slowest` after the band end. Thus one session fails up to that time over the turn.\n */\nexport const drainBand = (term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, mean: Quantity, connections: number, sessions: number): CountBand => {\n const turn = turnOf(mean, connections);\n return { lo: 0, hi: Math.ceil(counted(closingOf(term, sessions) / turn)) };\n};\n\n/**\n * This function gives the failed requests that the backlog term predicts (`BacklogTerm`). Each of\n * the n sessions on the target gets a request each turn. The turn is the measured mean period of a\n * client (`mean`) times the sessions of the client (`connections`). The requests of a session fail\n * from the start of the window to the band end (`span`). That span holds `span / turn` requests, one\n * less at its low edge and one more at its high edge. Each session fails r more requests in its drain time.\n *\n * A term with `drains` (SYS-43) also adds the drain failures of each session (`drainBand`).\n */\nexport const requestBand = (\n term: Pick<BacklogTerm, \"requests\"> & Partial<Pick<BacklogTerm, \"drain\" | \"drains\" | \"slowest\">>,\n span: Quantity,\n mean: Quantity,\n connections: number,\n sessions: number,\n): CountBand => {\n const turn = turnOf(mean, connections);\n const each = counted(valueIn(span, \"s\") / turn);\n if (term.drains === true && term.drain === undefined) throw new RangeError(\"a term with drains has no drain time d\");\n const drained = term.drains === true ? drainBand({ drain: term.drain!, slowest: term.slowest }, mean, connections, sessions) : { lo: 0, hi: 0 };\n return { lo: sessions * (Math.floor(each) - 1 + term.requests.lo + drained.lo), hi: sessions * (Math.ceil(each) + 1 + term.requests.hi + drained.hi) };\n};\n","// The names and the ports of the objects of a cell. The judge reads them, thus this module imports\n// nothing.\n\n/** These are the ports of the app: its server, and its health server for the probes. */\nexport const PORT = 8080;\nexport const HEALTH_PORT = 9000;\n/** This label makes the watcher follow the log of a pod. */\nexport const LOG_LABEL = \"lab.systems/log\";\n/** These are the names of the objects of a cell. */\nexport const SERVER = \"lab\";\nexport const CLIENT = \"client\";\nexport const REDIS = \"redis\";\n/** This class of a Service of type LoadBalancer selects kube-vip (pkg/kubevip/constants.go of v1.3.1). */\nexport const LB_CLASS = \"kube-vip.io/kube-vip-class\";\n/** This annotation of a Service gives kube-vip the address of its VIP (pkg/kubevip/annotations.go of v1.3.1). */\nexport const VIP_ANNOTATION = \"kube-vip.io/loadbalancerIPs\";\n/** This is the name of the node of each client outside the cluster, in its lines (`KindCell.vip`). */\nexport const OUTSIDE = \"outside\";\n","// The statistics of a kind verdict: the median, the interval of the median and a quantile. They are\n// the statistics of the verdict of the harness, and a test holds them to it. The judge reads a\n// record without the harness, because the harness loads its Docker lab. The three statistics\n// come from @mark1russell7/rigor-statistics.\nimport { medianInterval as intervalOfMedian, median, quantileSorted } from \"@mark1russell7/rigor-statistics\";\n\n/** This fraction, δ_rel, is how far the median of a cell can be outside its band and stay equivalent. */\nexport const RELATIVE = 0.05;\n\n/**\n * This function gives the median of sorted values: the middle value, or the mean of the two middle values.\n * It is `median` of @mark1russell7/rigor-statistics, which throws a RangeError for an empty list.\n */\nexport const middle = (sorted: readonly number[]): number => median(sorted);\n\n/**\n * This function gives the value at quantile p of sorted values, by nearest rank: x_(⌈p·n⌉). It is\n * `quantileSorted` of @mark1russell7/rigor-statistics with the method `\"nearest-rank\"`.\n */\nexport const quantileOf = (sorted: readonly number[], p: number): number => quantileSorted(sorted, p, \"nearest-rank\");\n\n/**\n * This function gives the distribution-free interval of a median: [x_(k), x_(n+1−k)], for the\n * largest k whose two tails each hold 2.5 % or less. For eleven runs, it gives [x_(2), x_(10)],\n * at 98.8 %. It is `medianInterval` of @mark1russell7/rigor-statistics at the level 0.95. An\n * empty list throws a RangeError.\n */\nexport const medianInterval = (sorted: readonly number[]): [number, number] => {\n const interval = intervalOfMedian(sorted, 0.95);\n return [interval.low, interval.high];\n};\n","/**\n * This module reads a run from its lines. Each time is in milliseconds on CLOCK_MONOTONIC. All the\n * containers of the VM share that clock: the clients, the service, the agents, the injector, the\n * watcher and the prober.\n */\nimport { middle } from \"./stats.ts\";\n\n/**\n * A line is one JSON line of a source of a run, with its stamp `t` in milliseconds on\n * CLOCK_MONOTONIC. It is a request of a client, a record of the service, a line of grpc-go or a probe answer. It is\n * also a pod, an EndpointSlice or an event of the API. Or it is the backends of the rules of a\n * node, a kernel record, or an act of the lab. A record keeps each line as its source wrote it.\n */\nexport interface Line {\n readonly ev: string;\n readonly t: number;\n readonly [field: string]: unknown;\n}\n\n/**\n * A request is one request of a client: its start, its duration in ms, its outcome, its client and\n * the node of the client. The backend (`b`) is the pod that answered. The local port (`lp`) is on\n * each request from 0.1.3, and on the failed ones before it. A conntrack entry is per port, thus the\n * requests on one port show which connection a stale entry came from.\n */\nexport interface Request {\n readonly t: number;\n readonly d: number;\n readonly o: string;\n readonly p: string;\n readonly n: string;\n readonly b?: string;\n readonly lp?: number | null;\n}\n\n/** A pod line is one state of a pod, as the watcher received it. */\nexport interface PodLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly node: string | null;\n readonly ip: string | null;\n readonly del: boolean;\n readonly ready: boolean;\n readonly phase: string | null;\n readonly cs: ReadonlyArray<{ readonly n: string; readonly r: boolean; readonly rc: number; readonly st: string; readonly id: string | null }>;\n readonly labels: Readonly<Record<string, string>>;\n}\n\n/** An endpoint is one endpoint of an EndpointSlice: its address, its conditions and its pod. */\nexport interface Endpoint {\n readonly ip: string | null;\n readonly r: boolean | null;\n readonly s: boolean | null;\n readonly x: boolean | null;\n readonly pod: string | null;\n readonly node: string | null;\n}\n\n/** A slice line is one state of an EndpointSlice. */\nexport interface SliceLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly svc: string | null;\n readonly eps: readonly Endpoint[];\n}\n\n/**\n * A rules line is the backends of the Service in the rules of one node, after a change. `prev` is the\n * start of the poll before it. An EDS line has the same fields (`ev` is `eds`). It gives the healthy\n * hosts of the server cluster in the Envoy of the client sidecar on the node.\n */\nexport interface RulesLine {\n readonly t: number;\n readonly prev: number | null;\n readonly node: string;\n readonly b: readonly string[];\n}\n\n/**\n * A propagation source is the poll whose lines give the backends of each node:\n * - `rules`: the rules of kube-proxy in the namespaces of the node.\n * - `eds`: the hosts of the server cluster in the Envoy of the client sidecar on the node. In a sidecar\n * mesh, the client sidecar picks the backend of each call, thus kube-proxy is not on the path.\n */\nexport type PropagationSource = \"rules\" | \"eds\";\n\n/** A record line is one transition of a machine of the service, with its own stamp `at`. */\nexport interface RecordLine {\n readonly t: number;\n readonly at: number;\n readonly p: string;\n readonly m: string;\n readonly i: string;\n readonly from: string;\n readonly to: string;\n readonly on: string;\n readonly d: string | null;\n}\n\n/**\n * A socket line is the connect or the close of a socket of the channel of a gRPC client\n * (`client-lines.ts`). It gives the client (`p`) and its node (`n`), and the local port of the socket.\n * A close also gives the code of an error of the socket (`err`), or null for a close with no error.\n */\nexport interface SocketLine {\n readonly t: number;\n readonly what: \"connect\" | \"close\";\n readonly p: string;\n readonly n: string;\n readonly lp: number | null;\n readonly err?: string | null;\n /** This address is the local address of the socket at its connect: the address of the client pod. Lines before 0.8.0 do not have it. */\n readonly la?: string | null;\n}\n\n/** This port is the HBONE port of ztunnel in each pod of the ambient mesh of Istio 1.31.3: the mesh leg ends there. */\nexport const HBONE_PORT = 15008;\n\n/** These are the states of a TCP socket of Linux that a tunnel line names (include/net/tcp_states.h of Linux v6.17, lines 12–28). */\nexport const TCP_STATE = { established: 1, finWait1: 4, closeWait: 8 } as const;\n\n/**\n * A tunnel line is a change of the state of a TCP socket with the HBONE port at one end, from the\n * prober (`kernel.state`). `src` and `dst` are each an address and a port, `a.b.c.d:port`. The stamp\n * `t` is in ms on CLOCK_MONOTONIC.\n */\nexport interface TunnelLine {\n readonly t: number;\n readonly src: string;\n readonly dst: string;\n readonly old: number;\n readonly new: number;\n}\n\n/** This function tells if a kernel record is a change of the state of a socket of the HBONE port. */\nexport const isTunnelState = (record: Readonly<Record<string, unknown>>): boolean =>\n record[\"ev\"] === \"state\" && [record[\"src\"], record[\"dst\"]].some((end) => typeof end === \"string\" && end.endsWith(`:${HBONE_PORT}`));\n\n/** This function gives the tunnel lines of a run, in sequence of their stamps. */\nexport const tunnelsOf = (lines: readonly Line[]): TunnelLine[] =>\n lines.filter((line) => line.ev === \"kernel.state\").map((line) => line as unknown as TunnelLine).sort((a, b) => a.t - b.t);\n\nconst of = <T>(lines: readonly Line[], ev: string): T[] => lines.filter((line) => line.ev === ev) as unknown as T[];\n\nexport const requestsOf = (lines: readonly Line[]): Request[] => of<Request>(lines, \"req\");\nexport const podsOf = (lines: readonly Line[]): PodLine[] => of<PodLine>(lines, \"pod\").sort((a, b) => a.t - b.t);\nexport const slicesOf = (lines: readonly Line[], svc: string): SliceLine[] =>\n of<SliceLine>(lines, \"slice\").filter((line) => line.svc === svc);\nexport const rulesOf = (lines: readonly Line[], source: PropagationSource = \"rules\"): RulesLine[] =>\n of<RulesLine>(lines, source).sort((a, b) => a.t - b.t);\nexport const recordsOf = (lines: readonly Line[]): RecordLine[] => of<RecordLine>(lines, \"rec\");\nexport const socketsOf = (lines: readonly Line[]): SocketLine[] => of<SocketLine>(lines, \"sock\").sort((a, b) => a.t - b.t);\n\n/** This function gives the requests that did not succeed, in sequence of their start. */\nexport const failuresOf = (lines: readonly Line[]): Request[] =>\n requestsOf(lines)\n .filter((request) => request.o !== \"ok\")\n .sort((a, b) => a.t - b.t);\n\n/** This function counts the outcomes of the requests, by outcome. */\nexport const outcomesOf = (requests: readonly Request[]): Record<string, number> => {\n const out: Record<string, number> = {};\n for (const request of requests) out[request.o] = (out[request.o] ?? 0) + 1;\n return out;\n};\n\n/**\n * This function orders the replicas by how many clients each one answered last, the most first,\n * then by name. `answers` gives the backend of the last answer of each client, by client. A client\n * of gRPC holds its connection to one replica, thus the first replica is the one whose stop the\n * most clients see.\n */\nexport const byClients = <T extends { readonly pod: string }>(replicas: readonly T[], answers: ReadonlyMap<string, string>): T[] => {\n const count = (pod: string): number => [...answers.values()].filter((backend) => backend === pod).length;\n return [...replicas].sort((a, b) => count(b.pod) - count(a.pod) || a.pod.localeCompare(b.pod));\n};\n\n/** These are the sessions of the clients at an instant: those on the target, of all, and those on the target by client. */\nexport interface Sessions {\n readonly onTarget: number;\n readonly of: number;\n readonly byClient: Readonly<Record<string, number>>;\n}\n\n/**\n * This function gives the sessions of the clients at an instant (`at`), and how many of them are on\n * the target pod. A client sends each request on its next session in turn. Thus its last `connections`\n * requests that started before the instant name its sessions, each by its local port. The backend of\n * a session is the body of the last answer on its port before the instant: the name of the pod. A\n * session with no such answer is not on the target. A request with no port names no session.\n */\nexport const sessionsAt = (lines: readonly Line[], at: number, target: string, connections: number): Sessions => {\n const before = requestsOf(lines)\n .filter((request) => request.t < at)\n .sort((a, b) => a.t - b.t);\n const byClient: Record<string, number> = {};\n let of = 0;\n for (const client of [...new Set(before.map((request) => request.p))].sort()) {\n const mine = before.filter((request) => request.p === client);\n const ports = new Set(mine.slice(-connections).flatMap((request) => (typeof request.lp === \"number\" ? [request.lp] : [])));\n const backend = (port: number): string | undefined => mine.filter((request) => request.lp === port && request.o === \"ok\" && request.b !== undefined).at(-1)?.b;\n byClient[client] = [...ports].filter((port) => backend(port) === target).length;\n of += ports.size;\n }\n return { onTarget: Object.values(byClient).reduce((sum, count) => sum + count, 0), of, byClient };\n};\n\n/**\n * The period of the clients is the interval between the starts of two requests in sequence of one\n * client. Each time is in milliseconds when `A` is a number. The median and the mean are of all the\n * intervals of all the clients, and `low` and `high` are the smallest and the largest interval.\n * `intervals` is their count, and `byClient` is the median of each client. A client with c kept\n * connections sends on each one in turn, thus each of its sessions gets a request each c periods.\n */\nexport interface Period<A = number> {\n readonly median: A;\n readonly mean: A;\n readonly low: A;\n readonly high: A;\n readonly intervals: number;\n readonly byClient: Readonly<Record<string, A>>;\n}\n\n/**\n * This function gives the measured period of the clients from their request lines that start from\n * `from` to `to`. The timer of a client is late by a different amount at each tick. Thus the median\n * stays near the setting of the client (`every`), but the lateness adds up in the mean.\n *\n * The mean is the span of the requests of each client over its intervals. A band can count the requests of a client in a window from the\n * mean. A client with fewer than 2 requests gives no interval. A run with no interval gives null.\n */\nexport const periodOf = (lines: readonly Line[], from: number, to: number): Period | null => {\n const starts = new Map<string, number[]>();\n for (const request of requestsOf(lines)) {\n if (request.t < from || request.t > to) continue;\n const mine = starts.get(request.p) ?? [];\n mine.push(request.t);\n starts.set(request.p, mine);\n }\n const all: number[] = [];\n const byClient: Record<string, number> = {};\n let span = 0;\n for (const client of [...starts.keys()].sort()) {\n const mine = starts.get(client)!.sort((a, b) => a - b);\n if (mine.length < 2) continue;\n const intervals = mine.slice(1).map((t, at) => t - mine[at]!);\n span += mine.at(-1)! - mine[0]!;\n all.push(...intervals);\n byClient[client] = middle(intervals.sort((a, b) => a - b));\n }\n if (all.length === 0) return null;\n all.sort((a, b) => a - b);\n return { median: middle(all), mean: span / all.length, low: all[0]!, high: all.at(-1)!, intervals: all.length, byClient };\n};\n\n/** This function gives the requests of each node, by the name of the node. */\nexport const byNode = (requests: readonly Request[]): Map<string, Request[]> => {\n const out = new Map<string, Request[]>();\n for (const request of requests) out.set(request.n, [...(out.get(request.n) ?? []), request]);\n return out;\n};\n\n/** This function gives the time that the watcher first received a deletion timestamp of one of the pods, after a time. */\nexport const deletionOf = (lines: readonly Line[], pods: readonly string[], after: number): number | null =>\n podsOf(lines).find((pod) => pods.includes(pod.name) && pod.del && pod.t >= after)?.t ?? null;\n\n/**\n * A ztunnel pod line is an event of a ztunnel pod in istio-system, from the watcher (`image/watch.mjs`).\n * Its `type` is the type of the event of the API, and `cs` gives the readiness of each container (`r`).\n */\nexport interface ZtunnelPodLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly node: string | null;\n readonly del: boolean;\n readonly cs: ReadonlyArray<{ readonly r: boolean }>;\n}\n\nexport const ztunnelPodsOf = (lines: readonly Line[]): ZtunnelPodLine[] => of<ZtunnelPodLine>(lines, \"ztunnel-pod\").sort((a, b) => a.t - b.t);\n\n/** This function gives the time that the watcher first received a deletion timestamp of a ztunnel pod, after a time: the reference `restart`. */\nexport const restartOf = (lines: readonly Line[], after: number): number | null => ztunnelPodsOf(lines).find((pod) => pod.del && pod.t >= after)?.t ?? null;\n\n/**\n * This function tells if a restart of ztunnel is over. Each ztunnel pod that got a deletion in the\n * lines is gone. Each node has a ready ztunnel pod with no deletion. It is false when no ztunnel pod\n * got a deletion.\n */\nexport const ztunnelReplaced = (lines: readonly Line[], nodes: readonly string[]): boolean => {\n const last = new Map<string, ZtunnelPodLine>();\n for (const pod of ztunnelPodsOf(lines)) last.set(pod.name, pod);\n const deleted = [...last.values()].filter((pod) => pod.del || pod.type === \"DELETED\");\n if (deleted.length === 0 || deleted.some((pod) => pod.type !== \"DELETED\")) return false;\n const ready = new Set(\n [...last.values()].filter((pod) => !pod.del && pod.type !== \"DELETED\" && pod.cs.length > 0 && pod.cs.every((status) => status.r)).map((pod) => pod.node),\n );\n return nodes.every((node) => ready.has(node));\n};\n\n/** This function gives the stamp of a transition of the service in a pod: the first matching record of a machine, after a time. */\nexport const transitionOf = (\n lines: readonly Line[],\n pod: string,\n machine: string,\n match: (record: RecordLine) => boolean,\n after: number,\n): number | null =>\n recordsOf(lines).find((record) => record.p === pod && record.m === machine && record.at >= after && match(record))?.at ?? null;\n\n/**\n * This function gives the line `stopping` of grpc-go in a pod, after a time. The server writes it at\n * SIGTERM. Then GracefulStop closes its listener and sends GOAWAY on each connection.\n */\nexport const stoppingOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n lines.find((line) => line.ev === \"stopping\" && line[\"p\"] === pod && line.t >= after)?.t ?? null;\n\n/**\n * This function gives when the server of a pod stopped its intake. That is the start of the phase\n * `stop intake` of the service, or the line `stopping` of grpc-go.\n */\nexport const intakeOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n transitionOf(lines, pod, \"drain\", (record) => record.to === \"stop intake\", after) ?? stoppingOf(lines, pod, after);\n\n/** This function gives when the server of a pod received its exit signal: a record of the service, or the line `stopping` of grpc-go. */\nexport const signalOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n transitionOf(lines, pod, \"exit\", (record) => record.on === \"exit.request\", after) ?? stoppingOf(lines, pod, after);\n\n/**\n * This function gives when the rules of a node stopped the selection of a backend: the first poll\n * after a time without it. The change came after `prev`, the poll before it, and at the latest at `t`.\n * The source `eds` gives the same for the client sidecar of the node.\n */\nexport const dropOf = (lines: readonly Line[], node: string, backend: string, after: number, source: PropagationSource = \"rules\"): RulesLine | null =>\n rulesOf(lines, source).find((line) => line.node === node && line.t >= after && !line.b.includes(backend)) ?? null;\n\n/** This function gives when the rules of a node had no backend of the Service, after a time. */\nexport const emptyOf = (lines: readonly Line[], node: string, after: number): RulesLine | null =>\n rulesOf(lines).find((line) => line.node === node && line.t >= after && line.b.length === 0) ?? null;\n\n/** This function gives when an EndpointSlice of the Service first had no ready endpoint, after a time. */\nexport const sliceEmptyOf = (lines: readonly Line[], svc: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;\n\n/** This function gives when an EndpointSlice of the Service first had a ready endpoint, after a time. */\nexport const sliceReadyOf = (lines: readonly Line[], svc: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;\n\n/**\n * This function tells if the latest EndpointSlice of the Service at a time had a ready endpoint. A\n * slice line comes only at a change, thus with no line before the time, it gives null.\n */\nexport const sliceReadyAt = (lines: readonly Line[], svc: string, at: number): boolean | null => {\n const latest = slicesOf(lines, svc).filter((slice) => slice.t <= at).at(-1);\n return latest === undefined ? null : latest.eps.some((endpoint) => endpoint.r === true);\n};\n\n/** This function gives when the endpoint of an address was first not ready in the EndpointSlice of the Service, after a time. */\nexport const sliceDropOf = (lines: readonly Line[], svc: string, ip: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.ip === ip && endpoint.r === true))?.t ?? null;\n\n/** This function gives the latest state of each pod at a time, by its name. A deleted pod is not in it. */\nexport const podsAt = (lines: readonly Line[], at: number): Map<string, PodLine> => {\n const out = new Map<string, PodLine>();\n for (const pod of podsOf(lines)) {\n if (pod.t > at) break;\n if (pod.type === \"DELETED\") out.delete(pod.name);\n else out.set(pod.name, pod);\n }\n return out;\n};\n\n/** This function gives the latest backends of each node at a time, by node. */\nexport const backendsAt = (lines: readonly Line[], at: number): Map<string, readonly string[]> => {\n const out = new Map<string, readonly string[]>();\n for (const line of rulesOf(lines)) {\n if (line.t > at) break;\n out.set(line.node, line.b);\n }\n return out;\n};\n\n/** This function gives the kernel records of the kinds that the lab keeps, counted by kind. */\nexport const kernelCounts = (lines: readonly Line[]): Record<string, number> => {\n const out: Record<string, number> = {};\n for (const line of lines) if (line.ev.startsWith(\"kernel.\")) out[line.ev.slice(7)] = (out[line.ev.slice(7)] ?? 0) + 1;\n return out;\n};\n\n/** This function gives the SIGTERM of each pod in a set after a time, by pod. A pod without one is not in it. */\nexport const signalsOf = (lines: readonly Line[], pods: readonly string[], after: number): Map<string, number> => {\n const out = new Map<string, number>();\n for (const pod of pods) {\n const at = signalOf(lines, pod, after);\n if (at !== null) out.set(pod, at);\n }\n return out;\n};\n\n/** This function gives the restart count of each container of each pod at a time, summed by pod. */\nexport const restartsAt = (lines: readonly Line[], at: number): Map<string, number> => {\n const out = new Map<string, number>();\n for (const [name, pod] of podsAt(lines, at)) out.set(name, pod.cs.reduce((sum, status) => sum + status.rc, 0));\n return out;\n};\n","import { valueIn } from \"@mark1russell7/quantity\";\nimport type { Backoff, ReconnectsPrediction } from \"./cell.ts\";\nimport type { Line } from \"./observe.ts\";\n\n/**\n * This module judges the return of the producers of a message broker after the stop of the broker\n * that owns their topic (SYS-56). It knows the backoff of a client and the lines of the lab, and\n * nothing of Pulsar. Each time is in milliseconds, on the clock of the lines.\n *\n * The backoff is the law of `Backoff::next` of the C++ client of Pulsar 4.2.0 (lib/Backoff.cc,\n * lines 33–57). The first delay is the initial delay, and each next delay is two times the last, up\n * to the most. The first call keeps its time. If a later call ends after the mandatory stop, it\n * gets the rest of the time to that stop, once. Then the call takes a random share of up to the\n * jitter from the delay. The delay is not below the initial delay at any time.\n */\n\n/** A try is the earliest and the latest time of one try to connect, after the first delay starts. */\nexport interface Try {\n readonly lo: number;\n readonly hi: number;\n}\n\n/** This is a backoff in milliseconds. */\ninterface Delays {\n readonly initial: number;\n readonly max: number;\n readonly stop: number;\n readonly jitter: number;\n}\n\nconst delaysOf = (backoff: Backoff): Delays => ({\n initial: valueIn(backoff.initial, \"ms\"),\n max: valueIn(backoff.max, \"ms\"),\n stop: valueIn(backoff.mandatoryStop, \"ms\"),\n jitter: backoff.jitter,\n});\n\n/**\n * This function gives the times of the tries of one path: each delay times `share`, and `latency`\n * from each try to the next call. The tries end with the first one after `until`.\n */\nconst pathOf = (delays: Delays, share: number, latency: number, until: number): number[] => {\n const tries: number[] = [];\n let next = delays.initial;\n let call = 0;\n let made = false;\n for (let count = 0; count < 1000; count += 1) {\n let current = next;\n next = Math.min(2 * next, delays.max);\n if (!made && call + current > delays.stop) {\n current = Math.max(delays.initial, delays.stop - call);\n made = true;\n }\n const at = call + Math.max(delays.initial, current * share);\n tries.push(at);\n if (at > until) break;\n call = at + latency;\n }\n return tries;\n};\n\n/**\n * This function gives the band of each try after the first delay starts, up to the first try whose\n * earliest time is after `until`. The earliest path has the most jitter and no time for a try. The\n * latest path has no jitter and `attempt` for each failed try. A later call gets a delay that ends no\n * earlier, thus each try of a path between them is in the band.\n */\nexport const triesOf = (backoff: Backoff, until: number): Try[] => {\n const delays = delaysOf(backoff);\n const late = pathOf(delays, 1, valueIn(backoff.attempt, \"ms\"), Number.POSITIVE_INFINITY);\n const early = pathOf(delays, 1 - delays.jitter, 0, until);\n return early.map((lo, index) => ({ lo, hi: late[index] ?? Number.POSITIVE_INFINITY }));\n};\n\n/**\n * This function gives the latest return of a producer after the fault, from the bands of the\n * prediction. It adds three terms. The first is the first delay at its latest. The second is the\n * latest time of the first try that cannot come before the latest change of the owner. The third\n * is the latest setup.\n */\nexport const latestReturn = (prediction: ReconnectsPrediction): number => {\n const disconnect = { lo: valueIn(prediction.disconnect.lo, \"ms\"), hi: valueIn(prediction.disconnect.hi, \"ms\") };\n const flip = valueIn(prediction.flip.hi, \"ms\");\n const tries = triesOf(prediction.backoff, flip - disconnect.lo);\n const after = tries.find((each) => each.lo >= flip - disconnect.lo) ?? tries.at(-1)!;\n return disconnect.hi + after.hi + valueIn(prediction.setup.hi, \"ms\");\n};\n\n/** This function gives the delay of each call of a backoff, as an interval, with `elapsed` from the first call to this one. */\nconst delayBand = (delays: Delays, index: number, elapsed: number, made: boolean, noise: number): { lo: number; hi: number; made: boolean; either: boolean } => {\n const nominal = Math.min(delays.initial * 2 ** index, delays.max);\n const band = (current: number) => ({ lo: Math.max(delays.initial, current * (1 - delays.jitter)), hi: Math.max(delays.initial, current) });\n if (made) return { ...band(nominal), made, either: false };\n const clamped = band(Math.max(delays.initial, delays.stop - elapsed));\n const plain = band(nominal);\n // the clock of the client and the clock of the lines differ by up to the noise: near the stop, each branch agrees\n if (Math.abs(elapsed + nominal - delays.stop) <= noise) return { lo: Math.min(clamped.lo, plain.lo), hi: Math.max(clamped.hi, plain.hi), made: false, either: true };\n return elapsed + nominal > delays.stop ? { ...clamped, made: true, either: false } : { ...plain, made: false, either: false };\n};\n\n/** This text is the start of the line of the C++ client that schedules a try: \"Schedule reconnection in 0.1 s\". */\nconst SCHEDULE = /Schedule reconnection in ([0-9.]+) s/;\n\n/** A schedule is one call of the backoff of a producer: when, and its delay in milliseconds. */\nexport interface Schedule {\n readonly t: number;\n readonly delay: number;\n}\n\n/** A return is the facts of one producer in one run. */\nexport interface Return {\n readonly pod: string;\n /** This time is the first call of the backoff after the fault, from the fault. */\n readonly disconnect: number | null;\n /** These are the calls of the backoff from the fault to the producer on the new owner. */\n readonly schedules: readonly Schedule[];\n /** This time is the producer on the new owner, from the fault, or null. */\n readonly back: number | null;\n /** This time is from the try that succeeded to the producer on the new owner. */\n readonly setup: number | null;\n /** This count is the tries up to the one that succeeded. */\n readonly tries: number;\n readonly ok: boolean;\n readonly why: string;\n}\n\n/** A judgement is the facts of one run: the change of the owner, each producer, and the failed sends. */\nexport interface Reconnects {\n readonly ok: boolean;\n readonly why: string;\n /** This time is the first lookup that names another owner, from the fault, or null. */\n readonly flip: number | null;\n /** This time is from the last lookup before that change to it. */\n readonly gap: number | null;\n readonly returns: readonly Return[];\n /** This count is the sends of the producers that failed, by outcome. */\n readonly failures: Readonly<Record<string, number>>;\n /** This time is the median return of the producers, from the fault, or null. */\n readonly value: number | null;\n}\n\nconst text = (line: Line, field: string): string | null => (typeof line[field] === \"string\" ? (line[field] as string) : null);\n\n/**\n * This function judges one run: the fault at `fault`, the broker `broker` that owned the topic, and\n * the lines of the run. A lookup line is `{ev: \"lookup\", t, o, owner}`, a line of the client is\n * `{ev: \"pulsar\", t, p, m}`, and a send is `{ev: \"send\", t, d, o, p}`. `timeout` and `every` are the\n * timeout and the interval of the sends. Each check has a margin of `noise`.\n *\n * For each producer, the delays of its backoff follow the law, from the observed time of each call.\n * Its last try comes after the last lookup that named the old owner. The try before it comes no\n * later than the first lookup that named another. Then the setup is in its band. Each failed send\n * starts between the fault and the return, with an outcome of the prediction. At least one fails.\n *\n * With `owner: \"either\"`, the lookups can name the old owner for the whole run, because it started\n * again and took the topic back. Then the last try comes after the start of the band `flip`. The\n * try before it comes no later than the end of that band.\n */\nexport const judgeReconnects = (\n prediction: ReconnectsPrediction,\n run: { readonly fault: number; readonly broker: string; readonly lines: readonly Line[] },\n sends: { readonly timeout: number; readonly every: number },\n noise: number,\n): Reconnects => {\n const { fault, broker, lines } = run;\n const ms = (band: { readonly lo: Parameters<typeof valueIn>[0]; readonly hi: Parameters<typeof valueIn>[0] }) => ({ lo: valueIn(band.lo, \"ms\"), hi: valueIn(band.hi, \"ms\") });\n const inBand = (value: number, band: { lo: number; hi: number }) => value >= band.lo - noise && value <= band.hi + noise;\n const lookups = lines.filter((line) => line.ev === \"lookup\" && line.t >= fault).sort((a, b) => a.t - b.t);\n const changed = lookups.findIndex((line) => line[\"o\"] === \"ok\" && text(line, \"owner\") !== null && text(line, \"owner\") !== broker);\n const fail = (why: string, more: Partial<Reconnects> = {}): Reconnects => ({ ok: false, why, flip: null, gap: null, returns: [], failures: {}, value: null, ...more });\n if (changed === -1 && prediction.owner !== \"either\") return fail(`no lookup after the fault names an owner other than ${broker}`);\n const band = ms(prediction.flip);\n // the lookups name one broker before and after the change: only the band of the change bounds the tries\n const same = changed === -1;\n const flipAt = same ? fault + band.hi : lookups[changed]!.t;\n const before = same ? fault + band.lo : changed === 0 ? fault : lookups[changed - 1]!.t;\n const flip = same ? null : flipAt - fault;\n const gap = same ? null : flipAt - before;\n if (flip !== null && !inBand(flip, band)) return fail(`the first lookup with another owner is ${flip.toFixed(0)} ms after the fault, outside the band`, { flip, gap });\n if (gap !== null && gap > valueIn(prediction.probe, \"ms\") + noise) return fail(`the lookups have a gap of ${gap.toFixed(0)} ms before the change of the owner`, { flip, gap });\n const delays = delaysOf(prediction.backoff);\n const setup = ms(prediction.setup);\n const disconnect = ms(prediction.disconnect);\n const pods = [...new Set(lines.filter((line) => line.ev === \"send\").map((line) => String(line[\"p\"])))].sort();\n if (pods.length === 0) return fail(\"the run has no sends\", { flip, gap });\n const returns: Return[] = pods.map((pod) => {\n const own = lines.filter((line) => line.ev === \"pulsar\" && line[\"p\"] === pod && line.t >= fault - noise).sort((a, b) => a.t - b.t);\n const created = own.find((line) => (text(line, \"m\") ?? \"\").includes(\"Created producer on broker\"));\n const back = created === undefined ? null : created.t - fault;\n const schedules: Schedule[] = own\n .filter((line) => created === undefined || line.t <= created.t)\n .flatMap((line) => {\n const found = SCHEDULE.exec(text(line, \"m\") ?? \"\");\n return found === null ? [] : [{ t: line.t, delay: Number(found[1]) * 1000 }];\n });\n const first = schedules[0];\n const facts = { pod, disconnect: first === undefined ? null : first.t - fault, schedules, back, tries: schedules.length };\n const no = (why: string, more: Partial<Return> = {}): Return => ({ ...facts, setup: null, ...more, ok: false, why: `${pod}: ${why}` });\n if (created === undefined) return no(\"the producer is not back on a broker after the fault\");\n if (first === undefined) return no(\"the producer schedules no try after the fault\");\n if (!inBand(first.t - fault, disconnect)) return no(`its first try is scheduled ${(first.t - fault).toFixed(0)} ms after the fault, outside the band`);\n let made = false;\n for (const [index, schedule] of schedules.entries()) {\n const band = delayBand(delays, index, schedule.t - first.t, made, noise);\n // the line gives the delay in whole milliseconds\n if (schedule.delay < band.lo - 1 || schedule.delay > band.hi + 1)\n return no(`the delay ${index + 1} is ${schedule.delay} ms, not in ${band.lo.toFixed(0)}–${band.hi.toFixed(0)} ms of the backoff`);\n // near the stop, a delay below the plain band shows that the client took the rest to the stop\n made = band.either ? schedule.delay < Math.min(delays.initial * 2 ** index, delays.max) * (1 - delays.jitter) - 1 : band.made;\n }\n const tries = schedules.map((schedule) => schedule.t + schedule.delay);\n const last = tries.at(-1)!;\n const earlier = tries.at(-2);\n if (last < before - noise) return no(`its last try at ${(last - fault).toFixed(0)} ms comes before the last lookup of the old owner`);\n if (earlier !== undefined && earlier > flipAt + noise) return no(`its try at ${(earlier - fault).toFixed(0)} ms comes after the change of the owner, and it did not succeed`);\n const took = created.t - last;\n if (!inBand(took, setup)) return no(`its setup takes ${took.toFixed(0)} ms, outside the band`, { setup: took });\n return { ...facts, setup: took, ok: true, why: `${pod}: back ${(created.t - fault).toFixed(0)} ms after the fault, at try ${tries.length}` };\n });\n const failed = lines.filter((line) => line.ev === \"send\" && line[\"o\"] !== \"ok\").sort((a, b) => a.t - b.t);\n const failures: Record<string, number> = {};\n for (const line of failed) failures[String(line[\"o\"])] = (failures[String(line[\"o\"])] ?? 0) + 1;\n const backs = returns.flatMap((each) => (each.back === null ? [] : [each.back])).sort((a, b) => a - b);\n const value = backs.length === 0 ? null : backs.length % 2 === 1 ? backs[(backs.length - 1) / 2]! : (backs[backs.length / 2 - 1]! + backs[backs.length / 2]!) / 2;\n const done = (ok: boolean, why: string): Reconnects => ({ ok, why, flip, gap, returns, failures, value });\n const wrong = returns.find((each) => !each.ok);\n if (wrong !== undefined) return done(false, wrong.why);\n const other = failed.find((line) => !prediction.outcomes.includes(String(line[\"o\"])));\n if (other !== undefined) return done(false, `a send of ${String(other[\"p\"])} ended ${String(other[\"o\"])}, not ${prediction.outcomes.join(\" or \")}`);\n if (failed.length === 0) return done(false, \"no send failed\");\n for (const each of returns) {\n const own = failed.filter((line) => line[\"p\"] === each.pod);\n const back = fault + each.back!;\n const outside = own.find((line) => line.t < fault - sends.timeout - noise || line.t > back + noise);\n if (outside !== undefined) return done(false, `a send of ${each.pod} at ${(outside.t - fault).toFixed(0)} ms failed outside the time to its return`);\n const latest = own.at(-1);\n if (latest === undefined) return done(false, `no send of ${each.pod} failed`);\n if (latest.t < back - sends.timeout - sends.every - noise) return done(false, `the last failed send of ${each.pod} is ${(back - latest.t).toFixed(0)} ms before its return`);\n }\n return done(true, `${flip === null ? \"the stopped broker owns the topic again\" : `another owner ${flip.toFixed(0)} ms after the fault`}; ${returns.map((each) => `${each.pod} back at try ${each.tries}`).join(\", \")}`);\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { valueIn } from \"@mark1russell7/quantity\";\nimport { backlogEnd, requestBand, seconds, secondsOf } from \"./bands.ts\";\nimport type { BacklogTerm, Cycle, KindCell, KindRun, Prediction, Reference, ResetReuse, WindowPrediction } from \"./cell.ts\";\nimport { PORT, SERVER } from \"./names.ts\";\nimport type { Line, Period, PropagationSource, Request, Sessions } from \"./observe.ts\";\nimport {\n HBONE_PORT,\n backendsAt,\n TCP_STATE,\n byNode,\n deletionOf,\n dropOf,\n emptyOf,\n failuresOf,\n intakeOf,\n outcomesOf,\n periodOf,\n podsOf,\n requestsOf,\n restartOf,\n sessionsAt,\n signalsOf,\n sliceDropOf,\n sliceEmptyOf,\n sliceReadyAt,\n sliceReadyOf,\n socketsOf,\n tunnelsOf,\n} from \"./observe.ts\";\nimport { RELATIVE, medianInterval, middle } from \"./stats.ts\";\nimport { judgeReconnects, latestReturn } from \"./reconnects.ts\";\n\n/**\n * This time is δ for kind: each time of a run lands in its band ± δ. Its parts are the interval of\n * the poll of the rules (50 ms) and the delay of the watcher. The watcher receives each change after\n * the API server writes it.\n */\nexport const KIND_NOISE: Quantity = { value: 100, unit: \"ms\" };\n/**\n * This time is how much earlier than the end of its window the last failed request can start. A\n * request goes to the closed pod by the choice of the rules, thus the last ones before the end can\n * go to another pod. At 50 requests a second and two pods, 12 requests in sequence miss the closed\n * pod with a chance of 1 in 4096.\n */\nexport const LAST_SLACK: Quantity = { value: 250, unit: \"ms\" };\n\n/** These are δ and the slack in milliseconds, the unit of the stamps. */\nconst NOISE = valueIn(KIND_NOISE, \"ms\");\nconst SLACK = valueIn(LAST_SLACK, \"ms\");\n\n/** A propagated change is when the rules of a node first had it: after the poll `after`, and by the poll `by`. */\nexport interface Propagated<A = Quantity> {\n readonly after: A | null;\n readonly by: A;\n}\n\n/**\n * The facts of a run are what each table reads: its failures by outcome and node, and the times of\n * its target. A count stays a number, and so does a stamp: `first`, `last` and `deletion` are\n * readings of CLOCK_MONOTONIC in milliseconds. Each other time is an amount after a reference. The\n * parameter `A` is the form of an amount: a quantity in the format `/2`, seconds in the format `/1`.\n */\nexport interface RunFacts<A = Quantity> {\n readonly failures: number;\n readonly outcomes: Readonly<Record<string, number>>;\n readonly byNode: Readonly<Record<string, number>>;\n readonly first: number | null;\n readonly last: number | null;\n readonly deletion: number | null;\n readonly intakeAfterDeletion: A | null;\n readonly sliceAfter: A | null;\n /** This record is the propagation of the target to the rules of each node, by node. */\n readonly propagation: Readonly<Record<string, Propagated<A> | null>>;\n /** This time is when the EndpointSlice had no ready endpoint, after the fault (`removal`). */\n readonly sliceEmpty?: A | undefined;\n /** These times are when the rules of each node had no backend, after the fault (`removal`). */\n readonly rules?: Readonly<Record<string, A | null>> | undefined;\n /** This time is when the target left the EndpointSlice, after the fault (`leaves`). */\n readonly left?: A | undefined;\n /** These times are the SIGTERM of each replica, after the fault (`restarts`). */\n readonly signals?: ReadonlyArray<A | null> | undefined;\n /**\n * These are the replicas of a window for each deleted replica (`each`). Each one is a replica of the\n * run with a deletion after its start, with the stamps of its intake and of its deletion.\n */\n readonly deletions?: readonly Deleted[] | undefined;\n /** These are the first LDS updates of the sidecar of each server pod after the fault, by pod (`updatesOf`). */\n readonly updates?: Readonly<Record<string, Propagated<A> | null>> | undefined;\n /** These are the first LDS updates of the sidecar of each server pod after the heal, by pod. */\n readonly healUpdates?: Readonly<Record<string, Propagated<A> | null>> | undefined;\n /** These are the first close of the socket of each client after the reference (`ends`), by client, or null for none. */\n readonly closes?: Readonly<Record<string, A | null>> | undefined;\n /**\n * These are the times of each cycle of a removal with flaps, in the sequence of the cycles. `empty` is\n * when the EndpointSlice had no ready endpoint, after the fault of the cycle. `ready` is when it had a\n * ready endpoint again, after the heal of the cycle. A time that the run does not have is null.\n */\n readonly cycles?: ReadonlyArray<{ readonly empty: A | null; readonly ready: A | null }> | undefined;\n /**\n * These are the sessions of the clients at the fault (`sessionsAt`): those on the target, of all,\n * and those on the target by client. A run of a workload with kept connections and a target has them.\n */\n readonly sessions?: Sessions | undefined;\n /**\n * This is the stall of the target (`app-stall`): its start after the fault, and how long its loop\n * stayed blocked. The app writes a line at each end of the stall. A run with no such line gives null.\n */\n readonly stall?: { readonly start: A | null; readonly held: A | null } | undefined;\n /**\n * This is the measured period of the clients (`periodOf`): the interval between two requests in\n * sequence of one client. It comes from the request lines of the counted span of the run. A run\n * with fewer than 2 requests of each client does not have it. A record before SYS-41 does not have it.\n */\n readonly period?: Period<A> | undefined;\n /**\n * These are the facts of the return of the producers (`reconnects`, SYS-56). They are the first\n * lookup with another owner, the gap of the lookups before it, each producer, and the failed sends\n * by outcome. Each time is from the fault, but `gap`.\n */\n readonly reconnects?: ReconnectsFacts<A> | undefined;\n}\n\n/** These are the facts of the return of the producers of a run (`RunFacts.reconnects`). */\nexport interface ReconnectsFacts<A = Quantity> {\n readonly flip: A | null;\n readonly gap: A | null;\n readonly returns: ReadonlyArray<{ readonly pod: string; readonly disconnect: A | null; readonly back: A | null; readonly setup: A | null; readonly tries: number }>;\n readonly failures: Readonly<Record<string, number>>;\n}\n\n/** A deleted replica is a replica of a run that got a deletion. It gives its pod, and the stamps of its intake (or null) and of its deletion. */\nexport interface Deleted {\n readonly pod: string;\n readonly intake: number | null;\n readonly deletion: number;\n}\n\n/**\n * A run check is the judgement of one run: if it agrees with the prediction, why, its main value,\n * and its facts. The main value is a time, or a count of requests or of replicas (`unitOf`).\n */\nexport interface RunCheck<A = Quantity> {\n readonly ok: boolean;\n readonly why: string;\n readonly value: A | null;\n readonly facts: RunFacts<A>;\n /**\n * This text tells why a run that agrees with the law is past its calibrated band. A request failed\n * after the window, but before the rules of its node dropped the target. Such a run makes its cell\n * `extend`, and the cell does not hold (D-EXTEND).\n */\n readonly tail?: string | undefined;\n}\n\n/** A kind decision is the result of a kind cell. */\nexport type KindDecision = \"holds\" | \"fails\" | \"extend\" | \"measured\" | \"calibration\" | \"void\";\n\n/** A kind verdict is the judgement of a cell on its counted runs. */\nexport interface KindVerdict<A = Quantity> {\n readonly decision: KindDecision;\n readonly counted: number;\n readonly voided: number;\n readonly failed: number;\n /** This amount is the median of the main value of the counted runs, or null. */\n readonly median: A | null;\n readonly why: string;\n readonly checks: ReadonlyArray<RunCheck<A>>;\n}\n\n/**\n * This function gives the unit of the main value of a cell, from its prediction:\n * - `s` for a time: the removal, the departure or the restart of a band, the end of a stall, or a close.\n * - `{request}` for the failed requests: no failure, a window, a fleet that stays, and a measurement.\n * - `{replica}` for the replicas that received SIGTERM, when no replica must restart.\n * - `{socket}` for the sockets of the clients that ended, when no socket must end.\n */\nexport const unitOf = (prediction: { readonly kind: Prediction[\"kind\"]; readonly band?: unknown }): string => {\n switch (prediction.kind) {\n case \"removal\":\n case \"leaves\":\n case \"stalls\":\n case \"reconnects\":\n return \"s\";\n case \"restarts\":\n return prediction.band === null ? \"{replica}\" : \"s\";\n case \"ends\":\n return prediction.band === null ? \"{socket}\" : \"s\";\n default:\n return \"{request}\";\n }\n};\n\nconst sec = (ms: number): number => Math.round(ms) / 1000;\nconst inBand = (value: number, band: { readonly lo: number; readonly hi: number }): boolean =>\n value >= band.lo - NOISE / 1000 && value <= band.hi + NOISE / 1000;\nconst time = (value: number | null): Quantity | null => (value === null ? null : seconds(value));\n\n/**\n * This function tells if a failed request is the reuse of a port that a reset closed. The same\n * client had a reset on the same port, up to `life` before the request. The request ends with\n * `outcome`.\n */\nexport const reusesReset = (request: Request, requests: readonly Request[], reuse: ResetReuse): boolean => {\n if (request.o !== reuse.outcome || request.lp === undefined || request.lp === null) return false;\n const life = valueIn(reuse.life, \"ms\") + NOISE;\n return requests.some(\n (earlier) =>\n earlier.o === \"reset\" &&\n earlier.p === request.p &&\n earlier.lp === request.lp &&\n earlier.t + earlier.d <= request.t &&\n request.t - (earlier.t + earlier.d) <= life,\n );\n};\n\n/**\n * This function gives a reference event of a run, as a stamp, or null when the run does not have it.\n * The references `deletion` and `intake` are those of the target, or of the replica `pod`.\n */\nexport const referenceOf = (run: Pick<KindRun, \"start\" | \"acts\" | \"target\" | \"lines\">, from: Reference, pod: string | undefined = run.target?.pod): number | null => {\n const lines = run.lines as readonly Line[];\n if (from === \"fault\") return run.acts.fault;\n if (from === \"resume\") return run.acts.resume;\n if (from === \"heal\") return run.acts.heal;\n if (from === \"restart\") return restartOf(lines, run.start);\n if (pod === undefined) return null;\n if (from === \"deletion\") return deletionOf(lines, [pod], run.start);\n return intakeOf(lines, pod, run.start);\n};\n\n/**\n * This function gives the cycles of a run: each fault and its heal (`KindRun.acts.cycles`). A run\n * without cycles gives its one fault and heal, or none when it does not have both stamps.\n */\nexport const cyclesOf = (run: Pick<KindRun, \"acts\">): readonly Cycle[] => {\n if (run.acts.cycles !== undefined) return run.acts.cycles;\n const { fault, heal } = run.acts;\n return fault === null || heal === null ? [] : [{ fault, heal }];\n};\n\n/**\n * This function gives the source of the propagation of a cell. In a sidecar mesh, the client sidecar\n * picks the backend of each call from its endpoints (EDS), thus the source is `eds`. Each other cell\n * goes through the rules of kube-proxy (`rules`).\n */\nexport const propagationSource = (cell: Pick<KindCell, \"mesh\">): PropagationSource => (cell.mesh?.mode === \"sidecar\" ? \"eds\" : \"rules\");\n\n/**\n * This function gives the propagation of each node for the target of a run, or for the replica of\n * the address `ip`. It is the time from its deletion (or its crash) to the first poll of the rules\n * of the node without it. The change came between the poll before (`after`) and that poll (`by`).\n * The source `eds` gives the poll of the client sidecar of each node.\n */\nexport const propagationOf = (\n run: KindRun,\n from: number | null,\n ip: string | undefined = run.target?.ip,\n source: PropagationSource = \"rules\",\n): Record<string, Propagated | null> => {\n const out: Record<string, Propagated | null> = {};\n if (ip === undefined || from === null) return out;\n const nodes = [...new Set((run.lines as readonly Line[]).filter((line) => line.ev === source).map((line) => String(line[\"node\"])))].sort();\n for (const node of nodes) {\n const drop = dropOf(run.lines as readonly Line[], node, `${ip}:${PORT}`, from, source);\n out[node] = drop === null ? null : { after: drop.prev === null ? null : seconds(sec(Math.max(0, drop.prev - from))), by: seconds(sec(drop.t - from)) };\n }\n return out;\n};\n\n/**\n * This function gives the first LDS update of the sidecar of each server pod after the stamp `from`.\n * The update came between the poll before (`after`) and the poll that saw it (`by`), after `from`.\n * A poller gives a line at each change of its counters. Thus a line after `from` with a poll before\n * it is an update, when its count `mod` is above the count before `from`. The first line of a poller\n * has no poll before it (`prev` is null), and it is no update.\n */\nexport const updatesOf = (run: Pick<KindRun, \"lines\">, from: number | null): Record<string, Propagated | null> => {\n const out: Record<string, Propagated | null> = {};\n if (from === null) return out;\n const lines = (run.lines as readonly Line[]).filter((line) => line.ev === \"lds\");\n for (const pod of [...new Set(lines.map((line) => String(line[\"pod\"])))].sort()) {\n const own = lines.filter((line) => String(line[\"pod\"]) === pod);\n const before = own.filter((line) => line.t <= from).at(-1);\n const base = before === undefined ? null : Number(before[\"mod\"]);\n const update = own.find((line) => line.t > from && typeof line[\"prev\"] === \"number\" && (base === null || Number(line[\"mod\"]) > base));\n const prev = update === undefined ? null : (update[\"prev\"] as number);\n out[pod] = update === undefined ? null : { after: seconds(sec(Math.max(0, prev! - from))), by: seconds(sec(update.t - from)) };\n }\n return out;\n};\n\n/** This function tells if the judge reads the LDS updates of a cell: the trigger is a policy of Istio. */\nconst listens = (cell: Pick<KindCell, \"trigger\">): boolean => cell.trigger.kind === \"authorization-policy\";\n\n/**\n * This function gives each replica of a run that got a deletion after the start of the run, in the\n * sequence of the deletions. A rolling update deletes each old replica in turn.\n */\nexport const deletionsOf = (run: KindRun): Deleted[] =>\n run.replicas\n .flatMap((replica) => {\n const deletion = referenceOf(run, \"deletion\", replica.pod);\n return deletion === null ? [] : [{ pod: replica.pod, intake: referenceOf(run, \"intake\", replica.pod), deletion }];\n })\n .sort((a, b) => a.deletion - b.deletion);\n\n/** This function tells if a prediction is a window for each deleted replica. */\nconst eachOf = (prediction: Prediction): boolean => prediction.kind === \"window\" && prediction.each === true;\n\n/**\n * A span is one window of a run, as stamps. It gives the replica of its references (or none), and its\n * two references. It also gives its ends with δ, and the deletion of its replica (`origin`). Then it\n * gives the propagation of that deletion to each node, and when the rules of a node dropped its replica.\n */\ninterface Span {\n readonly pod: string | undefined;\n readonly start: number;\n readonly end: number | null;\n readonly lo: number;\n readonly hi: number;\n readonly origin: number | null;\n readonly propagation: RunFacts[\"propagation\"];\n readonly dropped: (node: string) => number | null;\n}\n\n/** This function gives the window of the failed requests of a prediction: a window, the window of `ends`, `leaves`, `removal` or `stays`, or null. */\nconst windowOf = (prediction: Prediction): WindowPrediction | null =>\n prediction.kind === \"window\"\n ? prediction\n : prediction.kind === \"ends\" || prediction.kind === \"leaves\" || prediction.kind === \"removal\"\n ? (prediction.window ?? null)\n : prediction.kind === \"stays\" && prediction.failures?.kind === \"window\"\n ? prediction.failures\n : null;\n\n/**\n * This function gives how long a run observes after the end reference of its last window, or null\n * when its prediction sets no such time. The judge closes a window `end.band.hi` + δ after its end\n * reference. A request that starts by then ends at most the timeout of the workload later: the\n * client cancels it then. A prediction with no window, or a window with no end, sets none.\n */\nexport const observationAfter = (cell: Pick<KindCell, \"prediction\" | \"workload\">): Quantity | null => {\n const window = windowOf(cell.prediction);\n if (window === null || window.end === null) return null;\n // the backlog term closes the window up to n × d later, with n the most sessions on the target,\n // or (n − 1) × d.hi + the slowest drain of one session (SYS-45)\n const backlog = window.backlog;\n const drained =\n backlog === undefined\n ? 0\n : backlog.slowest === undefined || backlog.most < 1\n ? backlog.most * valueIn(backlog.drain.hi, \"ms\")\n : (backlog.most - 1) * valueIn(backlog.drain.hi, \"ms\") + Math.max(valueIn(backlog.slowest, \"ms\"), valueIn(backlog.drain.hi, \"ms\"));\n return seconds(sec(valueIn(window.end.band.hi, \"ms\") + drained + valueIn(cell.workload.timeout, \"ms\") + NOISE));\n};\n\n/**\n * This function gives the earliest end of the observation of a run, as a stamp, or null when its\n * prediction sets none (`observationAfter`). It is that time after the latest end reference of a\n * window: of the target, or with `each`, of each replica that got a deletion. A run that ends before\n * it can miss its own failures. In a rolling update of gRPC, a call waits in the queue of its channel\n * for a stalled connect. It fails only at its timeout (kind run 40128267098). A reference that is not\n * in the lines yet does not count.\n *\n * The band of `ends` also sets an end: its reference, the end of the band and δ. A permitted window\n * sets an end too: its reference, the end of its band, the timeout of the workload and δ.\n */\nexport const observationEnd = (cell: KindCell, run: Pick<KindRun, \"start\" | \"acts\" | \"target\" | \"replicas\" | \"lines\">): number | null => {\n const ends: number[] = [];\n const prediction = cell.prediction;\n if (prediction.kind === \"ends\" && prediction.band !== null) {\n const at = referenceOf(run, prediction.from);\n if (at !== null) ends.push(at + valueIn(prediction.band.hi, \"ms\") + NOISE);\n }\n const after = observationAfter(cell);\n // the producers of a broker: the latest return that the bands permit, then each send that waited for it\n if (prediction.kind === \"reconnects\" && run.acts.fault !== null) ends.push(run.acts.fault + latestReturn(prediction) + valueIn(cell.workload.timeout, \"ms\") + NOISE);\n const window = windowOf(prediction);\n if (after !== null && window !== null && window.end !== null) {\n const from = window.end.from;\n const pods: ReadonlyArray<string | undefined> = window.each === true ? run.replicas.map((replica) => replica.pod) : [run.target?.pod];\n const references = pods.flatMap((pod) => {\n const at = referenceOf(run, from, pod);\n return at === null ? [] : [at];\n });\n if (references.length > 0) ends.push(Math.max(...references) + valueIn(after, \"ms\"));\n }\n // a permitted window closes its band end after its reference: each request that starts in it ends a timeout later\n const permits = window?.permits;\n if (permits !== undefined) {\n const at = referenceOf(run, permits.from, run.target?.pod);\n if (at !== null) ends.push(at + valueIn(permits.band.hi, \"ms\") + valueIn(cell.workload.timeout, \"ms\") + NOISE);\n // the least observation after the reference (SYS-53): a late failure then shows in the record\n if (at !== null && permits.watch !== undefined) ends.push(at + valueIn(permits.watch, \"ms\") + NOISE);\n }\n return ends.length === 0 ? null : Math.max(...ends);\n};\n\n/** This function gives the facts of a run that each table reads: its failures by outcome and node, and the times of its target. */\nexport const factsOf = (cell: KindCell, run: KindRun): RunFacts => {\n const lines = run.lines as readonly Line[];\n const failures = failuresOf(lines).filter((request) => request.t >= run.start && request.t <= run.end);\n const deletion = referenceOf(run, \"deletion\");\n const intake = referenceOf(run, \"intake\");\n const crash = cell.trigger.kind === \"crash\" ? run.acts.fault : null;\n const from = deletion ?? crash;\n const period = periodOf(lines, run.start, run.end);\n return {\n failures: failures.length,\n outcomes: outcomesOf(failures),\n byNode: Object.fromEntries([...byNode(failures)].map(([node, list]) => [node, list.length])),\n first: failures.length === 0 ? null : failures[0]!.t,\n last: failures.length === 0 ? null : failures.at(-1)!.t,\n deletion,\n intakeAfterDeletion: deletion === null || intake === null ? null : seconds(sec(intake - deletion)),\n sliceAfter: run.target === null || from === null ? null : time((() => {\n const at = sliceDropOf(lines, SERVER, run.target!.ip, from);\n return at === null ? null : sec(at - from);\n })()),\n propagation: propagationOf(run, from, undefined, propagationSource(cell)),\n ...(eachOf(cell.prediction) ? { deletions: deletionsOf(run) } : {}),\n ...(listens(cell) ? { updates: updatesOf(run, run.acts.fault), healUpdates: updatesOf(run, run.acts.heal) } : {}),\n ...(cell.workload.connections !== undefined && run.target !== null && run.acts.fault !== null\n ? { sessions: sessionsAt(lines, run.acts.fault, run.target.pod, cell.workload.connections) }\n : {}),\n ...(cell.trigger.kind === \"app-stall\" ? { stall: stallFactOf(run) } : {}),\n ...(period === null ? {} : { period: periodFact(period) }),\n };\n};\n\n/** This function gives a time in milliseconds in seconds, to the microsecond. A period of a client is approximately 10 ms, thus a whole millisecond is too coarse. */\nconst fine = (ms: number): Quantity => seconds(Math.round(ms * 1000) / 1e6);\n\n/** This function gives the period of the clients (`periodOf`) with each time in seconds. */\nconst periodFact =(period: Period): Period<Quantity> => ({\n median: fine(period.median),\n mean: fine(period.mean),\n low: fine(period.low),\n high: fine(period.high),\n intervals: period.intervals,\n byClient: Object.fromEntries(Object.entries(period.byClient).map(([client, ms]) => [client, fine(ms)])),\n});\n\n/**\n * This function gives the stall of the target in a run. It is the start of its line `stall` after the\n * fault, and the time that the app gives in its end line (`held`). A time that the run does not have is null.\n */\nconst stallFactOf = (run: KindRun): { readonly start: Quantity | null; readonly held: Quantity | null } => {\n const fault = run.acts.fault;\n const pod = run.target?.pod;\n const mine = (run.lines as readonly Line[]).filter((line) => line.ev === \"stall\" && (pod === undefined || line[\"p\"] === pod) && line.t >= run.start);\n const start = mine.find((line) => line[\"phase\"] === \"start\");\n const end = mine.find((line) => line[\"phase\"] === \"end\");\n const held = end === undefined ? undefined : Number(end[\"held\"]);\n return {\n start: start === undefined || fault === null ? null : seconds(sec(start.t - fault)),\n held: held === undefined || !Number.isFinite(held) ? null : seconds(sec(held)),\n };\n};\n\ntype Done = (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck;\n\n/**\n * This function judges a removal with flaps. In each cycle, the Service has no ready endpoint, and the\n * rules of each node have no backend, in the band after its fault. Each time comes before the fault of\n * the next cycle. At the fault of each cycle after the first, the Service has a ready endpoint and the\n * rules of each node a backend. After the last heal, the Service has a ready endpoint again. The main\n * value is the empty Service of the first cycle.\n */\nconst removalOfCycles = (cell: KindCell, run: KindRun, prediction: Extract<Prediction, { kind: \"removal\" }>, done: Done): RunCheck => {\n const lines = run.lines as readonly Line[];\n const cycles = cyclesOf(run);\n if (cycles.length === 0) return done(false, \"the run has no cycle of a fault and its heal\", null);\n const band = secondsOf(prediction.band);\n const nodes = [...new Set(lines.filter((line) => line.ev === \"rules\").map((line) => String(line[\"node\"])))].sort();\n const problems: string[] = [];\n const times: Array<{ readonly empty: Quantity | null; readonly ready: Quantity | null }> = [];\n let rules: Record<string, Quantity | null> = {};\n cycles.forEach((cycle, k) => {\n const n = k + 1;\n const next = cycles[k + 1]?.fault ?? run.end;\n // the slice and the rules give a line only at a change, thus the first cycle starts at rest\n if (k > 0) {\n if (sliceReadyAt(lines, SERVER, cycle.fault) !== true) problems.push(`the Service had no ready endpoint at the fault of the cycle ${n}`);\n const backends = backendsAt(lines, cycle.fault);\n for (const node of nodes) if ((backends.get(node) ?? []).length === 0) problems.push(`the rules of ${node} had no backend at the fault of the cycle ${n}`);\n }\n const empty = sliceEmptyOf(lines, SERVER, cycle.fault);\n const value = empty === null || empty > next ? null : sec(empty - cycle.fault);\n if (value === null) problems.push(`the Service kept a ready endpoint in the cycle ${n}`);\n else if (!inBand(value, band)) problems.push(`the EndpointSlice had no ready endpoint at ${value} s in the cycle ${n}`);\n const own: Record<string, Quantity | null> = {};\n for (const node of nodes) {\n const drop = emptyOf(lines, node, cycle.fault);\n const at = drop === null || drop.t > next ? null : sec(drop.t - cycle.fault);\n own[node] = at === null ? null : seconds(at);\n if (at === null) problems.push(`the rules of ${node} kept a backend in the cycle ${n}`);\n else if (!inBand(at, { lo: band.lo, hi: band.hi + 0.05 })) problems.push(`the rules of ${node} had no backend at ${at} s in the cycle ${n}`);\n }\n if (k === 0) rules = own;\n const ready = sliceReadyOf(lines, SERVER, cycle.heal);\n const back = ready === null || ready > next ? null : sec(ready - cycle.heal);\n if (k === cycles.length - 1 && back === null) problems.push(\"the Service had no ready endpoint after the last heal\");\n times.push({ empty: value === null ? null : seconds(value), ready: back === null ? null : seconds(back) });\n });\n const first = times[0]!.empty === null ? null : valueIn(times[0]!.empty, \"s\");\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const empties = times.map((each) => (each.empty === null ? \"none\" : `${valueIn(each.empty, \"s\")} s`)).join(\", \");\n const agrees = `the Service was empty in each of ${cycles.length} cycles, at ${empties} after its fault${inner === null ? \"\" : `; ${inner.why}`}`;\n const more: Partial<RunFacts> = { ...(inner === null ? {} : inner.facts), ...(first === null ? {} : { sliceEmpty: seconds(first) }), rules, cycles: times };\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), first, more);\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n};\n\n/**\n * This function counts the failed requests of a run with the backlog term (`requestBand`). The span\n * is from the start of the window to the end band without the term. The turn of a session comes\n * from the measured mean period of the clients. A run with no measured period cannot be counted.\n */\nconst countOf = (\n cell: KindCell,\n window: WindowPrediction,\n term: BacklogTerm,\n onTarget: number,\n period: Period<Quantity> | undefined,\n failed: number,\n): { readonly ok: boolean; readonly why: string } => {\n if (period === undefined) return { ok: false, why: \"the run has no measured period, thus the backlog term cannot count its failed requests\" };\n const span = seconds(Math.round((valueIn(window.end!.band.hi, \"s\") - valueIn(window.start.band.lo, \"s\")) * 1e6) / 1e6);\n const band = requestBand(term, span, period.mean, cell.workload.connections ?? 1, onTarget);\n const at = `the count [${band.lo}, ${band.hi}] of ${onTarget} session${onTarget === 1 ? \"\" : \"s\"} on the target at a mean period of ${Math.round(valueIn(period.mean, \"ms\") * 1000) / 1000} ms`;\n return failed >= band.lo && failed <= band.hi ? { ok: true, why: `in ${at}` } : { ok: false, why: `${failed} failed requests, outside ${at}` };\n};\n\n/** This function judges one run against the prediction of its cell. */\nexport const checkRun =(cell: KindCell, run: KindRun): RunCheck => {\n const lines = run.lines as readonly Line[];\n const facts = factsOf(cell, run);\n const failures = failuresOf(lines).filter((request) => request.t >= run.start && request.t <= run.end);\n const prediction = cell.prediction;\n const unit = unitOf(prediction);\n const done = (ok: boolean, why: string, value: number | null, more: Partial<RunFacts> = {}): RunCheck => ({\n ok,\n why,\n value: value === null ? null : { value, unit },\n facts: { ...facts, ...more },\n });\n switch (prediction.kind) {\n case \"none\": {\n const excluded = prediction.outcomes;\n const counted = excluded === undefined ? failures : failures.filter((request) => excluded.includes(request.o));\n const what = excluded === undefined ? \"requests failed\" : `requests ended ${excluded.join(\", \")}`;\n return done(counted.length === 0, counted.length === 0 ? `no ${excluded === undefined ? \"request failed\" : `request ended ${excluded.join(\", \")}`}` : `${counted.length} ${what}: ${JSON.stringify(facts.outcomes)}`, counted.length);\n }\n case \"window\": {\n const each = prediction.each === true;\n const opens = secondsOf(prediction.start.band);\n // the backlog term: n × d more at each end of the end band, with n the sessions on the target at the fault\n const backlog = prediction.backlog;\n const onTarget = facts.sessions?.onTarget;\n if (backlog !== undefined && (prediction.end === null || prediction.end.from !== prediction.start.from || onTarget === undefined))\n return done(\n false,\n onTarget === undefined ? \"the run has no sessions on the target at the fault, thus the backlog term has no n\" : \"a window with the backlog term has an end with the reference of its start\",\n null,\n );\n const closes = prediction.end === null ? null : secondsOf(backlog === undefined ? prediction.end.band : backlogEnd(prediction.end.band, backlog, onTarget!));\n // a request after a window that started before the rules of its node dropped the replica of that\n // window agrees with the law: only the calibrated band is short (D-EXTEND). A request after the drop is still late\n const droppedAfter = (origin: number | null, propagation: RunFacts[\"propagation\"]) => (node: string): number | null => {\n const propagated = propagation[node];\n return origin === null || propagated === undefined || propagated === null ? null : origin + valueIn(propagated.by, \"ms\");\n };\n // the window of the target, or with `each` the window of each replica that got a deletion\n const pods: ReadonlyArray<string | undefined> = each ? (facts.deletions ?? []).map((deleted) => deleted.pod) : [run.target?.pod];\n if (pods.length === 0) return done(false, \"no replica of the run got a deletion\", null);\n // with flaps, the window of each cycle: its own fault and heal\n const flaps = prediction.flaps === true;\n const cyclic = (from: Reference): from is \"fault\" | \"heal\" => from === \"fault\" || from === \"heal\";\n if (flaps && (each || !cyclic(prediction.start.from) || (prediction.end !== null && !cyclic(prediction.end.from))))\n return done(false, \"a window with flaps has no each, and its references are the fault and the heal\", null);\n const cycles = flaps ? cyclesOf(run) : [];\n if (flaps && cycles.length === 0) return done(false, \"the run has no cycle of a fault and its heal\", null);\n const sources: ReadonlyArray<{ readonly pod: string | undefined; readonly cycle: Cycle | undefined }> = flaps\n ? cycles.map((cycle) => ({ pod: run.target?.pod, cycle }))\n : pods.map((pod) => ({ pod, cycle: undefined }));\n const windows: Span[] = [];\n for (const { pod, cycle } of sources) {\n const at = (from: Reference): number | null => (cycle !== undefined && cyclic(from) ? cycle[from] : referenceOf(run, from, pod));\n const start = at(prediction.start.from);\n const end = prediction.end === null ? null : at(prediction.end.from);\n if (start === null || (prediction.end !== null && end === null))\n return done(false, `the run has no ${start === null ? prediction.start.from : prediction.end!.from} reference${each ? ` for ${pod}` : \"\"}`, null);\n const origin = each ? referenceOf(run, \"deletion\", pod) : (facts.deletion ?? (cell.trigger.kind === \"crash\" ? run.acts.fault : null));\n const ip = run.replicas.find((replica) => replica.pod === pod)?.ip;\n const propagation = each ? propagationOf(run, origin, ip, propagationSource(cell)) : facts.propagation;\n windows.push({\n pod,\n start,\n end,\n lo: start + opens.lo * 1000 - NOISE,\n hi: end === null ? Number.POSITIVE_INFINITY : end + closes!.hi * 1000 + NOISE,\n origin,\n propagation,\n dropped: droppedAfter(origin, propagation),\n });\n }\n // a node that dropped the replica of a window after the propagation of the prediction, or kept it\n // past that bound to the end of the run: the run agrees with the law, but the band is short (D-EXTEND)\n const bound = prediction.propagation === undefined ? null : secondsOf(prediction.propagation).hi * 1000 + NOISE;\n const lateOf = (origin: number, propagated: { readonly by: Quantity } | null) => {\n const by = propagated === null ? null : valueIn(propagated.by, \"ms\");\n return { by, late: bound !== null && (by === null ? run.end - origin > bound : by > bound) };\n };\n // for a policy, the propagation is the LDS update of each server sidecar after the fault and after the heal\n const listened = listens(cell);\n const updates = (facts.updates ?? {}) as Readonly<Record<string, Propagated | null>>;\n const healUpdates = (facts.healUpdates ?? {}) as Readonly<Record<string, Propagated | null>>;\n const slow =\n bound === null\n ? []\n : listened\n ? ([[run.acts.fault, updates, \"the policy\"], [run.acts.heal, healUpdates, \"the delete of the policy\"]] as const).flatMap(([origin, by, what]) =>\n origin === null\n ? []\n : Object.entries(by).flatMap(([pod, propagated]) => {\n const late = lateOf(origin, propagated);\n return late.late ? [{ pod: what, node: pod, by: late.by }] : [];\n }),\n )\n : windows.flatMap(({ pod, origin, propagation }) =>\n origin === null\n ? []\n : Object.entries(propagation).flatMap(([node, propagated]) => {\n const late = lateOf(origin, propagated);\n return late.late ? [{ pod, node, by: late.by }] : [];\n }),\n );\n // the last LDS update after the heal: a call to its replica can fail until the next call to it after the update\n const lastHeal =\n !listened || run.acts.heal === null\n ? null\n : Object.values(healUpdates).reduce<number | null>((max, propagated) => (propagated === null ? max : Math.max(max ?? 0, valueIn(propagated.by, \"ms\"))), null);\n // a failure in the permitted window, outside each window and with a permitted outcome, does not count (SYS-51)\n const permits = prediction.permits;\n const permitAt = permits === undefined ? null : referenceOf(run, permits.from, run.target?.pod);\n if (permits !== undefined && permitAt === null) return done(false, `the run has no ${permits.from} reference for the permitted window`, null);\n const permitted = (request: Request): boolean =>\n permits !== undefined &&\n permitAt !== null &&\n permits.outcomes.includes(request.o) &&\n request.t >= permitAt + valueIn(permits.band.lo, \"ms\") - NOISE &&\n request.t <= permitAt + valueIn(permits.band.hi, \"ms\") + NOISE &&\n windows.every((window) => request.t < window.lo || request.t > window.hi);\n const allowedLate = failures.filter(permitted);\n const counting = allowedLate.length === 0 ? failures : failures.filter((request) => !allowedLate.includes(request));\n const relevant: Request[] = prediction.nodes === \"paused\" ? counting.filter((request) => request.n === run.paused) : counting;\n const others = prediction.nodes === \"paused\" ? counting.filter((request) => request.n !== run.paused) : [];\n const reuse = prediction.afterReset;\n const late = relevant.filter((request) => windows.every((window) => request.t < window.lo || request.t > window.hi));\n // a request outside the window that reuses the port of a reset is the CLOSE entry of that reset\n const reused = reuse === undefined ? [] : late.filter((request) => reusesReset(request, failures, reuse));\n const tailOf = (request: Request): Span | undefined =>\n reused.includes(request)\n ? undefined\n : windows.find((window) => {\n const drop = request.t > window.hi ? window.dropped(request.n) : null;\n return drop !== null && request.t <= drop + NOISE;\n });\n // a denial after the window, before the last LDS update after the heal and the next call to its replica\n const healTail = (request: Request): boolean =>\n lastHeal !== null && request.t > windows[0]!.hi && request.t <= run.acts.heal! + lastHeal + SLACK + NOISE;\n const tail = late.filter((request) => tailOf(request) !== undefined || healTail(request));\n const outside = late.filter((request) => !reused.includes(request) && !tail.includes(request));\n // a window that names its outcomes allows no other failure in it\n const allowed = prediction.outcomes;\n const wrong = allowed === undefined ? [] : relevant.filter((request) => !late.includes(request) && !allowed.includes(request.o));\n const bounds = (window: Span): string => `[${sec(window.lo - window.start)}, ${sec(window.hi - window.start)}] s`;\n const problems: string[] = [];\n if (outside.length > 0)\n problems.push(\n each\n ? `${outside.length} failed requests outside the window of each deleted replica: ${windows.map((window) => `${window.pod} ${bounds(window)}`).join(\", \")} after its ${prediction.start.from}`\n : flaps\n ? `${outside.length} failed requests outside the window of each cycle: ${windows.map((window, k) => `${k + 1} ${bounds(window)}`).join(\", \")} after its ${prediction.start.from}`\n : `${outside.length} failed requests outside ${bounds(windows[0]!)} after ${prediction.start.from}`,\n );\n if (others.length > 0) problems.push(`${others.length} failed requests on nodes whose kube-proxy did not pause`);\n if (wrong.length > 0) problems.push(`${wrong.length} failed requests in the window ended ${JSON.stringify(outcomesOf(wrong))}, not ${allowed!.join(\", \")}`);\n if (prediction.certain && relevant.length === 0) problems.push(\"no request failed in a window that the law opens\");\n // the backlog term counts the failed requests of the n sessions from the measured period of the clients\n const counted = backlog === undefined ? null : countOf(cell, prediction, backlog, onTarget!, facts.period, relevant.length);\n if (counted !== null && !counted.ok) problems.push(counted.why);\n // the window that ends last: the last failed request comes near its end\n const final = windows.reduce((a, b) => ((b.end ?? Number.NEGATIVE_INFINITY) > (a.end ?? Number.NEGATIVE_INFINITY) ? b : a));\n // with flaps, each cycle has a failed request, and its last one comes near the end of its window\n if (flaps && prediction.certain && relevant.length > 0) {\n windows.forEach((window, k) => {\n const own = relevant.filter((request) => request.t >= window.lo && request.t <= window.hi);\n if (own.length === 0) problems.push(`no request failed in the window of the cycle ${k + 1}`);\n else if (window.end !== null) {\n const earliest = window.end + closes!.lo * 1000 - NOISE - SLACK;\n if (own.at(-1)!.t < earliest) problems.push(`the last failed request of the cycle ${k + 1} started ${sec(earliest - own.at(-1)!.t)} s before its window can end`);\n }\n });\n }\n if (!flaps && prediction.certain && final.end !== null && relevant.length > 0) {\n const last = relevant.at(-1)!.t;\n const earliest = final.end + closes!.lo * 1000 - NOISE - SLACK;\n if (last < earliest) problems.push(`the last failed request started ${sec(earliest - last)} s before the window can end`);\n }\n const inside = relevant.filter((request) => !late.includes(request));\n const span = inside.length === 0 ? 0 : sec(inside.at(-1)!.t - inside[0]!.t);\n const where = each ? `the windows of ${windows.length} deleted replicas` : flaps ? `the windows of ${windows.length} cycles` : \"the window\";\n const agrees =\n (reused.length === 0\n ? `${relevant.length} failed requests, all in ${where} (span ${span} s)`\n : `${inside.length} failed requests in ${where} (span ${span} s), and ${reused.length} on a port that a reset closed`) +\n (counted === null ? \"\" : `, ${counted.why}`) +\n // the law permits these failures, thus they do not make the cell extend\n (allowedLate.length === 0 ? \"\" : `; ${allowedLate.length} failed requests in the permitted window after the ${permits!.from}: ${JSON.stringify(outcomesOf(allowedLate))}`);\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), relevant.length);\n if (problems.length > 0) return checked;\n const notes: string[] = [];\n if (tail.length > 0) {\n const last = tail.at(-1)!;\n const after = tailOf(last);\n notes.push(\n after === undefined\n ? `${tail.length} failed requests after the window, the last ${sec(last.t - windows[0]!.hi + NOISE)} s after it, before the last LDS update after the heal and the next call to its replica`\n : each\n ? `${tail.length} failed requests after a window, the last ${sec(last.t - after.hi + NOISE)} s after the window of ${after.pod} on ${last.n}, before the rules of ${last.n} dropped ${after.pod}`\n : `${tail.length} failed requests after the window, the last ${sec(last.t - after.hi + NOISE)} s after it on ${last.n}, before the rules of ${last.n} dropped the target`,\n );\n }\n if (slow.length > 0) {\n // a node that kept its replica to the end of the run is the latest\n const latest = slow.find((late) => late.by === null) ?? slow.reduce((a, b) => (b.by! > a.by! ? b : a));\n const bandHi = secondsOf(prediction.propagation!).hi;\n if (listened) {\n const update = latest.by === null ? `had no LDS update after ${latest.pod}` : `had its LDS update ${sec(latest.by)} s after ${latest.pod}`;\n notes.push(`${slow.length} LDS updates after the propagation of ${bandHi} s at the most, the latest: the sidecar of ${latest.node} ${update}`);\n } else {\n const what = each ? latest.pod : \"the target\";\n const drop = latest.by === null ? `kept ${what} to the end of the run` : `dropped ${what} ${sec(latest.by)} s after its deletion`;\n notes.push(`${slow.length} drops after the propagation of ${bandHi} s at the most, the latest: the rules of ${latest.node} ${drop}`);\n }\n }\n return notes.length === 0 ? checked : { ...checked, tail: notes.join(\"; \") };\n }\n case \"removal\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n if (prediction.flaps === true) return removalOfCycles(cell, run, prediction, done);\n const empty = sliceEmptyOf(lines, SERVER, fault);\n if (empty === null) return done(false, \"the Service kept a ready endpoint\", null);\n const value = sec(empty - fault);\n const band = secondsOf(prediction.band);\n const problems: string[] = [];\n if (!inBand(value, band)) problems.push(`the EndpointSlice had no ready endpoint at ${value} s`);\n const nodes = [...new Set(lines.filter((line) => line.ev === \"rules\").map((line) => String(line[\"node\"])))].sort();\n const rules: Record<string, Quantity | null> = {};\n for (const node of nodes) {\n const drop = emptyOf(lines, node, fault);\n rules[node] = drop === null ? null : seconds(sec(drop.t - fault));\n if (drop === null) problems.push(`the rules of ${node} kept a backend`);\n else if (!inBand(sec(drop.t - fault), { lo: band.lo, hi: band.hi + 0.05 }))\n problems.push(`the rules of ${node} had no backend at ${sec(drop.t - fault)} s`);\n }\n // with a window, the failed requests of the run must also agree with it, as with `leaves`\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const agrees = inner === null ? `the Service was empty at ${value} s` : `the Service was empty at ${value} s; ${inner.why}`;\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), value, { ...(inner === null ? {} : inner.facts), sliceEmpty: seconds(value), rules });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"leaves\": {\n const fault = run.acts.fault;\n if (fault === null || run.target === null) return done(false, \"the run has no fault stamp or no target\", null);\n const at = sliceDropOf(lines, SERVER, run.target.ip, fault);\n if (at === null) return done(false, `${run.target.pod} stayed ready in the EndpointSlice`, null);\n const value = sec(at - fault);\n const band = secondsOf(prediction.band);\n const problems: string[] = [];\n if (!inBand(value, band)) problems.push(`${run.target.pod} left the EndpointSlice at ${value} s`);\n const propagation = propagationOf(run, fault, undefined, propagationSource(cell));\n // the kube-proxy of a lost zone is frozen with its node, thus only the rules of the other nodes count\n const lost = cell.trigger.kind === \"zone-loss\" ? run.paused : null;\n for (const [node, drop] of Object.entries(propagation)) {\n if (node === lost) continue;\n const by = drop === null ? null : valueIn(drop.by, \"s\");\n if (by === null) problems.push(`the rules of ${node} kept ${run.target.pod}`);\n else if (!inBand(by, { lo: band.lo, hi: band.hi + 0.05 })) problems.push(`the rules of ${node} dropped it at ${by} s`);\n }\n // with a window, the failed requests of the run must also agree with it, as with `ends`\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const left = inner === null ? `${run.target.pod} left at ${value} s` : `${run.target.pod} left at ${value} s; ${inner.why}`;\n const checked = done(problems.length === 0, problems.length === 0 ? left : problems.join(\"; \"), value, { ...(inner === null ? {} : inner.facts), left: seconds(value), propagation });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"restarts\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n const until = run.acts.heal ?? run.end;\n const pods = run.replicas.map((replica) => replica.pod);\n const signals = signalsOf(lines, pods, fault);\n const inside = [...signals].filter(([, at]) => at <= until);\n if (prediction.band === null)\n return done(inside.length === 0, inside.length === 0 ? \"no replica received SIGTERM\" : `${inside.length} replicas received SIGTERM`, inside.length);\n const band = secondsOf(prediction.band);\n const times = pods.map((pod) => {\n const at = signals.get(pod);\n return at === undefined ? null : sec(at - fault);\n });\n const missing = times.filter((each) => each === null).length;\n const off = times.filter((each): each is number => each !== null && !inBand(each, band));\n const known = times.filter((each): each is number => each !== null).sort((a, b) => a - b);\n const ok = missing === 0 && off.length === 0;\n return done(ok, ok ? `each replica received SIGTERM, at ${known.join(\", \")} s` : `${missing} replicas without SIGTERM, ${off.length} outside the band (${known.join(\", \")} s)`, known.length === 0 ? null : middle(known), { signals: times.map(time) });\n }\n case \"stays\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n const until = run.end;\n const dropped = run.replicas.filter((replica) => {\n const at = sliceDropOf(lines, SERVER, replica.ip, fault);\n return at !== null && at <= until;\n });\n const refused = failures.filter((request) => request.o === \"refused\" && request.t >= fault);\n const problems: string[] = [];\n if (dropped.length > 0) problems.push(`${dropped.length} replicas left the EndpointSlice`);\n if (refused.length > 0) problems.push(`${refused.length} requests were refused`);\n // the failed requests of a slow dependency: a window, or none\n const inner = prediction.failures === undefined ? null : checkRun({ ...cell, prediction: prediction.failures }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const agrees = `the replicas stayed ready, ${failures.length} requests failed by their dependency${inner === null ? \"\" : `; ${inner.why}`}`;\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), failures.length, inner === null ? {} : inner.facts);\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"stalls\": {\n const fault = run.acts.fault;\n const heal = run.acts.heal;\n if (fault === null || heal === null) return done(false, \"the run has no fault or heal stamp\", null);\n const old = new Set(run.replicas.map((replica) => replica.pod));\n // only the replicas of the service: the pod of Redis is not a part of the rollout\n const servers = podsOf(lines).filter((pod) => pod.labels[\"app\"] === SERVER);\n const pods = servers.filter((pod) => pod.t >= fault && pod.t <= heal);\n const deleted = pods.filter((pod) => old.has(pod.name) && pod.del);\n const newReady = pods.filter((pod) => !old.has(pod.name) && pod.ready);\n const after = servers.filter((pod) => pod.t > heal);\n const firstReady = after.find((pod) => !old.has(pod.name) && pod.ready);\n const finished = firstReady !== undefined && after.some((pod) => old.has(pod.name) && pod.type === \"DELETED\");\n const problems: string[] = [];\n if (deleted.length > 0) problems.push(`${new Set(deleted.map((pod) => pod.name)).size} old pods were deleted while Redis was down`);\n if (newReady.length > 0) problems.push(\"a new pod became ready while Redis was down\");\n if (!finished) problems.push(\"the rollout did not continue after Redis came back\");\n if (problems.length === 0)\n return done(true, `the rollout waited for Redis, and its first new pod was ready ${sec(firstReady!.t - heal)} s after Redis came back`, sec(firstReady!.t - heal));\n return done(false, problems.join(\"; \"), null);\n }\n case \"ends\":\n return checkEnds(cell, run, prediction, done);\n case \"reconnects\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no stamp of the fault\", null);\n if (run.broker === undefined) return done(false, \"the run has no broker that owned the topic at the fault\", null);\n const judged = judgeReconnects(prediction, { fault, broker: run.broker, lines }, { timeout: valueIn(cell.workload.timeout, \"ms\"), every: valueIn(cell.workload.every, \"ms\") }, NOISE);\n const time = (value: number | null): Quantity | null => (value === null ? null : { value: sec(value), unit: \"s\" });\n const reconnects: ReconnectsFacts = {\n flip: time(judged.flip),\n gap: time(judged.gap),\n returns: judged.returns.map((each) => ({ pod: each.pod, disconnect: time(each.disconnect), back: time(each.back), setup: time(each.setup), tries: each.tries })),\n failures: judged.failures,\n };\n // the requests of the control go to the service of the cell, and the fault of the broker does not touch it\n if (failures.length > 0) return done(false, `${failures.length} requests of the control failed: ${JSON.stringify(facts.outcomes)}`, null, { reconnects });\n return done(judged.ok, judged.why, judged.value === null ? null : sec(judged.value), { reconnects });\n }\n case \"measured\":\n return done(true, \"measured\", facts.failures);\n }\n};\n\n/**\n * This function judges a run against a prediction `ends`. Each client with an answer before the\n * reference is a client of the run. Its socket is the port of that answer (`lp`).\n * - With a band, the first close of a socket of each client after the reference must be in the band\n * ± δ. It must be the close of that socket. The main value is the middle of these times.\n * - With no band, no socket of a client can close after the reference. The first request of each client\n * after the heal must be `ok` on that socket. The main value is the count of the closes.\n *\n * With a window, the failed requests of the run must also agree with that window (`checkRun`). A\n * prediction of the tunnels (`of: \"tunnel\"`) has its own judge (`checkTunnels`).\n */\nconst checkEnds = (\n cell: KindCell,\n run: KindRun,\n prediction: Extract<Prediction, { readonly kind: \"ends\" }>,\n done: (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck,\n): RunCheck => {\n const from = referenceOf(run, prediction.from);\n if (from === null) return done(false, `the run has no ${prediction.from} reference`, null);\n if (prediction.of === \"tunnel\") return checkTunnels(run, prediction, from, done);\n const lines = run.lines as readonly Line[];\n const calls = requestsOf(lines)\n .filter((request) => request.t >= run.start && request.t <= run.end)\n .sort((a, b) => a.t - b.t);\n // each client of the run, with its last answer before the reference\n const last = new Map<string, Request>();\n for (const request of calls) if (request.t < from && request.o === \"ok\") last.set(request.p, request);\n if (last.size === 0) return done(false, `no client had an answer before the ${prediction.from}`, null);\n const clients = [...last.keys()].sort();\n const shut = socketsOf(lines).filter((line) => line.what === \"close\" && line.t >= from && line.t <= run.end);\n const closes: Record<string, Quantity | null> = {};\n const times: number[] = [];\n const problems: string[] = [];\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n closes[client] = close === undefined ? null : seconds(sec(close.t - from));\n if (close !== undefined) times.push(sec(close.t - from));\n }\n let agrees: string;\n let value: number | null;\n if (prediction.band !== null) {\n const band = secondsOf(prediction.band);\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n const port = last.get(client)!.lp ?? null;\n if (close === undefined) problems.push(`the socket of ${client} did not end`);\n else if (port !== null && close.lp !== null && close.lp !== port) problems.push(`the first socket of ${client} to end had the port ${close.lp}, not the port ${port} of its last answer`);\n else if (!inBand(sec(close.t - from), band)) problems.push(`the socket of ${client} ended at ${sec(close.t - from)} s`);\n }\n const sorted = [...times].sort((a, b) => a - b);\n value = sorted.length === 0 ? null : middle(sorted);\n agrees = `the socket of each of ${clients.length} clients ended, at ${sorted.join(\", \")} s`;\n } else {\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n if (close !== undefined) problems.push(`the socket of ${client} ended ${sec(close.t - from)} s after the ${prediction.from}`);\n }\n // the first call after the heal goes on the socket of the last answer before the reference\n const resumed = run.acts.heal ?? from;\n for (const client of clients) {\n const port = last.get(client)!.lp ?? null;\n const next = calls.find((request) => request.p === client && request.t >= resumed);\n if (next === undefined) problems.push(`${client} sent no call after the heal`);\n else if (next.o !== \"ok\") problems.push(`the first call of ${client} after the heal ended ${next.o}`);\n else if ((next.lp ?? null) !== port) problems.push(`the first call of ${client} after the heal went on the port ${next.lp ?? \"none\"}, not ${port ?? \"none\"}`);\n }\n value = times.length;\n agrees = `no socket of ${clients.length} clients ended, and the first call of each one after the heal went on its socket`;\n }\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const why = problems.length > 0 ? problems.join(\"; \") : inner === null ? agrees : `${agrees}; ${inner.why}`;\n const checked = done(problems.length === 0, why, value, { ...(inner === null ? {} : inner.facts), closes });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n};\n\n/**\n * This function judges a run against a prediction `ends` of the tunnels (`of: \"tunnel\"`). Each client\n * with an answer before the reference is a client of the run. Its tunnel is the HBONE connection of\n * its ztunnel. The tunnel goes from the address of its pod to the HBONE port of the replica of its\n * last answer before the heal. The address of the pod is the local address of a socket of the client\n * in the run (`la`).\n * - The first change of the tunnel out of ESTABLISHED after the reference must be in the band ± δ.\n * It must be to FIN_WAIT1: the side of the client closes the tunnel, and the peer does not close first.\n * - With `answer`, a change to CLOSE_WAIT in that band ± δ also agrees. The peer closed first, but as\n * an answer to the close of the client.\n * - The first request of each client after the heal must succeed. The main value is the middle of the ends.\n */\nconst checkTunnels = (\n run: KindRun,\n prediction: Extract<Prediction, { readonly kind: \"ends\" }>,\n from: number,\n done: (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck,\n): RunCheck => {\n if (prediction.band === null) return done(false, \"a prediction of the tunnels needs a band\", null);\n const heal = run.acts.heal;\n if (heal === null) return done(false, \"the run has no heal\", null);\n const lines = run.lines as readonly Line[];\n const calls = requestsOf(lines)\n .filter((request) => request.t >= run.start && request.t <= run.end)\n .sort((a, b) => a.t - b.t);\n const clients = [...new Set(calls.filter((request) => request.t < from && request.o === \"ok\").map((request) => request.p))].sort();\n if (clients.length === 0) return done(false, `no client had an answer before the ${prediction.from}`, null);\n const band = secondsOf(prediction.band);\n const reply = prediction.answer === undefined ? null : secondsOf(prediction.answer);\n const tunnels = tunnelsOf(lines).filter((line) => line.t >= from && line.t <= run.end);\n const sockets = socketsOf(lines);\n const closes: Record<string, Quantity | null> = {};\n const times: number[] = [];\n const problems: string[] = [];\n for (const client of clients) {\n closes[client] = null;\n const answer = calls.filter((request) => request.p === client && request.t < heal && request.o === \"ok\").at(-1);\n const replica = run.replicas.find((each) => answer !== undefined && each.pod === answer.b);\n const address = sockets.find((line) => line.p === client && typeof line.la === \"string\" && line.la !== \"\")?.la;\n if (replica === undefined) {\n problems.push(`no replica of the run answered ${client} before the heal`);\n continue;\n }\n if (address === undefined || address === null) {\n problems.push(`no socket of ${client} gave the address of its pod`);\n continue;\n }\n const end = tunnels.find((line) => line.src.startsWith(`${address}:`) && line.dst === `${replica.ip}:${HBONE_PORT}` && line.old === TCP_STATE.established);\n if (end === undefined) {\n problems.push(`the tunnel of ${client} to ${replica.pod} did not end`);\n continue;\n }\n const at = sec(end.t - from);\n closes[client] = seconds(at);\n times.push(at);\n if (end.new === TCP_STATE.closeWait && reply !== null) {\n if (!inBand(at, reply)) problems.push(`the peer closed the tunnel of ${client} at ${at} s, outside the band of its answer`);\n } else if (end.new !== TCP_STATE.finWait1) problems.push(`the tunnel of ${client} went from ESTABLISHED to the state ${end.new}, not FIN_WAIT1: the peer closed first`);\n else if (!inBand(at, band)) problems.push(`the tunnel of ${client} ended at ${at} s`);\n const next = calls.find((request) => request.p === client && request.t >= heal);\n if (next === undefined) problems.push(`${client} sent no call after the heal`);\n else if (next.o !== \"ok\") problems.push(`the first call of ${client} after the heal ended ${next.o}`);\n }\n const sorted = [...times].sort((a, b) => a - b);\n const why =\n problems.length > 0\n ? problems.join(\"; \")\n : `the side of the client ended the tunnel of each of ${clients.length} clients, at ${sorted.join(\", \")} s, and the first call of each one after the heal succeeded`;\n return done(problems.length === 0, why, sorted.length === 0 ? null : middle(sorted), { closes });\n};\n\n/** This function judges a cell on its runs: each counted run must agree, and a median in a band must be equivalent to it. */\nexport const judgeKind = (cell: KindCell, runs: readonly KindRun[]): KindVerdict => {\n const counted = runs.filter((run) => !run.warmup && run.void === null);\n const voided = runs.filter((run) => !run.warmup && run.void !== null).length;\n const checks = counted.map((run) => checkRun(cell, run));\n // the main values of one cell share the unit of its prediction\n const values = checks.flatMap((check) => (check.value === null ? [] : [check.value.value])).sort((a, b) => a - b);\n const median: Quantity | null = values.length === 0 ? null : { value: middle(values), unit: unitOf(cell.prediction) };\n const failed = checks.filter((check) => !check.ok).length;\n if (counted.length === 0) return { decision: \"void\", counted: 0, voided, failed: 0, median: null, why: \"no counted run\", checks };\n if (cell.calibrates) return { decision: \"calibration\", counted: counted.length, voided, failed, median, why: \"a calibration of the propagation\", checks };\n if (cell.prediction.kind === \"measured\") return { decision: \"measured\", counted: counted.length, voided, failed: 0, median, why: cell.prediction.why, checks };\n const prediction = cell.prediction;\n const band = prediction.kind === \"removal\" || prediction.kind === \"leaves\" || prediction.kind === \"restarts\" || prediction.kind === \"ends\" ? prediction.band : null;\n if (failed > 0) {\n const first = checks.find((check) => !check.ok)!;\n return { decision: \"fails\", counted: counted.length, voided, failed, median, why: `${failed} of ${counted.length} runs disagree, the first: ${first.why}`, checks };\n }\n // a run past its calibrated band agrees with the law, but the band is short: the cell needs a longer one\n const tails = checks.filter((check) => check.tail !== undefined);\n if (tails.length > 0)\n return { decision: \"extend\", counted: counted.length, voided, failed, median, why: `${tails.length} of ${counted.length} runs are past the calibrated band, the first: ${tails[0]!.tail}`, checks };\n if (band !== null && values.length > 0) {\n const ends = secondsOf(band);\n const [from, to] = medianInterval(values);\n const wide = { lo: ends.lo * (1 - RELATIVE), hi: ends.hi * (1 + RELATIVE) };\n if (to < wide.lo || from > wide.hi)\n return { decision: \"fails\", counted: counted.length, voided, failed, median, why: `the median interval [${from}, ${to}] s is outside the band`, checks };\n if (from < wide.lo || to > wide.hi)\n return { decision: \"extend\", counted: counted.length, voided, failed, median, why: `the median interval [${from}, ${to}] s crosses the edge of the band`, checks };\n }\n return { decision: \"holds\", counted: counted.length, voided, failed, median, why: `${counted.length} of ${counted.length} runs agree`, checks };\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { seconds } from \"./bands.ts\";\nimport type { Band, KindCell, KindRun, Prediction, Trigger, WindowPrediction } from \"./cell.ts\";\nimport type { KindScenario } from \"./scenario.ts\";\nimport type { KindVerdict, Propagated, RunCheck, RunFacts } from \"./verdict.ts\";\nimport { judgeKind, unitOf } from \"./verdict.ts\";\nimport type { Substrate } from \"@mark1russell7/harness\";\n\n/**\n * This module is the raw record of a kind cell: its formats, and the upgrade from the format `/1`\n * to the format `/2`. The lab writes `/2`, and it does not write `/1` again. A reader reads a record\n * of `/1` through `upgrade`, and the meaning of each value stays the same.\n */\n\n/** This format is the format that the lab writes. Each amount in it is a quantity. */\nexport const FORMAT = \"systems.kind-cell-record/2\";\n/** This format is the first format. Its bands, its medians and its times are numbers. */\nexport const FORMAT_V1 = \"systems.kind-cell-record/1\";\n\n/** A load sample is what the VM did in 4 s before a run: when (a stamp of the wall clock in milliseconds), its idle share, and its busiest processes. */\nexport interface LoadSample {\n readonly t: number;\n readonly idle: number;\n readonly top: readonly string[];\n readonly foreign: readonly string[];\n}\n\n/** A cluster manifest is what a run records about its cluster: the versions, the images, the nodes and the mode as read back. */\nexport interface ClusterManifest {\n readonly kind: string;\n readonly nodeImage: string;\n readonly server: string;\n readonly mode: string;\n readonly docker: string;\n readonly nodes: ReadonlyArray<{\n readonly name: string;\n readonly kubelet: string;\n readonly kernel: string;\n readonly runtime: string;\n readonly os: string;\n }>;\n}\n\n/** An environment manifest is one cluster of a cell: its scenario, what the cluster was, and the images of the lab. */\nexport interface EnvironmentManifest {\n readonly env: number;\n readonly scenario: KindScenario;\n readonly cluster: ClusterManifest;\n readonly images: Readonly<Record<string, string>>;\n /** This block tells the layer, the cloud and the kernel of the record. A record from before it reads through `substrateOf`. */\n readonly substrate?: Substrate;\n}\n\n/**\n * A kind cell result is a cell, its runs over its environments, the manifest of each environment,\n * and its verdict. The parameter `A` is the form of an amount.\n */\nexport interface KindCellResult<A = Quantity> {\n readonly cell: KindCell<A>;\n readonly runs: readonly KindRun[];\n readonly manifests: readonly EnvironmentManifest[];\n readonly loads: readonly LoadSample[];\n readonly verdict: KindVerdict<A>;\n /** This text is the time of the verdict, in ISO 8601. */\n readonly at: string;\n}\n\n/** A kind cell record is the raw record of a cell in the format `/2`: a result with its format. */\nexport interface KindCellRecord extends KindCellResult {\n readonly format: typeof FORMAT;\n}\n\n/** A kind cell record of the format `/1` gives each band, median, main value and time of a fact as a number. */\nexport interface KindCellRecordV1 extends KindCellResult<number> {\n readonly format: typeof FORMAT_V1;\n}\n\n/** These are the parts of the format `/1`, with numbers for amounts. */\nexport type BandV1 = Band<number>;\nexport type PredictionV1 = Prediction<number>;\nexport type TriggerV1 = Trigger<number>;\nexport type KindCellV1 = KindCell<number>;\nexport type KindVerdictV1 = KindVerdict<number>;\nexport type RunCheckV1 = RunCheck<number>;\nexport type RunFactsV1 = RunFacts<number>;\n\nconst time = (value: number | null): Quantity | null => (value === null ? null : seconds(value));\nconst band = (old: BandV1): Band => ({ lo: seconds(old.lo), hi: seconds(old.hi) });\n/** The format `/1` gives each part of `cpu.max` in microseconds. */\nconst microseconds = (value: number): Quantity => ({ value, unit: \"us\" });\n\nconst upgradeTrigger = (trigger: TriggerV1): Trigger => {\n const { cpuMax, ...rest } = trigger;\n return cpuMax === undefined ? rest : { ...rest, cpuMax: { quota: microseconds(cpuMax.quota), period: microseconds(cpuMax.period) } };\n};\n\n/** The format `/1` has no backlog term, but its type does. Each time of the term is in seconds. */\nconst upgradeBacklog = (backlog: NonNullable<WindowPrediction<number>[\"backlog\"]>): NonNullable<WindowPrediction[\"backlog\"]> => {\n const { slowest, ...rest } = backlog;\n return { ...rest, drain: band(backlog.drain), ...(slowest === undefined ? {} : { slowest: seconds(slowest) }) };\n};\n\nconst upgradePermits = (permits: NonNullable<WindowPrediction<number>[\"permits\"]>): NonNullable<WindowPrediction[\"permits\"]> => {\n const { watch, ...rest } = permits;\n return { ...rest, band: band(permits.band), ...(watch === undefined ? {} : { watch: seconds(watch) }) };\n};\n\nconst upgradeWindow = (window: WindowPrediction<number>): WindowPrediction => {\n const { afterReset, propagation, backlog, permits, ...rest } = window;\n return {\n ...rest,\n start: { from: window.start.from, band: band(window.start.band) },\n end: window.end === null ? null : { from: window.end.from, band: band(window.end.band) },\n ...(afterReset === undefined ? {} : { afterReset: { life: seconds(afterReset.life), outcome: afterReset.outcome } }),\n ...(propagation === undefined ? {} : { propagation: band(propagation) }),\n ...(backlog === undefined ? {} : { backlog: upgradeBacklog(backlog) }),\n // the format /1 has no permitted window, but its type does\n ...(permits === undefined ? {} : { permits: upgradePermits(permits) }),\n };\n};\n\nconst upgradePrediction = (prediction: PredictionV1): Prediction => {\n switch (prediction.kind) {\n case \"window\":\n return upgradeWindow(prediction);\n // the format /1 has no prediction `ends`, but its type does\n case \"ends\": {\n const { window, answer, ...rest } = prediction;\n return {\n ...rest,\n band: prediction.band === null ? null : band(prediction.band),\n ...(window === undefined ? {} : { window: upgradeWindow(window) }),\n ...(answer === undefined ? {} : { answer: band(answer) }),\n };\n }\n // the format /1 has no window on `removal` and `leaves`, but their types do\n case \"removal\":\n case \"leaves\": {\n const { window, ...rest } = prediction;\n return { ...rest, band: band(prediction.band), ...(window === undefined ? {} : { window: upgradeWindow(window) }) };\n }\n case \"restarts\":\n return { ...prediction, band: prediction.band === null ? null : band(prediction.band) };\n // the format /1 has no failures on `stays`, but its type does\n case \"stays\": {\n const { failures, ...rest } = prediction;\n return { ...rest, ...(failures === undefined ? {} : { failures: failures.kind === \"window\" ? upgradeWindow(failures) : failures }) };\n }\n // the format /1 has no prediction `reconnects`, but its type does\n case \"reconnects\": {\n const { backoff } = prediction;\n return {\n ...prediction,\n flip: band(prediction.flip),\n probe: seconds(prediction.probe),\n disconnect: band(prediction.disconnect),\n backoff: { ...backoff, initial: seconds(backoff.initial), max: seconds(backoff.max), mandatoryStop: seconds(backoff.mandatoryStop), attempt: seconds(backoff.attempt) },\n setup: band(prediction.setup),\n };\n }\n default:\n return prediction;\n }\n};\n\n/** This function gives a cell of the format `/1` in the format `/2`: its bands in seconds, and its `cpu.max` in microseconds. */\nexport const upgradeCell = (cell: KindCellV1): KindCell => ({\n ...cell,\n trigger: upgradeTrigger(cell.trigger),\n prediction: upgradePrediction(cell.prediction),\n});\n\nconst upgradeFacts = (facts: RunFactsV1): RunFacts => {\n const propagated = (old: Propagated<number> | null): Propagated | null => (old === null ? null : { after: time(old.after), by: seconds(old.by) });\n const byKey = (record: Readonly<Record<string, Propagated<number> | null>>) => Object.fromEntries(Object.entries(record).map(([key, old]) => [key, propagated(old)]));\n const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, cycles, stall, period, reconnects, ...rest } = facts;\n return {\n ...rest,\n intakeAfterDeletion: time(facts.intakeAfterDeletion),\n sliceAfter: time(facts.sliceAfter),\n propagation: byKey(facts.propagation),\n ...(updates === undefined ? {} : { updates: byKey(updates) }),\n ...(healUpdates === undefined ? {} : { healUpdates: byKey(healUpdates) }),\n ...(sliceEmpty === undefined ? {} : { sliceEmpty: seconds(sliceEmpty) }),\n ...(rules === undefined ? {} : { rules: Object.fromEntries(Object.entries(rules).map(([node, old]) => [node, time(old)])) }),\n ...(left === undefined ? {} : { left: seconds(left) }),\n ...(signals === undefined ? {} : { signals: signals.map((old) => time(old)) }),\n ...(closes === undefined ? {} : { closes: Object.fromEntries(Object.entries(closes).map(([client, old]) => [client, time(old)])) }),\n ...(cycles === undefined ? {} : { cycles: cycles.map((old) => ({ empty: time(old.empty), ready: time(old.ready) })) }),\n ...(stall === undefined ? {} : { stall: { start: time(stall.start), held: time(stall.held) } }),\n // the format /1 has no facts of the producers, but its type does\n ...(reconnects === undefined\n ? {}\n : {\n reconnects: {\n ...reconnects,\n flip: time(reconnects.flip),\n gap: time(reconnects.gap),\n returns: reconnects.returns.map((each) => ({ ...each, disconnect: time(each.disconnect), back: time(each.back), setup: time(each.setup) })),\n },\n }),\n ...(period === undefined\n ? {}\n : {\n period: {\n ...period,\n median: seconds(period.median),\n mean: seconds(period.mean),\n low: seconds(period.low),\n high: seconds(period.high),\n byClient: Object.fromEntries(Object.entries(period.byClient).map(([client, old]) => [client, seconds(old)])),\n },\n }),\n };\n};\n\n/**\n * This function gives a record in the format `/2`. A record of `/2` comes back as it is. A record\n * of `/1` gets each amount as a quantity, and each value stays the same:\n * - Each band and each time of a fact is in seconds, as `/1` gives it.\n * - The `cpu.max` of a throttle is in microseconds, as `/1` gives it.\n * - The median and the main value of each run get the unit of the prediction (`unitOf`): seconds,\n * failed requests (`{request}`) or replicas (`{replica}`).\n */\nexport const upgrade = (record: KindCellRecordV1 | KindCellRecord): KindCellRecord => {\n if (record.format === FORMAT) return record;\n const unit = unitOf(record.cell.prediction);\n const amount = (value: number | null): Quantity | null => (value === null ? null : { value, unit });\n const verdict = record.verdict;\n return {\n format: FORMAT,\n cell: upgradeCell(record.cell),\n runs: record.runs,\n manifests: record.manifests,\n loads: record.loads,\n verdict: {\n ...verdict,\n median: amount(verdict.median),\n checks: verdict.checks.map((check) => ({ ...check, value: amount(check.value), facts: upgradeFacts(check.facts) })),\n },\n at: record.at,\n };\n};\n\n/**\n * This function judges a record again, from its cell and its runs, with the judge of this version.\n * It reads a record of `/1` through `upgrade`. The verdict is in the format `/2`.\n */\nexport const judge = (record: KindCellRecordV1 | KindCellRecord): KindVerdict => {\n const current = upgrade(record);\n return judgeKind(current.cell, current.runs);\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { format, valueIn } from \"@mark1russell7/quantity\";\nimport { seconds, secondsOf, showBand } from \"./bands.ts\";\nimport type { Band, KindCell, KindRun, Prediction } from \"./cell.ts\";\nimport { middle, quantileOf } from \"./stats.ts\";\nimport type { KindVerdict } from \"./verdict.ts\";\nimport { factsOf, propagationOf, propagationSource, referenceOf, updatesOf } from \"./verdict.ts\";\n\n/** A judged cell is a cell, its runs and its verdict: the part of a result that a report reads. */\nexport interface Judged {\n readonly cell: KindCell;\n readonly runs: readonly KindRun[];\n readonly verdict: KindVerdict;\n}\n\n/** A spread is the count, the extremes, the median and the 99th percentile of a set of times. */\nexport interface TimeSpread {\n readonly count: number;\n readonly min: Quantity;\n readonly median: Quantity;\n readonly p99: Quantity;\n readonly max: Quantity;\n}\n\n/** This function gives the spread of a set of times, or null for none. The percentile is by nearest rank. */\nexport const timeSpread = (times: readonly Quantity[]): TimeSpread | null => {\n if (times.length === 0) return null;\n const sorted = times.map((each) => valueIn(each, \"s\")).sort((a, b) => a - b);\n const median = middle(sorted);\n return {\n count: sorted.length,\n min: seconds(sorted[0]!),\n median: seconds(Math.round(median * 1000) / 1000),\n p99: seconds(quantileOf(sorted, 0.99)),\n max: seconds(sorted.at(-1)!),\n };\n};\n\n/** This function gives a reference with its band, and only the reference when the band is [0, 0] s. */\nconst atBand = (from: string, band: Band): string => {\n const { lo, hi } = secondsOf(band);\n return lo === 0 && hi === 0 ? `the ${from}` : `the ${from} + ${showBand(band)}`;\n};\n\n/** This function gives the prediction of a cell in a short form for a table. A prediction `ends` gives its window after its band. */\nexport const predictionText = (prediction: Prediction): string => {\n switch (prediction.kind) {\n case \"none\":\n return prediction.outcomes === undefined ? \"no failure\" : `no ${prediction.outcomes.join(\", \")}`;\n case \"window\":\n // a window with `each` is a window for each replica that got a deletion, from the references of that replica.\n // A window can open before its reference: a stale SYN_SENT entry fails the paused node up to its life before the intake\n return `failures only from ${atBand(prediction.start.from, prediction.start.band)}${prediction.end === null ? \"\" : ` to ${atBand(prediction.end.from, prediction.end.band)}`}${prediction.each === true ? \", of each deleted replica\" : \"\"}${prediction.flaps === true ? \", in each cycle\" : \"\"}${prediction.nodes === \"paused\" ? \", on the paused node\" : \"\"}${prediction.certain ? \", at least one\" : \"\"}${prediction.outcomes === undefined ? \"\" : `, each one ${prediction.outcomes.join(\" or \")}`}${prediction.afterReset === undefined ? \"\" : `, or a ${prediction.afterReset.outcome} up to ${format(prediction.afterReset.life)} after a reset on its port`}${prediction.propagation === undefined ? \"\" : `, the rules drop the replica in ${showBand(prediction.propagation)}`}${prediction.backlog === undefined ? \"\" : `, the end n × ${showBand(prediction.backlog.drain)} later and ${prediction.backlog.requests.lo}–${prediction.backlog.requests.hi} more failures for each of the n sessions on the target${prediction.backlog.drains === true ? \", and its failures each turn in the drain of the n sessions\" : \"\"}, counted at the measured period${prediction.backlog.slowest === undefined ? \"\" : `, one session draining up to ${format(prediction.backlog.slowest)}`}${prediction.backlog.early === true ? \", the last failure up to one turn before the end\" : \"\"}`}${prediction.permits === undefined ? \"\" : `, and ${prediction.permits.outcomes.join(\" or \")} permitted at ${atBand(prediction.permits.from, prediction.permits.band)}${prediction.permits.watch === undefined ? \"\" : `, the record at least ${format(prediction.permits.watch)} after the ${prediction.permits.from}`}`}`;\n case \"removal\":\n return `Service empty in ${showBand(prediction.band)}${prediction.flaps === true ? \" after each fault, and ready again before the next\" : \"\"}${prediction.window === undefined ? \"\" : `; ${predictionText(prediction.window)}`}`;\n case \"leaves\":\n return `the replica leaves in ${showBand(prediction.band)}${prediction.window === undefined ? \"\" : `; ${predictionText(prediction.window)}`}`;\n case \"restarts\":\n return prediction.band === null ? \"no restart\" : `each replica SIGTERM in ${showBand(prediction.band)}`;\n case \"stays\":\n return `stays ready, no refusal${prediction.failures === undefined ? \"\" : `; ${predictionText(prediction.failures)}`}`;\n case \"stalls\":\n return \"the rollout waits for Redis\";\n case \"ends\": {\n const closes =\n prediction.band === null\n ? \"no socket of a client ends, and each one calls again on its socket\"\n : prediction.of === \"tunnel\"\n ? `the side of the client ends the tunnel of each client in ${atBand(prediction.from, prediction.band)}${prediction.answer === undefined ? \"\" : `, or the peer answers in ${atBand(prediction.from, prediction.answer)}`}, and each one calls again`\n : `the socket of each client ends in ${atBand(prediction.from, prediction.band)}`;\n return prediction.window === undefined ? closes : `${closes}; ${predictionText(prediction.window)}`;\n }\n case \"reconnects\":\n return `another owner in ${showBand(prediction.flip)}, each producer back at the first try of its backoff after it, failures only before it, each one ${prediction.outcomes.join(\" or \")}`;\n case \"measured\":\n return \"measured\";\n }\n};\n\n/**\n * This function gives the main measurement of a cell in a short form: its median and what it\n * counts. For failed requests, it is the middle count of the counted runs.\n */\nexport const medianText = (judged: Judged): string => {\n const { cell, verdict } = judged;\n if (verdict.median === null) return \"\";\n if (verdict.median.unit === \"{request}\") {\n const counted = judged.runs.filter((run) => !run.warmup && run.void === null);\n const failures = counted.map((run) => factsOf(cell, run).failures).sort((a, b) => a - b);\n return `${failures.length === 0 ? 0 : failures[Math.floor(failures.length / 2)]} failed requests`;\n }\n return format(verdict.median, { digits: 4 });\n};\n\n/** This function gives the table of the cells in Markdown. Each row has the cell, its plan cell, its mode, its trigger, the prediction, the verdict, its runs and its median. */\nexport const cellsTable = (judged: readonly Judged[]): string =>\n [\n \"| Cell | Plan id | Mode | Trigger | Prediction | Verdict | Runs | Median |\",\n \"| --- | --- | --- | --- | --- | --- | --- | --- |\",\n ...judged.map((each) => {\n const { cell, verdict } = each;\n const runs = verdict.voided === 0 ? `${verdict.counted}` : `${verdict.counted} (+${verdict.voided} void)`;\n return `| ${cell.name} | ${cell.id} | ${cell.mode} | ${cell.trigger.kind}${cell.trigger.flaps === undefined || cell.trigger.flaps.length === 0 ? \"\" : ` (${cell.trigger.flaps.length + 1} faults)`} | ${predictionText(cell.prediction)} | ${verdict.decision} | ${runs} | ${medianText(each)} |`;\n }),\n ].join(\"\\n\");\n\n/**\n * This function gives the propagation of each calibration, by node. It is the time from the\n * deletion to the poll of the rules of each node without the pod. It also gives the time to the\n * EndpointSlice and to the stop of the intake.\n *\n * For a policy of Istio, the propagation is the LDS update of each server sidecar after the apply,\n * by node (`updatesOf`). Then `heal` is the update after the delete of the policy. `slice` and\n * `intake` are null.\n */\nexport const calibrationOf = (judged: Judged): {\n readonly nodes: Readonly<Record<string, TimeSpread | null>>;\n readonly all: TimeSpread | null;\n readonly slice: TimeSpread | null;\n readonly intake: TimeSpread | null;\n readonly heal?: TimeSpread | null | undefined;\n} => {\n const byNode: Record<string, Quantity[]> = {};\n const slice: Quantity[] = [];\n const intake: Quantity[] = [];\n const counted = judged.runs.filter((each) => !each.warmup && each.void === null);\n if (judged.cell.trigger.kind === \"authorization-policy\") {\n const heal: Quantity[] = [];\n for (const run of counted) {\n const nodeOf = (pod: string): string => run.replicas.find((replica) => replica.pod === pod)?.node ?? pod;\n for (const [pod, update] of Object.entries(updatesOf(run, run.acts.fault))) if (update !== null) (byNode[nodeOf(pod)] ??= []).push(update.by);\n for (const update of Object.values(updatesOf(run, run.acts.heal))) if (update !== null) heal.push(update.by);\n }\n const nodes = Object.fromEntries(Object.entries(byNode).map(([node, values]) => [node, timeSpread(values)]));\n return { nodes, all: timeSpread(Object.values(byNode).flat()), slice: null, intake: null, heal: timeSpread(heal) };\n }\n for (const run of counted) {\n const deletion = referenceOf(run, \"deletion\");\n for (const [node, drop] of Object.entries(propagationOf(run, deletion, undefined, propagationSource(judged.cell)))) if (drop !== null) (byNode[node] ??= []).push(drop.by);\n const facts = factsOf(judged.cell, run);\n if (facts.sliceAfter !== null) slice.push(facts.sliceAfter);\n if (facts.intakeAfterDeletion !== null) intake.push(facts.intakeAfterDeletion);\n }\n const nodes = Object.fromEntries(Object.entries(byNode).map(([node, values]) => [node, timeSpread(values)]));\n return { nodes, all: timeSpread(Object.values(byNode).flat()), slice: timeSpread(slice), intake: timeSpread(intake) };\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { extentSchema, quantitySchema } from \"@mark1russell7/quantity/schema\";\nimport type { Stage } from \"@mark1russell7/service\";\nimport { z } from \"zod\";\nimport type { EdgeProtocol, KindRun, TriggerKind } from \"./cell.ts\";\nimport type { KindCellRecord, KindCellRecordV1 } from \"./record.ts\";\nimport { FORMAT, FORMAT_V1, upgrade } from \"./record.ts\";\nimport type { Dataplane, KubeProxyMode } from \"./scenario.ts\";\nimport { unitOf } from \"./verdict.ts\";\n\n/**\n * This module holds the zod schemas of a kind cell record, in the formats `/1` and `/2`. It names\n * the stages of the shutdown itself, thus it does not load the service. A test holds the names to\n * the service.\n */\n\n/** These are the stages of the shutdown of the service, in their sequence. */\nexport const STAGES: readonly [Stage, ...Stage[]] = [\n \"fail readiness\",\n \"stop intake\",\n \"drain\",\n \"close transports\",\n \"stop the poller\",\n \"tear down dependencies\",\n \"close the health server\",\n \"flush the output\",\n];\n\nconst TRIGGERS = [\n \"pod-deletion\",\n \"rolling-update\",\n \"node-drain\",\n \"scale-in\",\n \"crash\",\n \"liveness-restart\",\n \"freeze-process\",\n \"rst\",\n \"blackhole\",\n \"peer-gone-without-close\",\n \"app-stall\",\n \"rollout\",\n \"cpu-throttle\",\n \"authorization-policy\",\n \"idle\",\n \"ztunnel-restart\",\n \"certificate-expiry\",\n \"cannot-serve\",\n \"zone-loss\",\n \"latency\",\n \"dns-blackhole\",\n] as const satisfies readonly TriggerKind[];\nconst KUBE_PROXY = [\"iptables\", \"ipvs\", \"nftables\"] as const satisfies readonly KubeProxyMode[];\nconst MODES = [...KUBE_PROXY, \"cilium\"] as const satisfies readonly Dataplane[];\n\nconst time = quantitySchema(\"time\");\nconst extent = extentSchema(\"time\");\nconst count = z.number().int().nonnegative();\nconst gate = z.enum([\"readiness\", \"liveness\"]);\nconst reference = z.enum([\"deletion\", \"intake\", \"fault\", \"resume\", \"heal\", \"restart\"]);\n\nconst probe = z.object({ period: time, threshold: count, timeout: time });\nconst timing = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"debounce\"), interval: time, failAfter: count, recoverAfter: count }),\n z.object({ type: z.literal(\"window\"), failAfter: time, recoverAfter: time.optional() }),\n]);\nconst knobs = z.object({\n connect_bound: time,\n request_timeout: time,\n driver_writeoff_time: extent,\n keepalive_idle: extent,\n heartbeat_interval: extent,\n heartbeat_timeout: time,\n client_retry_window: extent,\n retry_base: time,\n retry_cap: time,\n close_bound: time,\n max_connection_age: extent,\n retrans_giveup_time: extent,\n});\nconst declaration = z.object({\n poll: z.object({ interval: time, jitter: z.number().min(0).lt(1), timeout: time }),\n readiness: timing,\n liveness: timing,\n startup: time,\n phases: z.array(z.tuple([z.enum(STAGES), time])),\n cooperativeWindow: extent,\n couplings: z.array(z.object({ from: gate, to: gate, effect: z.literal(\"fails\") })),\n redis: z.object({ gates: gate.nullable(), knobs, misses: count }).nullable(),\n flag: gate.nullable(),\n watchdog: z.object({ tick: time, threshold: time }).nullable(),\n lameDuck: z.boolean().optional(),\n protocol: z.enum([\"http/1.1\", \"h2c\"] as const satisfies readonly EdgeProtocol[]).optional(),\n sharedGate: z.boolean().optional(),\n});\n\nconst replica = z.object({ pod: z.string(), node: z.string(), ip: z.string(), version: z.string() });\n/** A line keeps each field that its source wrote. The judge reads `ev`, `t` and the fields of its kind. */\nconst line = z.object({ ev: z.string(), t: z.number() }).catchall(z.unknown());\nconst run: z.ZodType<KindRun> = z.object({\n env: count,\n index: z.number().int(),\n warmup: z.boolean(),\n start: z.number(),\n end: z.number(),\n acts: z.object({\n fault: z.number().nullable(),\n heal: z.number().nullable(),\n resume: z.number().nullable(),\n cycles: z.array(z.object({ fault: z.number(), heal: z.number() })).optional(),\n }),\n target: replica.nullable(),\n paused: z.string().nullable(),\n broker: z.string().optional(),\n replicas: z.array(replica),\n void: z.string().nullable(),\n lines: z.array(line),\n dropped: z.record(z.string(), count),\n notes: z.array(z.string()).optional(),\n});\nconst manifest = z.object({\n env: count,\n // A record from before the dataplane `cilium` has no `dataplane`: its dataplane is the mode of its kube-proxy.\n scenario: z\n .object({\n name: z.string(),\n kubernetes: z.string(),\n workers: count,\n dataplane: z.enum(MODES).optional(),\n kubeProxy: z.object({ mode: z.enum(KUBE_PROXY), minSyncPeriod: time, syncPeriod: time }).nullable(),\n cni: z.enum([\"kindnet\", \"cilium\"]),\n podSubnet: z.string(),\n serviceSubnet: z.string(),\n })\n .transform(({ dataplane, ...rest }) => ({ ...rest, dataplane: dataplane ?? rest.kubeProxy?.mode ?? \"cilium\" })),\n cluster: z.object({\n kind: z.string(),\n nodeImage: z.string(),\n server: z.string(),\n mode: z.string(),\n docker: z.string(),\n nodes: z.array(z.object({ name: z.string(), kubelet: z.string(), kernel: z.string(), runtime: z.string(), os: z.string() })),\n }),\n images: z.record(z.string(), z.string()),\n});\nconst load = z.object({ t: z.number(), idle: z.number(), top: z.array(z.string()), foreign: z.array(z.string()) });\n\n/**\n * This function gives the schema of a record whose amounts have one form. The schema `a` is for a\n * time. The schema `main` is for the main value of a run: a time or a count.\n */\nconst recordOf = <A>(a: z.ZodType<A>, main: z.ZodType<A>) => {\n const band = z.object({ lo: a, hi: a });\n const window = z.object({\n kind: z.literal(\"window\"),\n nodes: z.enum([\"all\", \"paused\"]),\n start: z.object({ from: reference, band }),\n end: z.object({ from: reference, band }).nullable(),\n certain: z.boolean(),\n afterReset: z.object({ life: a, outcome: z.string() }).optional(),\n each: z.boolean().optional(),\n propagation: band.optional(),\n flaps: z.boolean().optional(),\n outcomes: z.array(z.string()).optional(),\n backlog: z.object({ drain: band, requests: z.object({ lo: count, hi: count }), most: count, drains: z.boolean().optional(), slowest: a.optional(), early: z.boolean().optional() }).optional(),\n permits: z.object({ from: reference, band, outcomes: z.array(z.string()), watch: a.optional(), why: z.string() }).optional(),\n why: z.string(),\n });\n const none = z.object({ kind: z.literal(\"none\"), outcomes: z.array(z.string()).optional(), why: z.string() });\n const prediction = z.discriminatedUnion(\"kind\", [\n none,\n window,\n z.object({ kind: z.literal(\"removal\"), band, window: window.optional(), flaps: z.boolean().optional(), why: z.string() }),\n z.object({ kind: z.literal(\"leaves\"), band, window: window.optional(), why: z.string() }),\n z.object({ kind: z.literal(\"restarts\"), band: band.nullable(), why: z.string() }),\n z.object({ kind: z.literal(\"stays\"), failures: z.discriminatedUnion(\"kind\", [window, none]).optional(), why: z.string() }),\n z.object({ kind: z.literal(\"stalls\"), why: z.string() }),\n z.object({ kind: z.literal(\"ends\"), from: reference, band: band.nullable(), window: window.optional(), of: z.enum([\"socket\", \"tunnel\"]).optional(), answer: band.optional(), why: z.string() }),\n z.object({\n kind: z.literal(\"reconnects\"),\n flip: band,\n probe: a,\n disconnect: band,\n backoff: z.object({ initial: a, max: a, mandatoryStop: a, jitter: z.number(), attempt: a }),\n setup: band,\n outcomes: z.array(z.string()),\n why: z.string(),\n }),\n z.object({ kind: z.literal(\"measured\"), why: z.string() }),\n ]);\n const cell = z.object({\n id: z.string(),\n name: z.string(),\n template: z.enum([\"T07\", \"T15\", \"T18\"]),\n stack: z.enum([\"service\", \"grpc\"]).optional(),\n mesh: z\n .object({ flavor: z.enum([\"sidecar\", \"ambient\"]), mode: z.enum([\"sidecar\", \"ambient\"]), ztunnel: z.record(z.string(), z.string()).optional() })\n .optional(),\n substitutes: z.string().nullable(),\n mode: z.enum(MODES),\n workers: count,\n trigger: z.object({\n kind: z.enum(TRIGGERS),\n hold: time.optional(),\n lead: time.optional(),\n cpuMax: z.object({ quota: a, period: a }).optional(),\n account: z.string().optional(),\n middlebox: time.optional(),\n retries: count.optional(),\n quiet: z.boolean().optional(),\n close: z.boolean().optional(),\n partition: z.boolean().optional(),\n serves: z.boolean().optional(),\n flaps: z.array(z.object({ rest: time, hold: time })).optional(),\n delay: time.optional(),\n }),\n pod: z.object({ replicas: count, grace: time, preStop: time, readiness: probe, liveness: probe, startup: probe.nullable() }),\n declaration: declaration.nullable(),\n workload: z.object({\n every: time,\n timeout: time,\n connections: count.optional(),\n sessionCheck: z.object({ keepalive_time: extent, keepalive_timeout: time }).optional(),\n onTarget: count.optional(),\n byName: z.boolean().optional(),\n }),\n prediction,\n calibrates: z.boolean(),\n runs: count,\n vip: z\n .object({\n clients: count,\n announcer: z.enum([\"kube-vip\", \"metallb\"]).optional(),\n memberlist: z.object({ probeInterval: time, probeTimeout: time, suspicionMult: count }).optional(),\n })\n .optional(),\n pulsar: z.object({ clients: count, probe: time }).optional(),\n });\n const facts = z.object({\n failures: count,\n outcomes: z.record(z.string(), count),\n byNode: z.record(z.string(), count),\n first: z.number().nullable(),\n last: z.number().nullable(),\n deletion: z.number().nullable(),\n intakeAfterDeletion: a.nullable(),\n sliceAfter: a.nullable(),\n propagation: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()),\n sliceEmpty: a.optional(),\n rules: z.record(z.string(), a.nullable()).optional(),\n left: a.optional(),\n signals: z.array(a.nullable()).optional(),\n deletions: z.array(z.object({ pod: z.string(), intake: z.number().nullable(), deletion: z.number() })).optional(),\n updates: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()).optional(),\n healUpdates: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()).optional(),\n closes: z.record(z.string(), a.nullable()).optional(),\n cycles: z.array(z.object({ empty: a.nullable(), ready: a.nullable() })).optional(),\n sessions: z.object({ onTarget: count, of: count, byClient: z.record(z.string(), count) }).optional(),\n stall: z.object({ start: a.nullable(), held: a.nullable() }).optional(),\n period: z.object({ median: a, mean: a, low: a, high: a, intervals: count, byClient: z.record(z.string(), a) }).optional(),\n reconnects: z\n .object({\n flip: a.nullable(),\n gap: a.nullable(),\n returns: z.array(z.object({ pod: z.string(), disconnect: a.nullable(), back: a.nullable(), setup: a.nullable(), tries: count })),\n failures: z.record(z.string(), count),\n })\n .optional(),\n });\n const verdict = z.object({\n decision: z.enum([\"holds\", \"fails\", \"extend\", \"measured\", \"calibration\", \"void\"]),\n counted: count,\n voided: count,\n failed: count,\n median: main.nullable(),\n why: z.string(),\n checks: z.array(z.object({ ok: z.boolean(), why: z.string(), value: main.nullable(), facts, tail: z.string().optional() })),\n });\n return { cell, verdict, runs: z.array(run), manifests: z.array(manifest), loads: z.array(load), at: z.string() };\n};\n\nconst v2 = recordOf<Quantity>(time, quantitySchema([\"time\", \"count\"]));\nconst v1 = recordOf<number>(z.number(), z.number());\n\n/**\n * This schema accepts a record in the format `/2`. The median and the main value of each run must\n * have the unit of the prediction of the cell (`unitOf`).\n */\nexport const kindCellRecordSchema: z.ZodType<KindCellRecord> = z\n .object({ format: z.literal(FORMAT), ...v2 })\n .superRefine((record, ctx) => {\n const unit = unitOf(record.cell.prediction);\n const values = [record.verdict.median, ...record.verdict.checks.map((check) => check.value)];\n for (const value of values) {\n if (value !== null && value.unit !== unit)\n ctx.addIssue({ code: \"custom\", message: `the main value is in ${value.unit}, and the prediction ${record.cell.prediction.kind} gives ${unit}` });\n }\n });\n\n/** This schema accepts a record in the format `/1`. */\nexport const kindCellRecordV1Schema: z.ZodType<KindCellRecordV1> = z.object({ format: z.literal(FORMAT_V1), ...v1 });\n\n/** This function reads a record of either format from parsed JSON, and gives it in the format `/2`. */\nexport const readRecord = (data: unknown): KindCellRecord => {\n const format = typeof data === \"object\" && data !== null ? (data as { format?: unknown }).format : undefined;\n if (format === FORMAT_V1) return upgrade(kindCellRecordV1Schema.parse(data));\n if (format === FORMAT) return kindCellRecordSchema.parse(data);\n throw new Error(`a kind cell record has the format ${FORMAT} or ${FORMAT_V1}, not ${String(format)}`);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"judge-DjtNaAVO.js","names":["medianInterval","intervalOfMedian","time","medianInterval","time"],"sources":["../src/bands.ts","../src/names.ts","../src/stats.ts","../src/observe.ts","../src/reconnects.ts","../src/verdict.ts","../src/record.ts","../src/report.ts","../src/schema.ts"],"sourcesContent":["import type { Quantity } from \"@mark1russell7/quantity\";\nimport { valueIn } from \"@mark1russell7/quantity\";\nimport type { BacklogTerm, Band } from \"./cell.ts\";\n\n/** This module makes and prints the bands of the predictions. It imports only the amounts. */\n\n/** This function gives a time in seconds as a quantity. */\nexport const seconds = (value: number): Quantity => ({ value, unit: \"s\" });\n\n/** This function gives a band from its two ends in seconds. */\nexport const bandOf = (lo: number, hi: number): Band => ({ lo: seconds(lo), hi: seconds(hi) });\n\n/** This function gives the two ends of a band as numbers of seconds, for arithmetic. */\nexport const secondsOf = (band: Band): { readonly lo: number; readonly hi: number } => ({\n lo: valueIn(band.lo, \"s\"),\n hi: valueIn(band.hi, \"s\"),\n});\n\n/** This function gives a band in a short form for a name or a table: `[28, 49] s`. */\nexport const showBand = (band: Band): string => {\n const { lo, hi } = secondsOf(band);\n return `[${lo}, ${hi}] s`;\n};\n\n/** This function rounds a time to the microsecond, thus a band has no float residue. */\nconst us = (value: number): number => Math.round(value * 1e6) / 1e6;\n\n/**\n * This function gives the largest time after the band end at which the window of n sessions closes,\n * in seconds. Each session drains in d, thus it is n × d.hi. With `slowest` (SYS-45), one of the n\n * sessions can drain up to that time, thus it is (n − 1) × d.hi + the larger of `slowest` and d.hi.\n */\nconst closingOf = (term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, sessions: number): number => {\n const hi = valueIn(term.drain.hi, \"s\");\n if (term.slowest === undefined || sessions < 1) return sessions * hi;\n return (sessions - 1) * hi + Math.max(valueIn(term.slowest, \"s\"), hi);\n};\n\n/**\n * This function gives the end band of a window with the backlog term (`BacklogTerm`). It adds n × d\n * to each end of `end`, the end band without the term. The value n is the sessions on the target.\n * A term with `slowest` (SYS-45) adds (n − 1) × d.hi + `slowest` to the high end instead.\n */\nexport const backlogEnd = (end: Band, term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, sessions: number): Band => {\n const ends = secondsOf(end);\n const drain = secondsOf(term.drain);\n return bandOf(us(ends.lo + sessions * drain.lo), us(ends.hi + closingOf(term, sessions)));\n};\n\n/**\n * This function gives the band of the start of the last failed request of a window with the backlog\n * term, from the band end (the high end of `end`). This is the overshoot of a run. Its high end is\n * the high end of `backlogEnd`. Without `early`, its low end is n × d.lo (SYS-42). With `early`\n * (SYS-45), the last failed request can start up to one turn before the window closes. Its low end\n * is then the low end of `end` plus n × d.lo. The end band opens one turn before the band end.\n */\nexport const overshootBand = (end: Band, term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\" | \"early\">>, sessions: number): Band => {\n const ends = secondsOf(end);\n const closes = secondsOf(backlogEnd(end, term, sessions));\n const drain = secondsOf(term.drain);\n const lo = term.early === true ? closes.lo - ends.hi : sessions * drain.lo;\n return bandOf(us(lo), us(closes.hi - ends.hi));\n};\n\n/** A count band is a range of counts of requests. */\nexport interface CountBand {\n readonly lo: number;\n readonly hi: number;\n}\n\n/** This function gives a count rounded to six places, thus 10 s / 20 ms gives 500 and not 499.99999. */\nconst counted = (value: number): number => Math.round(value * 1e6) / 1e6;\n\n/** This function gives the turn of a session in seconds: the mean period of a client times its sessions. */\nconst turnOf = (mean: Quantity, connections: number): number => {\n const turn = valueIn(mean, \"s\") * connections;\n if (!(turn > 0)) throw new RangeError(`a turn of ${turn} s cannot count requests`);\n return turn;\n};\n\n/**\n * This function gives the drain failures of one session on the target (SYS-43). A session fails a\n * request each turn until the window closes. With n sessions on the target, the window closes up to\n * n × d.hi after the band end (`backlogEnd`). Thus one session fails 0 to ceil(n × d.hi / turn)\n * requests in the drain. The turn is the mean period of a client (`mean`) times its sessions\n * (`connections`). The term r is not in this band. With `slowest` (SYS-45), the window closes up to\n * (n − 1) × d.hi + `slowest` after the band end. Thus one session fails up to that time over the turn.\n */\nexport const drainBand = (term: Pick<BacklogTerm, \"drain\"> & Partial<Pick<BacklogTerm, \"slowest\">>, mean: Quantity, connections: number, sessions: number): CountBand => {\n const turn = turnOf(mean, connections);\n return { lo: 0, hi: Math.ceil(counted(closingOf(term, sessions) / turn)) };\n};\n\n/**\n * This function gives the failed requests that the backlog term predicts (`BacklogTerm`). Each of\n * the n sessions on the target gets a request each turn. The turn is the measured mean period of a\n * client (`mean`) times the sessions of the client (`connections`). The requests of a session fail\n * from the start of the window to the band end (`span`). That span holds `span / turn` requests, one\n * less at its low edge and one more at its high edge. Each session fails r more requests in its drain time.\n *\n * A term with `drains` (SYS-43) also adds the drain failures of each session (`drainBand`).\n */\nexport const requestBand = (\n term: Pick<BacklogTerm, \"requests\"> & Partial<Pick<BacklogTerm, \"drain\" | \"drains\" | \"slowest\">>,\n span: Quantity,\n mean: Quantity,\n connections: number,\n sessions: number,\n): CountBand => {\n const turn = turnOf(mean, connections);\n const each = counted(valueIn(span, \"s\") / turn);\n if (term.drains === true && term.drain === undefined) throw new RangeError(\"a term with drains has no drain time d\");\n const drained = term.drains === true ? drainBand({ drain: term.drain!, slowest: term.slowest }, mean, connections, sessions) : { lo: 0, hi: 0 };\n return { lo: sessions * (Math.floor(each) - 1 + term.requests.lo + drained.lo), hi: sessions * (Math.ceil(each) + 1 + term.requests.hi + drained.hi) };\n};\n","// The names and the ports of the objects of a cell. The judge reads them, thus this module imports\n// nothing.\n\n/** These are the ports of the app: its server, and its health server for the probes. */\nexport const PORT = 8080;\nexport const HEALTH_PORT = 9000;\n/** This label makes the watcher follow the log of a pod. */\nexport const LOG_LABEL = \"lab.systems/log\";\n/** These are the names of the objects of a cell. */\nexport const SERVER = \"lab\";\nexport const CLIENT = \"client\";\nexport const REDIS = \"redis\";\n/** This class of a Service of type LoadBalancer selects kube-vip (pkg/kubevip/constants.go of v1.3.1). */\nexport const LB_CLASS = \"kube-vip.io/kube-vip-class\";\n/** This annotation of a Service gives kube-vip the address of its VIP (pkg/kubevip/annotations.go of v1.3.1). */\nexport const VIP_ANNOTATION = \"kube-vip.io/loadbalancerIPs\";\n/** This is the name of the node of each client outside the cluster, in its lines (`KindCell.vip`). */\nexport const OUTSIDE = \"outside\";\n","// The statistics of a kind verdict: the median, the interval of the median and a quantile. They are\n// the statistics of the verdict of the harness, and a test holds them to it. The judge reads a\n// record without the harness, because the harness loads its Docker lab. The three statistics\n// come from @mark1russell7/rigor-statistics.\nimport { medianInterval as intervalOfMedian, median, quantileSorted } from \"@mark1russell7/rigor-statistics\";\n\n/** This fraction, δ_rel, is how far the median of a cell can be outside its band and stay equivalent. */\nexport const RELATIVE = 0.05;\n\n/**\n * This function gives the median of sorted values: the middle value, or the mean of the two middle values.\n * It is `median` of @mark1russell7/rigor-statistics, which throws a RangeError for an empty list.\n */\nexport const middle = (sorted: readonly number[]): number => median(sorted);\n\n/**\n * This function gives the value at quantile p of sorted values, by nearest rank: x_(⌈p·n⌉). It is\n * `quantileSorted` of @mark1russell7/rigor-statistics with the method `\"nearest-rank\"`.\n */\nexport const quantileOf = (sorted: readonly number[], p: number): number => quantileSorted(sorted, p, \"nearest-rank\");\n\n/**\n * This function gives the distribution-free interval of a median: [x_(k), x_(n+1−k)], for the\n * largest k whose two tails each hold 2.5 % or less. For eleven runs, it gives [x_(2), x_(10)],\n * at 98.8 %. It is `medianInterval` of @mark1russell7/rigor-statistics at the level 0.95. An\n * empty list throws a RangeError.\n */\nexport const medianInterval = (sorted: readonly number[]): [number, number] => {\n const interval = intervalOfMedian(sorted, 0.95);\n return [interval.low, interval.high];\n};\n","/**\n * This module reads a run from its lines. Each time is in milliseconds on CLOCK_MONOTONIC. All the\n * containers of the VM share that clock: the clients, the service, the agents, the injector, the\n * watcher and the prober.\n */\nimport { middle } from \"./stats.ts\";\n\n/**\n * A line is one JSON line of a source of a run, with its stamp `t` in milliseconds on\n * CLOCK_MONOTONIC. It is a request of a client, a record of the service, a line of grpc-go or a probe answer. It is\n * also a pod, an EndpointSlice or an event of the API. Or it is the backends of the rules of a\n * node, a kernel record, or an act of the lab. A record keeps each line as its source wrote it.\n */\nexport interface Line {\n readonly ev: string;\n readonly t: number;\n readonly [field: string]: unknown;\n}\n\n/**\n * A request is one request of a client: its start, its duration in ms, its outcome, its client and\n * the node of the client. The backend (`b`) is the pod that answered. The local port (`lp`) is on\n * each request from 0.1.3, and on the failed ones before it. A conntrack entry is per port, thus the\n * requests on one port show which connection a stale entry came from.\n */\nexport interface Request {\n readonly t: number;\n readonly d: number;\n readonly o: string;\n readonly p: string;\n readonly n: string;\n readonly b?: string;\n readonly lp?: number | null;\n}\n\n/** A pod line is one state of a pod, as the watcher received it. */\nexport interface PodLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly node: string | null;\n readonly ip: string | null;\n readonly del: boolean;\n readonly ready: boolean;\n readonly phase: string | null;\n readonly cs: ReadonlyArray<{ readonly n: string; readonly r: boolean; readonly rc: number; readonly st: string; readonly id: string | null }>;\n readonly labels: Readonly<Record<string, string>>;\n}\n\n/** An endpoint is one endpoint of an EndpointSlice: its address, its conditions and its pod. */\nexport interface Endpoint {\n readonly ip: string | null;\n readonly r: boolean | null;\n readonly s: boolean | null;\n readonly x: boolean | null;\n readonly pod: string | null;\n readonly node: string | null;\n}\n\n/** A slice line is one state of an EndpointSlice. */\nexport interface SliceLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly svc: string | null;\n readonly eps: readonly Endpoint[];\n}\n\n/**\n * A rules line is the backends of the Service in the rules of one node, after a change. `prev` is the\n * start of the poll before it. An EDS line has the same fields (`ev` is `eds`). It gives the healthy\n * hosts of the server cluster in the Envoy of the client sidecar on the node.\n */\nexport interface RulesLine {\n readonly t: number;\n readonly prev: number | null;\n readonly node: string;\n readonly b: readonly string[];\n}\n\n/**\n * A propagation source is the poll whose lines give the backends of each node:\n * - `rules`: the rules of kube-proxy in the namespaces of the node.\n * - `eds`: the hosts of the server cluster in the Envoy of the client sidecar on the node. In a sidecar\n * mesh, the client sidecar picks the backend of each call, thus kube-proxy is not on the path.\n */\nexport type PropagationSource = \"rules\" | \"eds\";\n\n/** A record line is one transition of a machine of the service, with its own stamp `at`. */\nexport interface RecordLine {\n readonly t: number;\n readonly at: number;\n readonly p: string;\n readonly m: string;\n readonly i: string;\n readonly from: string;\n readonly to: string;\n readonly on: string;\n readonly d: string | null;\n}\n\n/**\n * A socket line is the connect or the close of a socket of the channel of a gRPC client\n * (`client-lines.ts`). It gives the client (`p`) and its node (`n`), and the local port of the socket.\n * A close also gives the code of an error of the socket (`err`), or null for a close with no error.\n */\nexport interface SocketLine {\n readonly t: number;\n readonly what: \"connect\" | \"close\";\n readonly p: string;\n readonly n: string;\n readonly lp: number | null;\n readonly err?: string | null;\n /** This address is the local address of the socket at its connect: the address of the client pod. Lines before 0.8.0 do not have it. */\n readonly la?: string | null;\n}\n\n/** This port is the HBONE port of ztunnel in each pod of the ambient mesh of Istio 1.31.3: the mesh leg ends there. */\nexport const HBONE_PORT = 15008;\n\n/** These are the states of a TCP socket of Linux that a tunnel line names (include/net/tcp_states.h of Linux v6.17, lines 12–28). */\nexport const TCP_STATE = { established: 1, finWait1: 4, closeWait: 8 } as const;\n\n/**\n * A tunnel line is a change of the state of a TCP socket with the HBONE port at one end, from the\n * prober (`kernel.state`). `src` and `dst` are each an address and a port, `a.b.c.d:port`. The stamp\n * `t` is in ms on CLOCK_MONOTONIC.\n */\nexport interface TunnelLine {\n readonly t: number;\n readonly src: string;\n readonly dst: string;\n readonly old: number;\n readonly new: number;\n}\n\n/** This function tells if a kernel record is a change of the state of a socket of the HBONE port. */\nexport const isTunnelState = (record: Readonly<Record<string, unknown>>): boolean =>\n record[\"ev\"] === \"state\" && [record[\"src\"], record[\"dst\"]].some((end) => typeof end === \"string\" && end.endsWith(`:${HBONE_PORT}`));\n\n/** This function gives the tunnel lines of a run, in sequence of their stamps. */\nexport const tunnelsOf = (lines: readonly Line[]): TunnelLine[] =>\n lines.filter((line) => line.ev === \"kernel.state\").map((line) => line as unknown as TunnelLine).sort((a, b) => a.t - b.t);\n\nconst of = <T>(lines: readonly Line[], ev: string): T[] => lines.filter((line) => line.ev === ev) as unknown as T[];\n\nexport const requestsOf = (lines: readonly Line[]): Request[] => of<Request>(lines, \"req\");\nexport const podsOf = (lines: readonly Line[]): PodLine[] => of<PodLine>(lines, \"pod\").sort((a, b) => a.t - b.t);\nexport const slicesOf = (lines: readonly Line[], svc: string): SliceLine[] =>\n of<SliceLine>(lines, \"slice\").filter((line) => line.svc === svc);\nexport const rulesOf = (lines: readonly Line[], source: PropagationSource = \"rules\"): RulesLine[] =>\n of<RulesLine>(lines, source).sort((a, b) => a.t - b.t);\nexport const recordsOf = (lines: readonly Line[]): RecordLine[] => of<RecordLine>(lines, \"rec\");\nexport const socketsOf = (lines: readonly Line[]): SocketLine[] => of<SocketLine>(lines, \"sock\").sort((a, b) => a.t - b.t);\n\n/** This function gives the requests that did not succeed, in sequence of their start. */\nexport const failuresOf = (lines: readonly Line[]): Request[] =>\n requestsOf(lines)\n .filter((request) => request.o !== \"ok\")\n .sort((a, b) => a.t - b.t);\n\n/** This function counts the outcomes of the requests, by outcome. */\nexport const outcomesOf = (requests: readonly Request[]): Record<string, number> => {\n const out: Record<string, number> = {};\n for (const request of requests) out[request.o] = (out[request.o] ?? 0) + 1;\n return out;\n};\n\n/**\n * This function orders the replicas by how many clients each one answered last, the most first,\n * then by name. `answers` gives the backend of the last answer of each client, by client. A client\n * of gRPC holds its connection to one replica, thus the first replica is the one whose stop the\n * most clients see.\n */\nexport const byClients = <T extends { readonly pod: string }>(replicas: readonly T[], answers: ReadonlyMap<string, string>): T[] => {\n const count = (pod: string): number => [...answers.values()].filter((backend) => backend === pod).length;\n return [...replicas].sort((a, b) => count(b.pod) - count(a.pod) || a.pod.localeCompare(b.pod));\n};\n\n/** These are the sessions of the clients at an instant: those on the target, of all, and those on the target by client. */\nexport interface Sessions {\n readonly onTarget: number;\n readonly of: number;\n readonly byClient: Readonly<Record<string, number>>;\n}\n\n/**\n * This function gives the sessions of the clients at an instant (`at`), and how many of them are on\n * the target pod. A client sends each request on its next session in turn. Thus its last `connections`\n * requests that started before the instant name its sessions, each by its local port. The backend of\n * a session is the body of the last answer on its port before the instant: the name of the pod. A\n * session with no such answer is not on the target. A request with no port names no session.\n */\nexport const sessionsAt = (lines: readonly Line[], at: number, target: string, connections: number): Sessions => {\n const before = requestsOf(lines)\n .filter((request) => request.t < at)\n .sort((a, b) => a.t - b.t);\n const byClient: Record<string, number> = {};\n let of = 0;\n for (const client of [...new Set(before.map((request) => request.p))].sort()) {\n const mine = before.filter((request) => request.p === client);\n const ports = new Set(mine.slice(-connections).flatMap((request) => (typeof request.lp === \"number\" ? [request.lp] : [])));\n const backend = (port: number): string | undefined => mine.filter((request) => request.lp === port && request.o === \"ok\" && request.b !== undefined).at(-1)?.b;\n byClient[client] = [...ports].filter((port) => backend(port) === target).length;\n of += ports.size;\n }\n return { onTarget: Object.values(byClient).reduce((sum, count) => sum + count, 0), of, byClient };\n};\n\n/**\n * The period of the clients is the interval between the starts of two requests in sequence of one\n * client. Each time is in milliseconds when `A` is a number. The median and the mean are of all the\n * intervals of all the clients, and `low` and `high` are the smallest and the largest interval.\n * `intervals` is their count, and `byClient` is the median of each client. A client with c kept\n * connections sends on each one in turn, thus each of its sessions gets a request each c periods.\n */\nexport interface Period<A = number> {\n readonly median: A;\n readonly mean: A;\n readonly low: A;\n readonly high: A;\n readonly intervals: number;\n readonly byClient: Readonly<Record<string, A>>;\n}\n\n/**\n * This function gives the measured period of the clients from their request lines that start from\n * `from` to `to`. The timer of a client is late by a different amount at each tick. Thus the median\n * stays near the setting of the client (`every`), but the lateness adds up in the mean.\n *\n * The mean is the span of the requests of each client over its intervals. A band can count the requests of a client in a window from the\n * mean. A client with fewer than 2 requests gives no interval. A run with no interval gives null.\n */\nexport const periodOf = (lines: readonly Line[], from: number, to: number): Period | null => {\n const starts = new Map<string, number[]>();\n for (const request of requestsOf(lines)) {\n if (request.t < from || request.t > to) continue;\n const mine = starts.get(request.p) ?? [];\n mine.push(request.t);\n starts.set(request.p, mine);\n }\n const all: number[] = [];\n const byClient: Record<string, number> = {};\n let span = 0;\n for (const client of [...starts.keys()].sort()) {\n const mine = starts.get(client)!.sort((a, b) => a - b);\n if (mine.length < 2) continue;\n const intervals = mine.slice(1).map((t, at) => t - mine[at]!);\n span += mine.at(-1)! - mine[0]!;\n all.push(...intervals);\n byClient[client] = middle(intervals.sort((a, b) => a - b));\n }\n if (all.length === 0) return null;\n all.sort((a, b) => a - b);\n return { median: middle(all), mean: span / all.length, low: all[0]!, high: all.at(-1)!, intervals: all.length, byClient };\n};\n\n/** This function gives the requests of each node, by the name of the node. */\nexport const byNode = (requests: readonly Request[]): Map<string, Request[]> => {\n const out = new Map<string, Request[]>();\n for (const request of requests) out.set(request.n, [...(out.get(request.n) ?? []), request]);\n return out;\n};\n\n/** This function gives the time that the watcher first received a deletion timestamp of one of the pods, after a time. */\nexport const deletionOf = (lines: readonly Line[], pods: readonly string[], after: number): number | null =>\n podsOf(lines).find((pod) => pods.includes(pod.name) && pod.del && pod.t >= after)?.t ?? null;\n\n/**\n * A ztunnel pod line is an event of a ztunnel pod in istio-system, from the watcher (`image/watch.mjs`).\n * Its `type` is the type of the event of the API, and `cs` gives the readiness of each container (`r`).\n */\nexport interface ZtunnelPodLine {\n readonly t: number;\n readonly type: string;\n readonly name: string;\n readonly node: string | null;\n readonly del: boolean;\n readonly cs: ReadonlyArray<{ readonly r: boolean }>;\n}\n\nexport const ztunnelPodsOf = (lines: readonly Line[]): ZtunnelPodLine[] => of<ZtunnelPodLine>(lines, \"ztunnel-pod\").sort((a, b) => a.t - b.t);\n\n/** This function gives the time that the watcher first received a deletion timestamp of a ztunnel pod, after a time: the reference `restart`. */\nexport const restartOf = (lines: readonly Line[], after: number): number | null => ztunnelPodsOf(lines).find((pod) => pod.del && pod.t >= after)?.t ?? null;\n\n/**\n * This function tells if a restart of ztunnel is over. Each ztunnel pod that got a deletion in the\n * lines is gone. Each node has a ready ztunnel pod with no deletion. It is false when no ztunnel pod\n * got a deletion.\n */\nexport const ztunnelReplaced = (lines: readonly Line[], nodes: readonly string[]): boolean => {\n const last = new Map<string, ZtunnelPodLine>();\n for (const pod of ztunnelPodsOf(lines)) last.set(pod.name, pod);\n const deleted = [...last.values()].filter((pod) => pod.del || pod.type === \"DELETED\");\n if (deleted.length === 0 || deleted.some((pod) => pod.type !== \"DELETED\")) return false;\n const ready = new Set(\n [...last.values()].filter((pod) => !pod.del && pod.type !== \"DELETED\" && pod.cs.length > 0 && pod.cs.every((status) => status.r)).map((pod) => pod.node),\n );\n return nodes.every((node) => ready.has(node));\n};\n\n/** This function gives the stamp of a transition of the service in a pod: the first matching record of a machine, after a time. */\nexport const transitionOf = (\n lines: readonly Line[],\n pod: string,\n machine: string,\n match: (record: RecordLine) => boolean,\n after: number,\n): number | null =>\n recordsOf(lines).find((record) => record.p === pod && record.m === machine && record.at >= after && match(record))?.at ?? null;\n\n/**\n * This function gives the line `stopping` of grpc-go in a pod, after a time. The server writes it at\n * SIGTERM. Then GracefulStop closes its listener and sends GOAWAY on each connection.\n */\nexport const stoppingOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n lines.find((line) => line.ev === \"stopping\" && line[\"p\"] === pod && line.t >= after)?.t ?? null;\n\n/**\n * This function gives when the server of a pod stopped its intake. That is the start of the phase\n * `stop intake` of the service, or the line `stopping` of grpc-go.\n */\nexport const intakeOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n transitionOf(lines, pod, \"drain\", (record) => record.to === \"stop intake\", after) ?? stoppingOf(lines, pod, after);\n\n/** This function gives when the server of a pod received its exit signal: a record of the service, or the line `stopping` of grpc-go. */\nexport const signalOf = (lines: readonly Line[], pod: string, after: number): number | null =>\n transitionOf(lines, pod, \"exit\", (record) => record.on === \"exit.request\", after) ?? stoppingOf(lines, pod, after);\n\n/**\n * This function gives when the rules of a node stopped the selection of a backend: the first poll\n * after a time without it. The change came after `prev`, the poll before it, and at the latest at `t`.\n * The source `eds` gives the same for the client sidecar of the node.\n */\nexport const dropOf = (lines: readonly Line[], node: string, backend: string, after: number, source: PropagationSource = \"rules\"): RulesLine | null =>\n rulesOf(lines, source).find((line) => line.node === node && line.t >= after && !line.b.includes(backend)) ?? null;\n\n/** This function gives when the rules of a node had no backend of the Service, after a time. */\nexport const emptyOf = (lines: readonly Line[], node: string, after: number): RulesLine | null =>\n rulesOf(lines).find((line) => line.node === node && line.t >= after && line.b.length === 0) ?? null;\n\n/** This function gives when an EndpointSlice of the Service first had no ready endpoint, after a time. */\nexport const sliceEmptyOf = (lines: readonly Line[], svc: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;\n\n/** This function gives when an EndpointSlice of the Service first had a ready endpoint, after a time. */\nexport const sliceReadyOf = (lines: readonly Line[], svc: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;\n\n/**\n * This function tells if the latest EndpointSlice of the Service at a time had a ready endpoint. A\n * slice line comes only at a change, thus with no line before the time, it gives null.\n */\nexport const sliceReadyAt = (lines: readonly Line[], svc: string, at: number): boolean | null => {\n const latest = slicesOf(lines, svc).filter((slice) => slice.t <= at).at(-1);\n return latest === undefined ? null : latest.eps.some((endpoint) => endpoint.r === true);\n};\n\n/** This function gives when the endpoint of an address was first not ready in the EndpointSlice of the Service, after a time. */\nexport const sliceDropOf = (lines: readonly Line[], svc: string, ip: string, after: number): number | null =>\n slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.ip === ip && endpoint.r === true))?.t ?? null;\n\n/** This function gives the latest state of each pod at a time, by its name. A deleted pod is not in it. */\nexport const podsAt = (lines: readonly Line[], at: number): Map<string, PodLine> => {\n const out = new Map<string, PodLine>();\n for (const pod of podsOf(lines)) {\n if (pod.t > at) break;\n if (pod.type === \"DELETED\") out.delete(pod.name);\n else out.set(pod.name, pod);\n }\n return out;\n};\n\n/** This function gives the latest backends of each node at a time, by node. */\nexport const backendsAt = (lines: readonly Line[], at: number): Map<string, readonly string[]> => {\n const out = new Map<string, readonly string[]>();\n for (const line of rulesOf(lines)) {\n if (line.t > at) break;\n out.set(line.node, line.b);\n }\n return out;\n};\n\n/** This function gives the kernel records of the kinds that the lab keeps, counted by kind. */\nexport const kernelCounts = (lines: readonly Line[]): Record<string, number> => {\n const out: Record<string, number> = {};\n for (const line of lines) if (line.ev.startsWith(\"kernel.\")) out[line.ev.slice(7)] = (out[line.ev.slice(7)] ?? 0) + 1;\n return out;\n};\n\n/** This function gives the SIGTERM of each pod in a set after a time, by pod. A pod without one is not in it. */\nexport const signalsOf = (lines: readonly Line[], pods: readonly string[], after: number): Map<string, number> => {\n const out = new Map<string, number>();\n for (const pod of pods) {\n const at = signalOf(lines, pod, after);\n if (at !== null) out.set(pod, at);\n }\n return out;\n};\n\n/** This function gives the restart count of each container of each pod at a time, summed by pod. */\nexport const restartsAt = (lines: readonly Line[], at: number): Map<string, number> => {\n const out = new Map<string, number>();\n for (const [name, pod] of podsAt(lines, at)) out.set(name, pod.cs.reduce((sum, status) => sum + status.rc, 0));\n return out;\n};\n","import { valueIn } from \"@mark1russell7/quantity\";\nimport type { Backoff, ReconnectsPrediction } from \"./cell.ts\";\nimport type { Line } from \"./observe.ts\";\n\n/**\n * This module judges the return of the producers of a message broker after the stop of the broker\n * that owns their topic (SYS-56). It knows the backoff of a client and the lines of the lab, and\n * nothing of Pulsar. Each time is in milliseconds, on the clock of the lines.\n *\n * The backoff is the law of `Backoff::next` of the C++ client of Pulsar 4.2.0 (lib/Backoff.cc,\n * lines 33–57). The first delay is the initial delay, and each next delay is two times the last, up\n * to the most. The first call keeps its time. If a later call ends after the mandatory stop, it\n * gets the rest of the time to that stop, once. Then the call takes a random share of up to the\n * jitter from the delay. The delay is not below the initial delay at any time.\n */\n\n/** A try is the earliest and the latest time of one try to connect, after the first delay starts. */\nexport interface Try {\n readonly lo: number;\n readonly hi: number;\n}\n\n/** This is a backoff in milliseconds. */\ninterface Delays {\n readonly initial: number;\n readonly max: number;\n readonly stop: number;\n readonly jitter: number;\n}\n\nconst delaysOf = (backoff: Backoff): Delays => ({\n initial: valueIn(backoff.initial, \"ms\"),\n max: valueIn(backoff.max, \"ms\"),\n stop: valueIn(backoff.mandatoryStop, \"ms\"),\n jitter: backoff.jitter,\n});\n\n/**\n * This function gives the times of the tries of one path: each delay times `share`, and `latency`\n * from each try to the next call. The tries end with the first one after `until`.\n */\nconst pathOf = (delays: Delays, share: number, latency: number, until: number): number[] => {\n const tries: number[] = [];\n let next = delays.initial;\n let call = 0;\n let made = false;\n for (let count = 0; count < 1000; count += 1) {\n let current = next;\n next = Math.min(2 * next, delays.max);\n if (!made && call + current > delays.stop) {\n current = Math.max(delays.initial, delays.stop - call);\n made = true;\n }\n const at = call + Math.max(delays.initial, current * share);\n tries.push(at);\n if (at > until) break;\n call = at + latency;\n }\n return tries;\n};\n\n/**\n * This function gives the band of each try after the first delay starts, up to the first try whose\n * earliest time is after `until`. The earliest path has the most jitter and no time for a try. The\n * latest path has no jitter and `attempt` for each failed try. A later call gets a delay that ends no\n * earlier, thus each try of a path between them is in the band.\n */\nexport const triesOf = (backoff: Backoff, until: number): Try[] => {\n const delays = delaysOf(backoff);\n const late = pathOf(delays, 1, valueIn(backoff.attempt, \"ms\"), Number.POSITIVE_INFINITY);\n const early = pathOf(delays, 1 - delays.jitter, 0, until);\n return early.map((lo, index) => ({ lo, hi: late[index] ?? Number.POSITIVE_INFINITY }));\n};\n\n/**\n * This function gives the latest return of a producer after the fault, from the bands of the\n * prediction. It adds three terms. The first is the first delay at its latest. The second is the\n * latest time of the first try that cannot come before the latest change of the owner. The third\n * is the latest setup.\n */\nexport const latestReturn = (prediction: ReconnectsPrediction): number => {\n const disconnect = { lo: valueIn(prediction.disconnect.lo, \"ms\"), hi: valueIn(prediction.disconnect.hi, \"ms\") };\n const flip = valueIn(prediction.flip.hi, \"ms\");\n const tries = triesOf(prediction.backoff, flip - disconnect.lo);\n const after = tries.find((each) => each.lo >= flip - disconnect.lo) ?? tries.at(-1)!;\n return disconnect.hi + after.hi + valueIn(prediction.setup.hi, \"ms\");\n};\n\n/** This function gives the delay of each call of a backoff, as an interval, with `elapsed` from the first call to this one. */\nconst delayBand = (delays: Delays, index: number, elapsed: number, made: boolean, noise: number): { lo: number; hi: number; made: boolean; either: boolean } => {\n const nominal = Math.min(delays.initial * 2 ** index, delays.max);\n const band = (current: number) => ({ lo: Math.max(delays.initial, current * (1 - delays.jitter)), hi: Math.max(delays.initial, current) });\n if (made) return { ...band(nominal), made, either: false };\n const clamped = band(Math.max(delays.initial, delays.stop - elapsed));\n const plain = band(nominal);\n // the clock of the client and the clock of the lines differ by up to the noise: near the stop, each branch agrees\n if (Math.abs(elapsed + nominal - delays.stop) <= noise) return { lo: Math.min(clamped.lo, plain.lo), hi: Math.max(clamped.hi, plain.hi), made: false, either: true };\n return elapsed + nominal > delays.stop ? { ...clamped, made: true, either: false } : { ...plain, made: false, either: false };\n};\n\n/** This text is the start of the line of the C++ client that schedules a try: \"Schedule reconnection in 0.1 s\". */\nconst SCHEDULE = /Schedule reconnection in ([0-9.]+) s/;\n\n/** A schedule is one call of the backoff of a producer: when, and its delay in milliseconds. */\nexport interface Schedule {\n readonly t: number;\n readonly delay: number;\n}\n\n/** A return is the facts of one producer in one run. */\nexport interface Return {\n readonly pod: string;\n /** This time is the first call of the backoff after the fault, from the fault. */\n readonly disconnect: number | null;\n /** These are the calls of the backoff from the fault to the producer on the new owner. */\n readonly schedules: readonly Schedule[];\n /** This time is the producer on the new owner, from the fault, or null. */\n readonly back: number | null;\n /** This time is from the try that succeeded to the producer on the new owner. */\n readonly setup: number | null;\n /** This count is the tries up to the one that succeeded. */\n readonly tries: number;\n readonly ok: boolean;\n readonly why: string;\n}\n\n/** A judgement is the facts of one run: the change of the owner, each producer, and the failed sends. */\nexport interface Reconnects {\n readonly ok: boolean;\n readonly why: string;\n /** This time is the first lookup that names another owner, from the fault, or null. */\n readonly flip: number | null;\n /** This time is from the last lookup before that change to it. */\n readonly gap: number | null;\n readonly returns: readonly Return[];\n /** This count is the sends of the producers that failed, by outcome. */\n readonly failures: Readonly<Record<string, number>>;\n /** This time is the median return of the producers, from the fault, or null. */\n readonly value: number | null;\n}\n\nconst text = (line: Line, field: string): string | null => (typeof line[field] === \"string\" ? (line[field] as string) : null);\n\n/**\n * This function judges one run: the fault at `fault`, the broker `broker` that owned the topic, and\n * the lines of the run. A lookup line is `{ev: \"lookup\", t, o, owner}`, a line of the client is\n * `{ev: \"pulsar\", t, p, m}`, and a send is `{ev: \"send\", t, d, o, p}`. `timeout` and `every` are the\n * timeout and the interval of the sends. Each check has a margin of `noise`.\n *\n * For each producer, the delays of its backoff follow the law, from the observed time of each call.\n * Its last try comes after the last lookup that named the old owner. The try before it comes no\n * later than the first lookup that named another. Then the setup is in its band. Each failed send\n * starts between the fault and the return, with an outcome of the prediction. At least one fails.\n *\n * With `owner: \"either\"`, the lookups can name the old owner for the whole run, because it started\n * again and took the topic back. Then the last try comes after the start of the band `flip`. The\n * try before it comes no later than the end of that band.\n */\nexport const judgeReconnects = (\n prediction: ReconnectsPrediction,\n run: { readonly fault: number; readonly broker: string; readonly lines: readonly Line[] },\n sends: { readonly timeout: number; readonly every: number },\n noise: number,\n): Reconnects => {\n const { fault, broker, lines } = run;\n const ms = (band: { readonly lo: Parameters<typeof valueIn>[0]; readonly hi: Parameters<typeof valueIn>[0] }) => ({ lo: valueIn(band.lo, \"ms\"), hi: valueIn(band.hi, \"ms\") });\n const inBand = (value: number, band: { lo: number; hi: number }) => value >= band.lo - noise && value <= band.hi + noise;\n const lookups = lines.filter((line) => line.ev === \"lookup\" && line.t >= fault).sort((a, b) => a.t - b.t);\n const changed = lookups.findIndex((line) => line[\"o\"] === \"ok\" && text(line, \"owner\") !== null && text(line, \"owner\") !== broker);\n const fail = (why: string, more: Partial<Reconnects> = {}): Reconnects => ({ ok: false, why, flip: null, gap: null, returns: [], failures: {}, value: null, ...more });\n if (changed === -1 && prediction.owner !== \"either\") return fail(`no lookup after the fault names an owner other than ${broker}`);\n const band = ms(prediction.flip);\n // the lookups name one broker before and after the change: only the band of the change bounds the tries\n const same = changed === -1;\n const flipAt = same ? fault + band.hi : lookups[changed]!.t;\n const before = same ? fault + band.lo : changed === 0 ? fault : lookups[changed - 1]!.t;\n const flip = same ? null : flipAt - fault;\n const gap = same ? null : flipAt - before;\n if (flip !== null && !inBand(flip, band)) return fail(`the first lookup with another owner is ${flip.toFixed(0)} ms after the fault, outside the band`, { flip, gap });\n if (gap !== null && gap > valueIn(prediction.probe, \"ms\") + noise) return fail(`the lookups have a gap of ${gap.toFixed(0)} ms before the change of the owner`, { flip, gap });\n const delays = delaysOf(prediction.backoff);\n const setup = ms(prediction.setup);\n const disconnect = ms(prediction.disconnect);\n const pods = [...new Set(lines.filter((line) => line.ev === \"send\").map((line) => String(line[\"p\"])))].sort();\n if (pods.length === 0) return fail(\"the run has no sends\", { flip, gap });\n const returns: Return[] = pods.map((pod) => {\n const own = lines.filter((line) => line.ev === \"pulsar\" && line[\"p\"] === pod && line.t >= fault - noise).sort((a, b) => a.t - b.t);\n const created = own.find((line) => (text(line, \"m\") ?? \"\").includes(\"Created producer on broker\"));\n const back = created === undefined ? null : created.t - fault;\n const schedules: Schedule[] = own\n .filter((line) => created === undefined || line.t <= created.t)\n .flatMap((line) => {\n const found = SCHEDULE.exec(text(line, \"m\") ?? \"\");\n return found === null ? [] : [{ t: line.t, delay: Number(found[1]) * 1000 }];\n });\n const first = schedules[0];\n const facts = { pod, disconnect: first === undefined ? null : first.t - fault, schedules, back, tries: schedules.length };\n const no = (why: string, more: Partial<Return> = {}): Return => ({ ...facts, setup: null, ...more, ok: false, why: `${pod}: ${why}` });\n if (created === undefined) return no(\"the producer is not back on a broker after the fault\");\n if (first === undefined) return no(\"the producer schedules no try after the fault\");\n if (!inBand(first.t - fault, disconnect)) return no(`its first try is scheduled ${(first.t - fault).toFixed(0)} ms after the fault, outside the band`);\n let made = false;\n for (const [index, schedule] of schedules.entries()) {\n const band = delayBand(delays, index, schedule.t - first.t, made, noise);\n // the line gives the delay in whole milliseconds\n if (schedule.delay < band.lo - 1 || schedule.delay > band.hi + 1)\n return no(`the delay ${index + 1} is ${schedule.delay} ms, not in ${band.lo.toFixed(0)}–${band.hi.toFixed(0)} ms of the backoff`);\n // near the stop, a delay below the plain band shows that the client took the rest to the stop\n made = band.either ? schedule.delay < Math.min(delays.initial * 2 ** index, delays.max) * (1 - delays.jitter) - 1 : band.made;\n }\n const tries = schedules.map((schedule) => schedule.t + schedule.delay);\n const last = tries.at(-1)!;\n const earlier = tries.at(-2);\n if (last < before - noise) return no(`its last try at ${(last - fault).toFixed(0)} ms comes before the last lookup of the old owner`);\n if (earlier !== undefined && earlier > flipAt + noise) return no(`its try at ${(earlier - fault).toFixed(0)} ms comes after the change of the owner, and it did not succeed`);\n const took = created.t - last;\n if (!inBand(took, setup)) return no(`its setup takes ${took.toFixed(0)} ms, outside the band`, { setup: took });\n return { ...facts, setup: took, ok: true, why: `${pod}: back ${(created.t - fault).toFixed(0)} ms after the fault, at try ${tries.length}` };\n });\n const failed = lines.filter((line) => line.ev === \"send\" && line[\"o\"] !== \"ok\").sort((a, b) => a.t - b.t);\n const failures: Record<string, number> = {};\n for (const line of failed) failures[String(line[\"o\"])] = (failures[String(line[\"o\"])] ?? 0) + 1;\n const backs = returns.flatMap((each) => (each.back === null ? [] : [each.back])).sort((a, b) => a - b);\n const value = backs.length === 0 ? null : backs.length % 2 === 1 ? backs[(backs.length - 1) / 2]! : (backs[backs.length / 2 - 1]! + backs[backs.length / 2]!) / 2;\n const done = (ok: boolean, why: string): Reconnects => ({ ok, why, flip, gap, returns, failures, value });\n const wrong = returns.find((each) => !each.ok);\n if (wrong !== undefined) return done(false, wrong.why);\n const other = failed.find((line) => !prediction.outcomes.includes(String(line[\"o\"])));\n if (other !== undefined) return done(false, `a send of ${String(other[\"p\"])} ended ${String(other[\"o\"])}, not ${prediction.outcomes.join(\" or \")}`);\n if (failed.length === 0) return done(false, \"no send failed\");\n for (const each of returns) {\n const own = failed.filter((line) => line[\"p\"] === each.pod);\n const back = fault + each.back!;\n const outside = own.find((line) => line.t < fault - sends.timeout - noise || line.t > back + noise);\n if (outside !== undefined) return done(false, `a send of ${each.pod} at ${(outside.t - fault).toFixed(0)} ms failed outside the time to its return`);\n const latest = own.at(-1);\n if (latest === undefined) return done(false, `no send of ${each.pod} failed`);\n if (latest.t < back - sends.timeout - sends.every - noise) return done(false, `the last failed send of ${each.pod} is ${(back - latest.t).toFixed(0)} ms before its return`);\n }\n return done(true, `${flip === null ? \"the stopped broker owns the topic again\" : `another owner ${flip.toFixed(0)} ms after the fault`}; ${returns.map((each) => `${each.pod} back at try ${each.tries}`).join(\", \")}`);\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { valueIn } from \"@mark1russell7/quantity\";\nimport { backlogEnd, requestBand, seconds, secondsOf } from \"./bands.ts\";\nimport type { BacklogTerm, Cycle, KindCell, KindRun, Prediction, Reference, ResetReuse, WindowPrediction } from \"./cell.ts\";\nimport { PORT, SERVER } from \"./names.ts\";\nimport type { Line, Period, PropagationSource, Request, Sessions } from \"./observe.ts\";\nimport {\n HBONE_PORT,\n backendsAt,\n TCP_STATE,\n byNode,\n deletionOf,\n dropOf,\n emptyOf,\n failuresOf,\n intakeOf,\n outcomesOf,\n periodOf,\n podsOf,\n requestsOf,\n restartOf,\n sessionsAt,\n signalsOf,\n sliceDropOf,\n sliceEmptyOf,\n sliceReadyAt,\n sliceReadyOf,\n socketsOf,\n tunnelsOf,\n} from \"./observe.ts\";\nimport { RELATIVE, medianInterval, middle } from \"./stats.ts\";\nimport { judgeReconnects, latestReturn } from \"./reconnects.ts\";\n\n/**\n * This time is δ for kind: each time of a run lands in its band ± δ. Its parts are the interval of\n * the poll of the rules (50 ms) and the delay of the watcher. The watcher receives each change after\n * the API server writes it.\n */\nexport const KIND_NOISE: Quantity = { value: 100, unit: \"ms\" };\n/**\n * This time is how much earlier than the end of its window the last failed request can start. A\n * request goes to the closed pod by the choice of the rules, thus the last ones before the end can\n * go to another pod. At 50 requests a second and two pods, 12 requests in sequence miss the closed\n * pod with a chance of 1 in 4096.\n */\nexport const LAST_SLACK: Quantity = { value: 250, unit: \"ms\" };\n\n/** These are δ and the slack in milliseconds, the unit of the stamps. */\nconst NOISE = valueIn(KIND_NOISE, \"ms\");\nconst SLACK = valueIn(LAST_SLACK, \"ms\");\n\n/** A propagated change is when the rules of a node first had it: after the poll `after`, and by the poll `by`. */\nexport interface Propagated<A = Quantity> {\n readonly after: A | null;\n readonly by: A;\n}\n\n/**\n * The facts of a run are what each table reads: its failures by outcome and node, and the times of\n * its target. A count stays a number, and so does a stamp: `first`, `last` and `deletion` are\n * readings of CLOCK_MONOTONIC in milliseconds. Each other time is an amount after a reference. The\n * parameter `A` is the form of an amount: a quantity in the format `/2`, seconds in the format `/1`.\n */\nexport interface RunFacts<A = Quantity> {\n readonly failures: number;\n readonly outcomes: Readonly<Record<string, number>>;\n readonly byNode: Readonly<Record<string, number>>;\n readonly first: number | null;\n readonly last: number | null;\n readonly deletion: number | null;\n readonly intakeAfterDeletion: A | null;\n readonly sliceAfter: A | null;\n /** This record is the propagation of the target to the rules of each node, by node. */\n readonly propagation: Readonly<Record<string, Propagated<A> | null>>;\n /** This time is when the EndpointSlice had no ready endpoint, after the fault (`removal`). */\n readonly sliceEmpty?: A | undefined;\n /** These times are when the rules of each node had no backend, after the fault (`removal`). */\n readonly rules?: Readonly<Record<string, A | null>> | undefined;\n /** This time is when the target left the EndpointSlice, after the fault (`leaves`). */\n readonly left?: A | undefined;\n /** These times are the SIGTERM of each replica, after the fault (`restarts`). */\n readonly signals?: ReadonlyArray<A | null> | undefined;\n /**\n * These are the replicas of a window for each deleted replica (`each`). Each one is a replica of the\n * run with a deletion after its start, with the stamps of its intake and of its deletion.\n */\n readonly deletions?: readonly Deleted[] | undefined;\n /** These are the first LDS updates of the sidecar of each server pod after the fault, by pod (`updatesOf`). */\n readonly updates?: Readonly<Record<string, Propagated<A> | null>> | undefined;\n /** These are the first LDS updates of the sidecar of each server pod after the heal, by pod. */\n readonly healUpdates?: Readonly<Record<string, Propagated<A> | null>> | undefined;\n /** These are the first close of the socket of each client after the reference (`ends`), by client, or null for none. */\n readonly closes?: Readonly<Record<string, A | null>> | undefined;\n /**\n * These are the times of each cycle of a removal with flaps, in the sequence of the cycles. `empty` is\n * when the EndpointSlice had no ready endpoint, after the fault of the cycle. `ready` is when it had a\n * ready endpoint again, after the heal of the cycle. A time that the run does not have is null.\n */\n readonly cycles?: ReadonlyArray<{ readonly empty: A | null; readonly ready: A | null }> | undefined;\n /**\n * These are the sessions of the clients at the fault (`sessionsAt`): those on the target, of all,\n * and those on the target by client. A run of a workload with kept connections and a target has them.\n */\n readonly sessions?: Sessions | undefined;\n /**\n * This is the stall of the target (`app-stall`): its start after the fault, and how long its loop\n * stayed blocked. The app writes a line at each end of the stall. A run with no such line gives null.\n */\n readonly stall?: { readonly start: A | null; readonly held: A | null } | undefined;\n /**\n * This is the measured period of the clients (`periodOf`): the interval between two requests in\n * sequence of one client. It comes from the request lines of the counted span of the run. A run\n * with fewer than 2 requests of each client does not have it. A record before SYS-41 does not have it.\n */\n readonly period?: Period<A> | undefined;\n /**\n * These are the facts of the return of the producers (`reconnects`, SYS-56). They are the first\n * lookup with another owner, the gap of the lookups before it, each producer, and the failed sends\n * by outcome. Each time is from the fault, but `gap`.\n */\n readonly reconnects?: ReconnectsFacts<A> | undefined;\n}\n\n/** These are the facts of the return of the producers of a run (`RunFacts.reconnects`). */\nexport interface ReconnectsFacts<A = Quantity> {\n readonly flip: A | null;\n readonly gap: A | null;\n readonly returns: ReadonlyArray<{ readonly pod: string; readonly disconnect: A | null; readonly back: A | null; readonly setup: A | null; readonly tries: number }>;\n readonly failures: Readonly<Record<string, number>>;\n}\n\n/** A deleted replica is a replica of a run that got a deletion. It gives its pod, and the stamps of its intake (or null) and of its deletion. */\nexport interface Deleted {\n readonly pod: string;\n readonly intake: number | null;\n readonly deletion: number;\n}\n\n/**\n * A run check is the judgement of one run: if it agrees with the prediction, why, its main value,\n * and its facts. The main value is a time, or a count of requests or of replicas (`unitOf`).\n */\nexport interface RunCheck<A = Quantity> {\n readonly ok: boolean;\n readonly why: string;\n readonly value: A | null;\n readonly facts: RunFacts<A>;\n /**\n * This text tells why a run that agrees with the law is past its calibrated band. A request failed\n * after the window, but before the rules of its node dropped the target. Such a run makes its cell\n * `extend`, and the cell does not hold (D-EXTEND).\n */\n readonly tail?: string | undefined;\n}\n\n/** A kind decision is the result of a kind cell. */\nexport type KindDecision = \"holds\" | \"fails\" | \"extend\" | \"measured\" | \"calibration\" | \"void\";\n\n/** A kind verdict is the judgement of a cell on its counted runs. */\nexport interface KindVerdict<A = Quantity> {\n readonly decision: KindDecision;\n readonly counted: number;\n readonly voided: number;\n readonly failed: number;\n /** This amount is the median of the main value of the counted runs, or null. */\n readonly median: A | null;\n readonly why: string;\n readonly checks: ReadonlyArray<RunCheck<A>>;\n}\n\n/**\n * This function gives the unit of the main value of a cell, from its prediction:\n * - `s` for a time: the removal, the departure or the restart of a band, the end of a stall, or a close.\n * - `{request}` for the failed requests: no failure, a window, a fleet that stays, and a measurement.\n * - `{replica}` for the replicas that received SIGTERM, when no replica must restart.\n * - `{socket}` for the sockets of the clients that ended, when no socket must end.\n */\nexport const unitOf = (prediction: { readonly kind: Prediction[\"kind\"]; readonly band?: unknown }): string => {\n switch (prediction.kind) {\n case \"removal\":\n case \"leaves\":\n case \"stalls\":\n case \"reconnects\":\n return \"s\";\n case \"restarts\":\n return prediction.band === null ? \"{replica}\" : \"s\";\n case \"ends\":\n return prediction.band === null ? \"{socket}\" : \"s\";\n default:\n return \"{request}\";\n }\n};\n\nconst sec = (ms: number): number => Math.round(ms) / 1000;\nconst inBand = (value: number, band: { readonly lo: number; readonly hi: number }): boolean =>\n value >= band.lo - NOISE / 1000 && value <= band.hi + NOISE / 1000;\nconst time = (value: number | null): Quantity | null => (value === null ? null : seconds(value));\n\n/**\n * This function tells if a failed request is the reuse of a port that a reset closed. The same\n * client had a reset on the same port, up to `life` before the request. The request ends with\n * `outcome`.\n */\nexport const reusesReset = (request: Request, requests: readonly Request[], reuse: ResetReuse): boolean => {\n if (request.o !== reuse.outcome || request.lp === undefined || request.lp === null) return false;\n const life = valueIn(reuse.life, \"ms\") + NOISE;\n return requests.some(\n (earlier) =>\n earlier.o === \"reset\" &&\n earlier.p === request.p &&\n earlier.lp === request.lp &&\n earlier.t + earlier.d <= request.t &&\n request.t - (earlier.t + earlier.d) <= life,\n );\n};\n\n/**\n * This function gives a reference event of a run, as a stamp, or null when the run does not have it.\n * The references `deletion` and `intake` are those of the target, or of the replica `pod`.\n */\nexport const referenceOf = (run: Pick<KindRun, \"start\" | \"acts\" | \"target\" | \"lines\">, from: Reference, pod: string | undefined = run.target?.pod): number | null => {\n const lines = run.lines as readonly Line[];\n if (from === \"fault\") return run.acts.fault;\n if (from === \"resume\") return run.acts.resume;\n if (from === \"heal\") return run.acts.heal;\n if (from === \"restart\") return restartOf(lines, run.start);\n if (pod === undefined) return null;\n if (from === \"deletion\") return deletionOf(lines, [pod], run.start);\n return intakeOf(lines, pod, run.start);\n};\n\n/**\n * This function gives the cycles of a run: each fault and its heal (`KindRun.acts.cycles`). A run\n * without cycles gives its one fault and heal, or none when it does not have both stamps.\n */\nexport const cyclesOf = (run: Pick<KindRun, \"acts\">): readonly Cycle[] => {\n if (run.acts.cycles !== undefined) return run.acts.cycles;\n const { fault, heal } = run.acts;\n return fault === null || heal === null ? [] : [{ fault, heal }];\n};\n\n/**\n * This function gives the source of the propagation of a cell. In a sidecar mesh, the client sidecar\n * picks the backend of each call from its endpoints (EDS), thus the source is `eds`. Each other cell\n * goes through the rules of kube-proxy (`rules`).\n */\nexport const propagationSource = (cell: Pick<KindCell, \"mesh\">): PropagationSource => (cell.mesh?.mode === \"sidecar\" ? \"eds\" : \"rules\");\n\n/**\n * This function gives the propagation of each node for the target of a run, or for the replica of\n * the address `ip`. It is the time from its deletion (or its crash) to the first poll of the rules\n * of the node without it. The change came between the poll before (`after`) and that poll (`by`).\n * The source `eds` gives the poll of the client sidecar of each node.\n */\nexport const propagationOf = (\n run: KindRun,\n from: number | null,\n ip: string | undefined = run.target?.ip,\n source: PropagationSource = \"rules\",\n): Record<string, Propagated | null> => {\n const out: Record<string, Propagated | null> = {};\n if (ip === undefined || from === null) return out;\n const nodes = [...new Set((run.lines as readonly Line[]).filter((line) => line.ev === source).map((line) => String(line[\"node\"])))].sort();\n for (const node of nodes) {\n const drop = dropOf(run.lines as readonly Line[], node, `${ip}:${PORT}`, from, source);\n out[node] = drop === null ? null : { after: drop.prev === null ? null : seconds(sec(Math.max(0, drop.prev - from))), by: seconds(sec(drop.t - from)) };\n }\n return out;\n};\n\n/**\n * This function gives the first LDS update of the sidecar of each server pod after the stamp `from`.\n * The update came between the poll before (`after`) and the poll that saw it (`by`), after `from`.\n * A poller gives a line at each change of its counters. Thus a line after `from` with a poll before\n * it is an update, when its count `mod` is above the count before `from`. The first line of a poller\n * has no poll before it (`prev` is null), and it is no update.\n */\nexport const updatesOf = (run: Pick<KindRun, \"lines\">, from: number | null): Record<string, Propagated | null> => {\n const out: Record<string, Propagated | null> = {};\n if (from === null) return out;\n const lines = (run.lines as readonly Line[]).filter((line) => line.ev === \"lds\");\n for (const pod of [...new Set(lines.map((line) => String(line[\"pod\"])))].sort()) {\n const own = lines.filter((line) => String(line[\"pod\"]) === pod);\n const before = own.filter((line) => line.t <= from).at(-1);\n const base = before === undefined ? null : Number(before[\"mod\"]);\n const update = own.find((line) => line.t > from && typeof line[\"prev\"] === \"number\" && (base === null || Number(line[\"mod\"]) > base));\n const prev = update === undefined ? null : (update[\"prev\"] as number);\n out[pod] = update === undefined ? null : { after: seconds(sec(Math.max(0, prev! - from))), by: seconds(sec(update.t - from)) };\n }\n return out;\n};\n\n/** This function tells if the judge reads the LDS updates of a cell: the trigger is a policy of Istio. */\nconst listens = (cell: Pick<KindCell, \"trigger\">): boolean => cell.trigger.kind === \"authorization-policy\";\n\n/**\n * This function gives each replica of a run that got a deletion after the start of the run, in the\n * sequence of the deletions. A rolling update deletes each old replica in turn.\n */\nexport const deletionsOf = (run: KindRun): Deleted[] =>\n run.replicas\n .flatMap((replica) => {\n const deletion = referenceOf(run, \"deletion\", replica.pod);\n return deletion === null ? [] : [{ pod: replica.pod, intake: referenceOf(run, \"intake\", replica.pod), deletion }];\n })\n .sort((a, b) => a.deletion - b.deletion);\n\n/** This function tells if a prediction is a window for each deleted replica. */\nconst eachOf = (prediction: Prediction): boolean => prediction.kind === \"window\" && prediction.each === true;\n\n/**\n * A span is one window of a run, as stamps. It gives the replica of its references (or none), and its\n * two references. It also gives its ends with δ, and the deletion of its replica (`origin`). Then it\n * gives the propagation of that deletion to each node, and when the rules of a node dropped its replica.\n */\ninterface Span {\n readonly pod: string | undefined;\n readonly start: number;\n readonly end: number | null;\n readonly lo: number;\n readonly hi: number;\n readonly origin: number | null;\n readonly propagation: RunFacts[\"propagation\"];\n readonly dropped: (node: string) => number | null;\n}\n\n/** This function gives the window of the failed requests of a prediction: a window, the window of `ends`, `leaves`, `removal` or `stays`, or null. */\nconst windowOf = (prediction: Prediction): WindowPrediction | null =>\n prediction.kind === \"window\"\n ? prediction\n : prediction.kind === \"ends\" || prediction.kind === \"leaves\" || prediction.kind === \"removal\"\n ? (prediction.window ?? null)\n : prediction.kind === \"stays\" && prediction.failures?.kind === \"window\"\n ? prediction.failures\n : null;\n\n/**\n * This function gives how long a run observes after the end reference of its last window, or null\n * when its prediction sets no such time. The judge closes a window `end.band.hi` + δ after its end\n * reference. A request that starts by then ends at most the timeout of the workload later: the\n * client cancels it then. A prediction with no window, or a window with no end, sets none.\n */\nexport const observationAfter = (cell: Pick<KindCell, \"prediction\" | \"workload\">): Quantity | null => {\n const window = windowOf(cell.prediction);\n if (window === null || window.end === null) return null;\n // the backlog term closes the window up to n × d later, with n the most sessions on the target,\n // or (n − 1) × d.hi + the slowest drain of one session (SYS-45)\n const backlog = window.backlog;\n const drained =\n backlog === undefined\n ? 0\n : backlog.slowest === undefined || backlog.most < 1\n ? backlog.most * valueIn(backlog.drain.hi, \"ms\")\n : (backlog.most - 1) * valueIn(backlog.drain.hi, \"ms\") + Math.max(valueIn(backlog.slowest, \"ms\"), valueIn(backlog.drain.hi, \"ms\"));\n return seconds(sec(valueIn(window.end.band.hi, \"ms\") + drained + valueIn(cell.workload.timeout, \"ms\") + NOISE));\n};\n\n/**\n * This function gives the earliest end of the observation of a run, as a stamp, or null when its\n * prediction sets none (`observationAfter`). It is that time after the latest end reference of a\n * window: of the target, or with `each`, of each replica that got a deletion. A run that ends before\n * it can miss its own failures. In a rolling update of gRPC, a call waits in the queue of its channel\n * for a stalled connect. It fails only at its timeout (kind run 40128267098). A reference that is not\n * in the lines yet does not count.\n *\n * The band of `ends` also sets an end: its reference, the end of the band and δ. A permitted window\n * sets an end too: its reference, the end of its band, the timeout of the workload and δ.\n */\nexport const observationEnd = (cell: KindCell, run: Pick<KindRun, \"start\" | \"acts\" | \"target\" | \"replicas\" | \"lines\">): number | null => {\n const ends: number[] = [];\n const prediction = cell.prediction;\n if (prediction.kind === \"ends\" && prediction.band !== null) {\n const at = referenceOf(run, prediction.from);\n if (at !== null) ends.push(at + valueIn(prediction.band.hi, \"ms\") + NOISE);\n }\n const after = observationAfter(cell);\n // the producers of a broker: the latest return that the bands permit, then each send that waited for it\n if (prediction.kind === \"reconnects\" && run.acts.fault !== null) ends.push(run.acts.fault + latestReturn(prediction) + valueIn(cell.workload.timeout, \"ms\") + NOISE);\n const window = windowOf(prediction);\n if (after !== null && window !== null && window.end !== null) {\n const from = window.end.from;\n const pods: ReadonlyArray<string | undefined> = window.each === true ? run.replicas.map((replica) => replica.pod) : [run.target?.pod];\n const references = pods.flatMap((pod) => {\n const at = referenceOf(run, from, pod);\n return at === null ? [] : [at];\n });\n if (references.length > 0) ends.push(Math.max(...references) + valueIn(after, \"ms\"));\n }\n // a permitted window closes its band end after its reference: each request that starts in it ends a timeout later\n const permits = window?.permits;\n if (permits !== undefined) {\n const at = referenceOf(run, permits.from, run.target?.pod);\n if (at !== null) ends.push(at + valueIn(permits.band.hi, \"ms\") + valueIn(cell.workload.timeout, \"ms\") + NOISE);\n // the least observation after the reference (SYS-53): a late failure then shows in the record\n if (at !== null && permits.watch !== undefined) ends.push(at + valueIn(permits.watch, \"ms\") + NOISE);\n }\n return ends.length === 0 ? null : Math.max(...ends);\n};\n\n/** This function gives the facts of a run that each table reads: its failures by outcome and node, and the times of its target. */\nexport const factsOf = (cell: KindCell, run: KindRun): RunFacts => {\n const lines = run.lines as readonly Line[];\n const failures = failuresOf(lines).filter((request) => request.t >= run.start && request.t <= run.end);\n const deletion = referenceOf(run, \"deletion\");\n const intake = referenceOf(run, \"intake\");\n const crash = cell.trigger.kind === \"crash\" ? run.acts.fault : null;\n const from = deletion ?? crash;\n const period = periodOf(lines, run.start, run.end);\n return {\n failures: failures.length,\n outcomes: outcomesOf(failures),\n byNode: Object.fromEntries([...byNode(failures)].map(([node, list]) => [node, list.length])),\n first: failures.length === 0 ? null : failures[0]!.t,\n last: failures.length === 0 ? null : failures.at(-1)!.t,\n deletion,\n intakeAfterDeletion: deletion === null || intake === null ? null : seconds(sec(intake - deletion)),\n sliceAfter: run.target === null || from === null ? null : time((() => {\n const at = sliceDropOf(lines, SERVER, run.target!.ip, from);\n return at === null ? null : sec(at - from);\n })()),\n propagation: propagationOf(run, from, undefined, propagationSource(cell)),\n ...(eachOf(cell.prediction) ? { deletions: deletionsOf(run) } : {}),\n ...(listens(cell) ? { updates: updatesOf(run, run.acts.fault), healUpdates: updatesOf(run, run.acts.heal) } : {}),\n ...(cell.workload.connections !== undefined && run.target !== null && run.acts.fault !== null\n ? { sessions: sessionsAt(lines, run.acts.fault, run.target.pod, cell.workload.connections) }\n : {}),\n ...(cell.trigger.kind === \"app-stall\" ? { stall: stallFactOf(run) } : {}),\n ...(period === null ? {} : { period: periodFact(period) }),\n };\n};\n\n/** This function gives a time in milliseconds in seconds, to the microsecond. A period of a client is approximately 10 ms, thus a whole millisecond is too coarse. */\nconst fine = (ms: number): Quantity => seconds(Math.round(ms * 1000) / 1e6);\n\n/** This function gives the period of the clients (`periodOf`) with each time in seconds. */\nconst periodFact =(period: Period): Period<Quantity> => ({\n median: fine(period.median),\n mean: fine(period.mean),\n low: fine(period.low),\n high: fine(period.high),\n intervals: period.intervals,\n byClient: Object.fromEntries(Object.entries(period.byClient).map(([client, ms]) => [client, fine(ms)])),\n});\n\n/**\n * This function gives the stall of the target in a run. It is the start of its line `stall` after the\n * fault, and the time that the app gives in its end line (`held`). A time that the run does not have is null.\n */\nconst stallFactOf = (run: KindRun): { readonly start: Quantity | null; readonly held: Quantity | null } => {\n const fault = run.acts.fault;\n const pod = run.target?.pod;\n const mine = (run.lines as readonly Line[]).filter((line) => line.ev === \"stall\" && (pod === undefined || line[\"p\"] === pod) && line.t >= run.start);\n const start = mine.find((line) => line[\"phase\"] === \"start\");\n const end = mine.find((line) => line[\"phase\"] === \"end\");\n const held = end === undefined ? undefined : Number(end[\"held\"]);\n return {\n start: start === undefined || fault === null ? null : seconds(sec(start.t - fault)),\n held: held === undefined || !Number.isFinite(held) ? null : seconds(sec(held)),\n };\n};\n\ntype Done = (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck;\n\n/**\n * This function judges a removal with flaps. In each cycle, the Service has no ready endpoint, and the\n * rules of each node have no backend, in the band after its fault. Each time comes before the fault of\n * the next cycle. At the fault of each cycle after the first, the Service has a ready endpoint and the\n * rules of each node a backend. After the last heal, the Service has a ready endpoint again. The main\n * value is the empty Service of the first cycle.\n */\nconst removalOfCycles = (cell: KindCell, run: KindRun, prediction: Extract<Prediction, { kind: \"removal\" }>, done: Done): RunCheck => {\n const lines = run.lines as readonly Line[];\n const cycles = cyclesOf(run);\n if (cycles.length === 0) return done(false, \"the run has no cycle of a fault and its heal\", null);\n const band = secondsOf(prediction.band);\n const nodes = [...new Set(lines.filter((line) => line.ev === \"rules\").map((line) => String(line[\"node\"])))].sort();\n const problems: string[] = [];\n const times: Array<{ readonly empty: Quantity | null; readonly ready: Quantity | null }> = [];\n let rules: Record<string, Quantity | null> = {};\n cycles.forEach((cycle, k) => {\n const n = k + 1;\n const next = cycles[k + 1]?.fault ?? run.end;\n // the slice and the rules give a line only at a change, thus the first cycle starts at rest\n if (k > 0) {\n if (sliceReadyAt(lines, SERVER, cycle.fault) !== true) problems.push(`the Service had no ready endpoint at the fault of the cycle ${n}`);\n const backends = backendsAt(lines, cycle.fault);\n for (const node of nodes) if ((backends.get(node) ?? []).length === 0) problems.push(`the rules of ${node} had no backend at the fault of the cycle ${n}`);\n }\n const empty = sliceEmptyOf(lines, SERVER, cycle.fault);\n const value = empty === null || empty > next ? null : sec(empty - cycle.fault);\n if (value === null) problems.push(`the Service kept a ready endpoint in the cycle ${n}`);\n else if (!inBand(value, band)) problems.push(`the EndpointSlice had no ready endpoint at ${value} s in the cycle ${n}`);\n const own: Record<string, Quantity | null> = {};\n for (const node of nodes) {\n const drop = emptyOf(lines, node, cycle.fault);\n const at = drop === null || drop.t > next ? null : sec(drop.t - cycle.fault);\n own[node] = at === null ? null : seconds(at);\n if (at === null) problems.push(`the rules of ${node} kept a backend in the cycle ${n}`);\n else if (!inBand(at, { lo: band.lo, hi: band.hi + 0.05 })) problems.push(`the rules of ${node} had no backend at ${at} s in the cycle ${n}`);\n }\n if (k === 0) rules = own;\n const ready = sliceReadyOf(lines, SERVER, cycle.heal);\n const back = ready === null || ready > next ? null : sec(ready - cycle.heal);\n if (k === cycles.length - 1 && back === null) problems.push(\"the Service had no ready endpoint after the last heal\");\n times.push({ empty: value === null ? null : seconds(value), ready: back === null ? null : seconds(back) });\n });\n const first = times[0]!.empty === null ? null : valueIn(times[0]!.empty, \"s\");\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const empties = times.map((each) => (each.empty === null ? \"none\" : `${valueIn(each.empty, \"s\")} s`)).join(\", \");\n const agrees = `the Service was empty in each of ${cycles.length} cycles, at ${empties} after its fault${inner === null ? \"\" : `; ${inner.why}`}`;\n const more: Partial<RunFacts> = { ...(inner === null ? {} : inner.facts), ...(first === null ? {} : { sliceEmpty: seconds(first) }), rules, cycles: times };\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), first, more);\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n};\n\n/**\n * This function counts the failed requests of a run with the backlog term (`requestBand`). The span\n * is from the start of the window to the end band without the term. The turn of a session comes\n * from the measured mean period of the clients. A run with no measured period cannot be counted.\n */\nconst countOf = (\n cell: KindCell,\n window: WindowPrediction,\n term: BacklogTerm,\n onTarget: number,\n period: Period<Quantity> | undefined,\n failed: number,\n): { readonly ok: boolean; readonly why: string } => {\n if (period === undefined) return { ok: false, why: \"the run has no measured period, thus the backlog term cannot count its failed requests\" };\n const span = seconds(Math.round((valueIn(window.end!.band.hi, \"s\") - valueIn(window.start.band.lo, \"s\")) * 1e6) / 1e6);\n const band = requestBand(term, span, period.mean, cell.workload.connections ?? 1, onTarget);\n const at = `the count [${band.lo}, ${band.hi}] of ${onTarget} session${onTarget === 1 ? \"\" : \"s\"} on the target at a mean period of ${Math.round(valueIn(period.mean, \"ms\") * 1000) / 1000} ms`;\n return failed >= band.lo && failed <= band.hi ? { ok: true, why: `in ${at}` } : { ok: false, why: `${failed} failed requests, outside ${at}` };\n};\n\n/** This function judges one run against the prediction of its cell. */\nexport const checkRun =(cell: KindCell, run: KindRun): RunCheck => {\n const lines = run.lines as readonly Line[];\n const facts = factsOf(cell, run);\n const failures = failuresOf(lines).filter((request) => request.t >= run.start && request.t <= run.end);\n const prediction = cell.prediction;\n const unit = unitOf(prediction);\n const done = (ok: boolean, why: string, value: number | null, more: Partial<RunFacts> = {}): RunCheck => ({\n ok,\n why,\n value: value === null ? null : { value, unit },\n facts: { ...facts, ...more },\n });\n switch (prediction.kind) {\n case \"none\": {\n const excluded = prediction.outcomes;\n const counted = excluded === undefined ? failures : failures.filter((request) => excluded.includes(request.o));\n const what = excluded === undefined ? \"requests failed\" : `requests ended ${excluded.join(\", \")}`;\n return done(counted.length === 0, counted.length === 0 ? `no ${excluded === undefined ? \"request failed\" : `request ended ${excluded.join(\", \")}`}` : `${counted.length} ${what}: ${JSON.stringify(facts.outcomes)}`, counted.length);\n }\n case \"window\": {\n const each = prediction.each === true;\n const opens = secondsOf(prediction.start.band);\n // the backlog term: n × d more at each end of the end band, with n the sessions on the target at the fault\n const backlog = prediction.backlog;\n const onTarget = facts.sessions?.onTarget;\n if (backlog !== undefined && (prediction.end === null || prediction.end.from !== prediction.start.from || onTarget === undefined))\n return done(\n false,\n onTarget === undefined ? \"the run has no sessions on the target at the fault, thus the backlog term has no n\" : \"a window with the backlog term has an end with the reference of its start\",\n null,\n );\n const closes = prediction.end === null ? null : secondsOf(backlog === undefined ? prediction.end.band : backlogEnd(prediction.end.band, backlog, onTarget!));\n // a request after a window that started before the rules of its node dropped the replica of that\n // window agrees with the law: only the calibrated band is short (D-EXTEND). A request after the drop is still late\n const droppedAfter = (origin: number | null, propagation: RunFacts[\"propagation\"]) => (node: string): number | null => {\n const propagated = propagation[node];\n return origin === null || propagated === undefined || propagated === null ? null : origin + valueIn(propagated.by, \"ms\");\n };\n // the window of the target, or with `each` the window of each replica that got a deletion\n const pods: ReadonlyArray<string | undefined> = each ? (facts.deletions ?? []).map((deleted) => deleted.pod) : [run.target?.pod];\n if (pods.length === 0) return done(false, \"no replica of the run got a deletion\", null);\n // with flaps, the window of each cycle: its own fault and heal\n const flaps = prediction.flaps === true;\n const cyclic = (from: Reference): from is \"fault\" | \"heal\" => from === \"fault\" || from === \"heal\";\n if (flaps && (each || !cyclic(prediction.start.from) || (prediction.end !== null && !cyclic(prediction.end.from))))\n return done(false, \"a window with flaps has no each, and its references are the fault and the heal\", null);\n const cycles = flaps ? cyclesOf(run) : [];\n if (flaps && cycles.length === 0) return done(false, \"the run has no cycle of a fault and its heal\", null);\n const sources: ReadonlyArray<{ readonly pod: string | undefined; readonly cycle: Cycle | undefined }> = flaps\n ? cycles.map((cycle) => ({ pod: run.target?.pod, cycle }))\n : pods.map((pod) => ({ pod, cycle: undefined }));\n const windows: Span[] = [];\n for (const { pod, cycle } of sources) {\n const at = (from: Reference): number | null => (cycle !== undefined && cyclic(from) ? cycle[from] : referenceOf(run, from, pod));\n const start = at(prediction.start.from);\n const end = prediction.end === null ? null : at(prediction.end.from);\n if (start === null || (prediction.end !== null && end === null))\n return done(false, `the run has no ${start === null ? prediction.start.from : prediction.end!.from} reference${each ? ` for ${pod}` : \"\"}`, null);\n const origin = each ? referenceOf(run, \"deletion\", pod) : (facts.deletion ?? (cell.trigger.kind === \"crash\" ? run.acts.fault : null));\n const ip = run.replicas.find((replica) => replica.pod === pod)?.ip;\n const propagation = each ? propagationOf(run, origin, ip, propagationSource(cell)) : facts.propagation;\n windows.push({\n pod,\n start,\n end,\n lo: start + opens.lo * 1000 - NOISE,\n hi: end === null ? Number.POSITIVE_INFINITY : end + closes!.hi * 1000 + NOISE,\n origin,\n propagation,\n dropped: droppedAfter(origin, propagation),\n });\n }\n // a node that dropped the replica of a window after the propagation of the prediction, or kept it\n // past that bound to the end of the run: the run agrees with the law, but the band is short (D-EXTEND)\n const bound = prediction.propagation === undefined ? null : secondsOf(prediction.propagation).hi * 1000 + NOISE;\n const lateOf = (origin: number, propagated: { readonly by: Quantity } | null) => {\n const by = propagated === null ? null : valueIn(propagated.by, \"ms\");\n return { by, late: bound !== null && (by === null ? run.end - origin > bound : by > bound) };\n };\n // for a policy, the propagation is the LDS update of each server sidecar after the fault and after the heal\n const listened = listens(cell);\n const updates = (facts.updates ?? {}) as Readonly<Record<string, Propagated | null>>;\n const healUpdates = (facts.healUpdates ?? {}) as Readonly<Record<string, Propagated | null>>;\n const slow =\n bound === null\n ? []\n : listened\n ? ([[run.acts.fault, updates, \"the policy\"], [run.acts.heal, healUpdates, \"the delete of the policy\"]] as const).flatMap(([origin, by, what]) =>\n origin === null\n ? []\n : Object.entries(by).flatMap(([pod, propagated]) => {\n const late = lateOf(origin, propagated);\n return late.late ? [{ pod: what, node: pod, by: late.by }] : [];\n }),\n )\n : windows.flatMap(({ pod, origin, propagation }) =>\n origin === null\n ? []\n : Object.entries(propagation).flatMap(([node, propagated]) => {\n const late = lateOf(origin, propagated);\n return late.late ? [{ pod, node, by: late.by }] : [];\n }),\n );\n // the last LDS update after the heal: a call to its replica can fail until the next call to it after the update\n const lastHeal =\n !listened || run.acts.heal === null\n ? null\n : Object.values(healUpdates).reduce<number | null>((max, propagated) => (propagated === null ? max : Math.max(max ?? 0, valueIn(propagated.by, \"ms\"))), null);\n // a failure in the permitted window, outside each window and with a permitted outcome, does not count (SYS-51)\n const permits = prediction.permits;\n const permitAt = permits === undefined ? null : referenceOf(run, permits.from, run.target?.pod);\n if (permits !== undefined && permitAt === null) return done(false, `the run has no ${permits.from} reference for the permitted window`, null);\n const permitted = (request: Request): boolean =>\n permits !== undefined &&\n permitAt !== null &&\n permits.outcomes.includes(request.o) &&\n request.t >= permitAt + valueIn(permits.band.lo, \"ms\") - NOISE &&\n request.t <= permitAt + valueIn(permits.band.hi, \"ms\") + NOISE &&\n windows.every((window) => request.t < window.lo || request.t > window.hi);\n const allowedLate = failures.filter(permitted);\n const counting = allowedLate.length === 0 ? failures : failures.filter((request) => !allowedLate.includes(request));\n const relevant: Request[] = prediction.nodes === \"paused\" ? counting.filter((request) => request.n === run.paused) : counting;\n const others = prediction.nodes === \"paused\" ? counting.filter((request) => request.n !== run.paused) : [];\n const reuse = prediction.afterReset;\n const late = relevant.filter((request) => windows.every((window) => request.t < window.lo || request.t > window.hi));\n // a request outside the window that reuses the port of a reset is the CLOSE entry of that reset\n const reused = reuse === undefined ? [] : late.filter((request) => reusesReset(request, failures, reuse));\n const tailOf = (request: Request): Span | undefined =>\n reused.includes(request)\n ? undefined\n : windows.find((window) => {\n const drop = request.t > window.hi ? window.dropped(request.n) : null;\n return drop !== null && request.t <= drop + NOISE;\n });\n // a denial after the window, before the last LDS update after the heal and the next call to its replica\n const healTail = (request: Request): boolean =>\n lastHeal !== null && request.t > windows[0]!.hi && request.t <= run.acts.heal! + lastHeal + SLACK + NOISE;\n const tail = late.filter((request) => tailOf(request) !== undefined || healTail(request));\n const outside = late.filter((request) => !reused.includes(request) && !tail.includes(request));\n // a window that names its outcomes allows no other failure in it\n const allowed = prediction.outcomes;\n const wrong = allowed === undefined ? [] : relevant.filter((request) => !late.includes(request) && !allowed.includes(request.o));\n const bounds = (window: Span): string => `[${sec(window.lo - window.start)}, ${sec(window.hi - window.start)}] s`;\n const problems: string[] = [];\n if (outside.length > 0)\n problems.push(\n each\n ? `${outside.length} failed requests outside the window of each deleted replica: ${windows.map((window) => `${window.pod} ${bounds(window)}`).join(\", \")} after its ${prediction.start.from}`\n : flaps\n ? `${outside.length} failed requests outside the window of each cycle: ${windows.map((window, k) => `${k + 1} ${bounds(window)}`).join(\", \")} after its ${prediction.start.from}`\n : `${outside.length} failed requests outside ${bounds(windows[0]!)} after ${prediction.start.from}`,\n );\n if (others.length > 0) problems.push(`${others.length} failed requests on nodes whose kube-proxy did not pause`);\n if (wrong.length > 0) problems.push(`${wrong.length} failed requests in the window ended ${JSON.stringify(outcomesOf(wrong))}, not ${allowed!.join(\", \")}`);\n if (prediction.certain && relevant.length === 0) problems.push(\"no request failed in a window that the law opens\");\n // the backlog term counts the failed requests of the n sessions from the measured period of the clients\n const counted = backlog === undefined ? null : countOf(cell, prediction, backlog, onTarget!, facts.period, relevant.length);\n if (counted !== null && !counted.ok) problems.push(counted.why);\n // the window that ends last: the last failed request comes near its end\n const final = windows.reduce((a, b) => ((b.end ?? Number.NEGATIVE_INFINITY) > (a.end ?? Number.NEGATIVE_INFINITY) ? b : a));\n // with flaps, each cycle has a failed request, and its last one comes near the end of its window\n if (flaps && prediction.certain && relevant.length > 0) {\n windows.forEach((window, k) => {\n const own = relevant.filter((request) => request.t >= window.lo && request.t <= window.hi);\n if (own.length === 0) problems.push(`no request failed in the window of the cycle ${k + 1}`);\n else if (window.end !== null) {\n const earliest = window.end + closes!.lo * 1000 - NOISE - SLACK;\n if (own.at(-1)!.t < earliest) problems.push(`the last failed request of the cycle ${k + 1} started ${sec(earliest - own.at(-1)!.t)} s before its window can end`);\n }\n });\n }\n if (!flaps && prediction.certain && final.end !== null && relevant.length > 0) {\n const last = relevant.at(-1)!.t;\n const earliest = final.end + closes!.lo * 1000 - NOISE - SLACK;\n if (last < earliest) problems.push(`the last failed request started ${sec(earliest - last)} s before the window can end`);\n }\n const inside = relevant.filter((request) => !late.includes(request));\n const span = inside.length === 0 ? 0 : sec(inside.at(-1)!.t - inside[0]!.t);\n const where = each ? `the windows of ${windows.length} deleted replicas` : flaps ? `the windows of ${windows.length} cycles` : \"the window\";\n const agrees =\n (reused.length === 0\n ? `${relevant.length} failed requests, all in ${where} (span ${span} s)`\n : `${inside.length} failed requests in ${where} (span ${span} s), and ${reused.length} on a port that a reset closed`) +\n (counted === null ? \"\" : `, ${counted.why}`) +\n // the law permits these failures, thus they do not make the cell extend\n (allowedLate.length === 0 ? \"\" : `; ${allowedLate.length} failed requests in the permitted window after the ${permits!.from}: ${JSON.stringify(outcomesOf(allowedLate))}`);\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), relevant.length);\n if (problems.length > 0) return checked;\n const notes: string[] = [];\n if (tail.length > 0) {\n const last = tail.at(-1)!;\n const after = tailOf(last);\n notes.push(\n after === undefined\n ? `${tail.length} failed requests after the window, the last ${sec(last.t - windows[0]!.hi + NOISE)} s after it, before the last LDS update after the heal and the next call to its replica`\n : each\n ? `${tail.length} failed requests after a window, the last ${sec(last.t - after.hi + NOISE)} s after the window of ${after.pod} on ${last.n}, before the rules of ${last.n} dropped ${after.pod}`\n : `${tail.length} failed requests after the window, the last ${sec(last.t - after.hi + NOISE)} s after it on ${last.n}, before the rules of ${last.n} dropped the target`,\n );\n }\n if (slow.length > 0) {\n // a node that kept its replica to the end of the run is the latest\n const latest = slow.find((late) => late.by === null) ?? slow.reduce((a, b) => (b.by! > a.by! ? b : a));\n const bandHi = secondsOf(prediction.propagation!).hi;\n if (listened) {\n const update = latest.by === null ? `had no LDS update after ${latest.pod}` : `had its LDS update ${sec(latest.by)} s after ${latest.pod}`;\n notes.push(`${slow.length} LDS updates after the propagation of ${bandHi} s at the most, the latest: the sidecar of ${latest.node} ${update}`);\n } else {\n const what = each ? latest.pod : \"the target\";\n const drop = latest.by === null ? `kept ${what} to the end of the run` : `dropped ${what} ${sec(latest.by)} s after its deletion`;\n notes.push(`${slow.length} drops after the propagation of ${bandHi} s at the most, the latest: the rules of ${latest.node} ${drop}`);\n }\n }\n return notes.length === 0 ? checked : { ...checked, tail: notes.join(\"; \") };\n }\n case \"removal\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n if (prediction.flaps === true) return removalOfCycles(cell, run, prediction, done);\n const empty = sliceEmptyOf(lines, SERVER, fault);\n if (empty === null) return done(false, \"the Service kept a ready endpoint\", null);\n const value = sec(empty - fault);\n const band = secondsOf(prediction.band);\n const problems: string[] = [];\n if (!inBand(value, band)) problems.push(`the EndpointSlice had no ready endpoint at ${value} s`);\n const nodes = [...new Set(lines.filter((line) => line.ev === \"rules\").map((line) => String(line[\"node\"])))].sort();\n const rules: Record<string, Quantity | null> = {};\n for (const node of nodes) {\n const drop = emptyOf(lines, node, fault);\n rules[node] = drop === null ? null : seconds(sec(drop.t - fault));\n if (drop === null) problems.push(`the rules of ${node} kept a backend`);\n else if (!inBand(sec(drop.t - fault), { lo: band.lo, hi: band.hi + 0.05 }))\n problems.push(`the rules of ${node} had no backend at ${sec(drop.t - fault)} s`);\n }\n // with a window, the failed requests of the run must also agree with it, as with `leaves`\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const agrees = inner === null ? `the Service was empty at ${value} s` : `the Service was empty at ${value} s; ${inner.why}`;\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), value, { ...(inner === null ? {} : inner.facts), sliceEmpty: seconds(value), rules });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"leaves\": {\n const fault = run.acts.fault;\n if (fault === null || run.target === null) return done(false, \"the run has no fault stamp or no target\", null);\n const at = sliceDropOf(lines, SERVER, run.target.ip, fault);\n if (at === null) return done(false, `${run.target.pod} stayed ready in the EndpointSlice`, null);\n const value = sec(at - fault);\n const band = secondsOf(prediction.band);\n const problems: string[] = [];\n if (!inBand(value, band)) problems.push(`${run.target.pod} left the EndpointSlice at ${value} s`);\n const propagation = propagationOf(run, fault, undefined, propagationSource(cell));\n // the kube-proxy of a lost zone is frozen with its node, thus only the rules of the other nodes count\n const lost = cell.trigger.kind === \"zone-loss\" ? run.paused : null;\n for (const [node, drop] of Object.entries(propagation)) {\n if (node === lost) continue;\n const by = drop === null ? null : valueIn(drop.by, \"s\");\n if (by === null) problems.push(`the rules of ${node} kept ${run.target.pod}`);\n else if (!inBand(by, { lo: band.lo, hi: band.hi + 0.05 })) problems.push(`the rules of ${node} dropped it at ${by} s`);\n }\n // with a window, the failed requests of the run must also agree with it, as with `ends`\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const left = inner === null ? `${run.target.pod} left at ${value} s` : `${run.target.pod} left at ${value} s; ${inner.why}`;\n const checked = done(problems.length === 0, problems.length === 0 ? left : problems.join(\"; \"), value, { ...(inner === null ? {} : inner.facts), left: seconds(value), propagation });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"restarts\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n const until = run.acts.heal ?? run.end;\n const pods = run.replicas.map((replica) => replica.pod);\n const signals = signalsOf(lines, pods, fault);\n const inside = [...signals].filter(([, at]) => at <= until);\n if (prediction.band === null)\n return done(inside.length === 0, inside.length === 0 ? \"no replica received SIGTERM\" : `${inside.length} replicas received SIGTERM`, inside.length);\n const band = secondsOf(prediction.band);\n const times = pods.map((pod) => {\n const at = signals.get(pod);\n return at === undefined ? null : sec(at - fault);\n });\n const missing = times.filter((each) => each === null).length;\n const off = times.filter((each): each is number => each !== null && !inBand(each, band));\n const known = times.filter((each): each is number => each !== null).sort((a, b) => a - b);\n const ok = missing === 0 && off.length === 0;\n return done(ok, ok ? `each replica received SIGTERM, at ${known.join(\", \")} s` : `${missing} replicas without SIGTERM, ${off.length} outside the band (${known.join(\", \")} s)`, known.length === 0 ? null : middle(known), { signals: times.map(time) });\n }\n case \"stays\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no fault stamp\", null);\n const until = run.end;\n const dropped = run.replicas.filter((replica) => {\n const at = sliceDropOf(lines, SERVER, replica.ip, fault);\n return at !== null && at <= until;\n });\n const refused = failures.filter((request) => request.o === \"refused\" && request.t >= fault);\n const problems: string[] = [];\n if (dropped.length > 0) problems.push(`${dropped.length} replicas left the EndpointSlice`);\n if (refused.length > 0) problems.push(`${refused.length} requests were refused`);\n // the failed requests of a slow dependency: a window, or none\n const inner = prediction.failures === undefined ? null : checkRun({ ...cell, prediction: prediction.failures }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const agrees = `the replicas stayed ready, ${failures.length} requests failed by their dependency${inner === null ? \"\" : `; ${inner.why}`}`;\n const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join(\"; \"), failures.length, inner === null ? {} : inner.facts);\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n }\n case \"stalls\": {\n const fault = run.acts.fault;\n const heal = run.acts.heal;\n if (fault === null || heal === null) return done(false, \"the run has no fault or heal stamp\", null);\n const old = new Set(run.replicas.map((replica) => replica.pod));\n // only the replicas of the service: the pod of Redis is not a part of the rollout\n const servers = podsOf(lines).filter((pod) => pod.labels[\"app\"] === SERVER);\n const pods = servers.filter((pod) => pod.t >= fault && pod.t <= heal);\n const deleted = pods.filter((pod) => old.has(pod.name) && pod.del);\n const newReady = pods.filter((pod) => !old.has(pod.name) && pod.ready);\n const after = servers.filter((pod) => pod.t > heal);\n const firstReady = after.find((pod) => !old.has(pod.name) && pod.ready);\n const finished = firstReady !== undefined && after.some((pod) => old.has(pod.name) && pod.type === \"DELETED\");\n const problems: string[] = [];\n if (deleted.length > 0) problems.push(`${new Set(deleted.map((pod) => pod.name)).size} old pods were deleted while Redis was down`);\n if (newReady.length > 0) problems.push(\"a new pod became ready while Redis was down\");\n if (!finished) problems.push(\"the rollout did not continue after Redis came back\");\n if (problems.length === 0)\n return done(true, `the rollout waited for Redis, and its first new pod was ready ${sec(firstReady!.t - heal)} s after Redis came back`, sec(firstReady!.t - heal));\n return done(false, problems.join(\"; \"), null);\n }\n case \"ends\":\n return checkEnds(cell, run, prediction, done);\n case \"reconnects\": {\n const fault = run.acts.fault;\n if (fault === null) return done(false, \"the run has no stamp of the fault\", null);\n if (run.broker === undefined) return done(false, \"the run has no broker that owned the topic at the fault\", null);\n const judged = judgeReconnects(prediction, { fault, broker: run.broker, lines }, { timeout: valueIn(cell.workload.timeout, \"ms\"), every: valueIn(cell.workload.every, \"ms\") }, NOISE);\n const time = (value: number | null): Quantity | null => (value === null ? null : { value: sec(value), unit: \"s\" });\n const reconnects: ReconnectsFacts = {\n flip: time(judged.flip),\n gap: time(judged.gap),\n returns: judged.returns.map((each) => ({ pod: each.pod, disconnect: time(each.disconnect), back: time(each.back), setup: time(each.setup), tries: each.tries })),\n failures: judged.failures,\n };\n // the requests of the control go to the service of the cell, and the fault of the broker does not touch it\n if (failures.length > 0) return done(false, `${failures.length} requests of the control failed: ${JSON.stringify(facts.outcomes)}`, null, { reconnects });\n return done(judged.ok, judged.why, judged.value === null ? null : sec(judged.value), { reconnects });\n }\n case \"measured\":\n return done(true, \"measured\", facts.failures);\n }\n};\n\n/**\n * This function judges a run against a prediction `ends`. Each client with an answer before the\n * reference is a client of the run. Its socket is the port of that answer (`lp`).\n * - With a band, the first close of a socket of each client after the reference must be in the band\n * ± δ. It must be the close of that socket. The main value is the middle of these times.\n * - With no band, no socket of a client can close after the reference. The first request of each client\n * after the heal must be `ok` on that socket. The main value is the count of the closes.\n *\n * With a window, the failed requests of the run must also agree with that window (`checkRun`). A\n * prediction of the tunnels (`of: \"tunnel\"`) has its own judge (`checkTunnels`).\n */\nconst checkEnds = (\n cell: KindCell,\n run: KindRun,\n prediction: Extract<Prediction, { readonly kind: \"ends\" }>,\n done: (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck,\n): RunCheck => {\n const from = referenceOf(run, prediction.from);\n if (from === null) return done(false, `the run has no ${prediction.from} reference`, null);\n if (prediction.of === \"tunnel\") return checkTunnels(run, prediction, from, done);\n const lines = run.lines as readonly Line[];\n const calls = requestsOf(lines)\n .filter((request) => request.t >= run.start && request.t <= run.end)\n .sort((a, b) => a.t - b.t);\n // each client of the run, with its last answer before the reference\n const last = new Map<string, Request>();\n for (const request of calls) if (request.t < from && request.o === \"ok\") last.set(request.p, request);\n if (last.size === 0) return done(false, `no client had an answer before the ${prediction.from}`, null);\n const clients = [...last.keys()].sort();\n const shut = socketsOf(lines).filter((line) => line.what === \"close\" && line.t >= from && line.t <= run.end);\n const closes: Record<string, Quantity | null> = {};\n const times: number[] = [];\n const problems: string[] = [];\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n closes[client] = close === undefined ? null : seconds(sec(close.t - from));\n if (close !== undefined) times.push(sec(close.t - from));\n }\n let agrees: string;\n let value: number | null;\n if (prediction.band !== null) {\n const band = secondsOf(prediction.band);\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n const port = last.get(client)!.lp ?? null;\n if (close === undefined) problems.push(`the socket of ${client} did not end`);\n else if (port !== null && close.lp !== null && close.lp !== port) problems.push(`the first socket of ${client} to end had the port ${close.lp}, not the port ${port} of its last answer`);\n else if (!inBand(sec(close.t - from), band)) problems.push(`the socket of ${client} ended at ${sec(close.t - from)} s`);\n }\n const sorted = [...times].sort((a, b) => a - b);\n value = sorted.length === 0 ? null : middle(sorted);\n agrees = `the socket of each of ${clients.length} clients ended, at ${sorted.join(\", \")} s`;\n } else {\n for (const client of clients) {\n const close = shut.find((line) => line.p === client);\n if (close !== undefined) problems.push(`the socket of ${client} ended ${sec(close.t - from)} s after the ${prediction.from}`);\n }\n // the first call after the heal goes on the socket of the last answer before the reference\n const resumed = run.acts.heal ?? from;\n for (const client of clients) {\n const port = last.get(client)!.lp ?? null;\n const next = calls.find((request) => request.p === client && request.t >= resumed);\n if (next === undefined) problems.push(`${client} sent no call after the heal`);\n else if (next.o !== \"ok\") problems.push(`the first call of ${client} after the heal ended ${next.o}`);\n else if ((next.lp ?? null) !== port) problems.push(`the first call of ${client} after the heal went on the port ${next.lp ?? \"none\"}, not ${port ?? \"none\"}`);\n }\n value = times.length;\n agrees = `no socket of ${clients.length} clients ended, and the first call of each one after the heal went on its socket`;\n }\n const inner = prediction.window === undefined ? null : checkRun({ ...cell, prediction: prediction.window }, run);\n if (inner !== null && !inner.ok) problems.push(inner.why);\n const why = problems.length > 0 ? problems.join(\"; \") : inner === null ? agrees : `${agrees}; ${inner.why}`;\n const checked = done(problems.length === 0, why, value, { ...(inner === null ? {} : inner.facts), closes });\n return inner?.tail === undefined ? checked : { ...checked, tail: inner.tail };\n};\n\n/**\n * This function judges a run against a prediction `ends` of the tunnels (`of: \"tunnel\"`). Each client\n * with an answer before the reference is a client of the run. Its tunnel is the HBONE connection of\n * its ztunnel. The tunnel goes from the address of its pod to the HBONE port of the replica of its\n * last answer before the heal. The address of the pod is the local address of a socket of the client\n * in the run (`la`).\n * - The first change of the tunnel out of ESTABLISHED after the reference must be in the band ± δ.\n * It must be to FIN_WAIT1: the side of the client closes the tunnel, and the peer does not close first.\n * - With `answer`, a change to CLOSE_WAIT in that band ± δ also agrees. The peer closed first, but as\n * an answer to the close of the client.\n * - The first request of each client after the heal must succeed. The main value is the middle of the ends.\n */\nconst checkTunnels = (\n run: KindRun,\n prediction: Extract<Prediction, { readonly kind: \"ends\" }>,\n from: number,\n done: (ok: boolean, why: string, value: number | null, more?: Partial<RunFacts>) => RunCheck,\n): RunCheck => {\n if (prediction.band === null) return done(false, \"a prediction of the tunnels needs a band\", null);\n const heal = run.acts.heal;\n if (heal === null) return done(false, \"the run has no heal\", null);\n const lines = run.lines as readonly Line[];\n const calls = requestsOf(lines)\n .filter((request) => request.t >= run.start && request.t <= run.end)\n .sort((a, b) => a.t - b.t);\n const clients = [...new Set(calls.filter((request) => request.t < from && request.o === \"ok\").map((request) => request.p))].sort();\n if (clients.length === 0) return done(false, `no client had an answer before the ${prediction.from}`, null);\n const band = secondsOf(prediction.band);\n const reply = prediction.answer === undefined ? null : secondsOf(prediction.answer);\n const tunnels = tunnelsOf(lines).filter((line) => line.t >= from && line.t <= run.end);\n const sockets = socketsOf(lines);\n const closes: Record<string, Quantity | null> = {};\n const times: number[] = [];\n const problems: string[] = [];\n for (const client of clients) {\n closes[client] = null;\n const answer = calls.filter((request) => request.p === client && request.t < heal && request.o === \"ok\").at(-1);\n const replica = run.replicas.find((each) => answer !== undefined && each.pod === answer.b);\n const address = sockets.find((line) => line.p === client && typeof line.la === \"string\" && line.la !== \"\")?.la;\n if (replica === undefined) {\n problems.push(`no replica of the run answered ${client} before the heal`);\n continue;\n }\n if (address === undefined || address === null) {\n problems.push(`no socket of ${client} gave the address of its pod`);\n continue;\n }\n const end = tunnels.find((line) => line.src.startsWith(`${address}:`) && line.dst === `${replica.ip}:${HBONE_PORT}` && line.old === TCP_STATE.established);\n if (end === undefined) {\n problems.push(`the tunnel of ${client} to ${replica.pod} did not end`);\n continue;\n }\n const at = sec(end.t - from);\n closes[client] = seconds(at);\n times.push(at);\n if (end.new === TCP_STATE.closeWait && reply !== null) {\n if (!inBand(at, reply)) problems.push(`the peer closed the tunnel of ${client} at ${at} s, outside the band of its answer`);\n } else if (end.new !== TCP_STATE.finWait1) problems.push(`the tunnel of ${client} went from ESTABLISHED to the state ${end.new}, not FIN_WAIT1: the peer closed first`);\n else if (!inBand(at, band)) problems.push(`the tunnel of ${client} ended at ${at} s`);\n const next = calls.find((request) => request.p === client && request.t >= heal);\n if (next === undefined) problems.push(`${client} sent no call after the heal`);\n else if (next.o !== \"ok\") problems.push(`the first call of ${client} after the heal ended ${next.o}`);\n }\n const sorted = [...times].sort((a, b) => a - b);\n const why =\n problems.length > 0\n ? problems.join(\"; \")\n : `the side of the client ended the tunnel of each of ${clients.length} clients, at ${sorted.join(\", \")} s, and the first call of each one after the heal succeeded`;\n return done(problems.length === 0, why, sorted.length === 0 ? null : middle(sorted), { closes });\n};\n\n/** This function judges a cell on its runs: each counted run must agree, and a median in a band must be equivalent to it. */\nexport const judgeKind = (cell: KindCell, runs: readonly KindRun[]): KindVerdict => {\n const counted = runs.filter((run) => !run.warmup && run.void === null);\n const voided = runs.filter((run) => !run.warmup && run.void !== null).length;\n const checks = counted.map((run) => checkRun(cell, run));\n // the main values of one cell share the unit of its prediction\n const values = checks.flatMap((check) => (check.value === null ? [] : [check.value.value])).sort((a, b) => a - b);\n const median: Quantity | null = values.length === 0 ? null : { value: middle(values), unit: unitOf(cell.prediction) };\n const failed = checks.filter((check) => !check.ok).length;\n if (counted.length === 0) return { decision: \"void\", counted: 0, voided, failed: 0, median: null, why: \"no counted run\", checks };\n if (cell.calibrates) return { decision: \"calibration\", counted: counted.length, voided, failed, median, why: \"a calibration of the propagation\", checks };\n if (cell.prediction.kind === \"measured\") return { decision: \"measured\", counted: counted.length, voided, failed: 0, median, why: cell.prediction.why, checks };\n const prediction = cell.prediction;\n const band = prediction.kind === \"removal\" || prediction.kind === \"leaves\" || prediction.kind === \"restarts\" || prediction.kind === \"ends\" ? prediction.band : null;\n if (failed > 0) {\n const first = checks.find((check) => !check.ok)!;\n return { decision: \"fails\", counted: counted.length, voided, failed, median, why: `${failed} of ${counted.length} runs disagree, the first: ${first.why}`, checks };\n }\n // a run past its calibrated band agrees with the law, but the band is short: the cell needs a longer one\n const tails = checks.filter((check) => check.tail !== undefined);\n if (tails.length > 0)\n return { decision: \"extend\", counted: counted.length, voided, failed, median, why: `${tails.length} of ${counted.length} runs are past the calibrated band, the first: ${tails[0]!.tail}`, checks };\n if (band !== null && values.length > 0) {\n const ends = secondsOf(band);\n const [from, to] = medianInterval(values);\n const wide = { lo: ends.lo * (1 - RELATIVE), hi: ends.hi * (1 + RELATIVE) };\n if (to < wide.lo || from > wide.hi)\n return { decision: \"fails\", counted: counted.length, voided, failed, median, why: `the median interval [${from}, ${to}] s is outside the band`, checks };\n if (from < wide.lo || to > wide.hi)\n return { decision: \"extend\", counted: counted.length, voided, failed, median, why: `the median interval [${from}, ${to}] s crosses the edge of the band`, checks };\n }\n return { decision: \"holds\", counted: counted.length, voided, failed, median, why: `${counted.length} of ${counted.length} runs agree`, checks };\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { seconds } from \"./bands.ts\";\nimport type { Band, KindCell, KindRun, Prediction, Trigger, WindowPrediction } from \"./cell.ts\";\nimport type { KindScenario } from \"./scenario.ts\";\nimport type { KindVerdict, Propagated, RunCheck, RunFacts } from \"./verdict.ts\";\nimport { judgeKind, unitOf } from \"./verdict.ts\";\nimport type { Substrate } from \"@mark1russell7/harness\";\n\n/**\n * This module is the raw record of a kind cell: its formats, and the upgrade from the format `/1`\n * to the format `/2`. The lab writes `/2`, and it does not write `/1` again. A reader reads a record\n * of `/1` through `upgrade`, and the meaning of each value stays the same.\n */\n\n/** This format is the format that the lab writes. Each amount in it is a quantity. */\nexport const FORMAT = \"systems.kind-cell-record/2\";\n/** This format is the first format. Its bands, its medians and its times are numbers. */\nexport const FORMAT_V1 = \"systems.kind-cell-record/1\";\n\n/**\n * A load sample is what the VM did in 4 s before a run: when (a stamp of the wall clock in\n * milliseconds), its idle share, and its busiest processes. A sample of the gate has `needed`, the\n * idle share of the gate at that time. A baseline sample has no `needed`.\n */\nexport interface LoadSample {\n readonly t: number;\n readonly idle: number;\n readonly top: readonly string[];\n readonly foreign: readonly string[];\n readonly needed?: number | undefined;\n}\n\n/** A cluster manifest is what a run records about its cluster: the versions, the images, the nodes and the mode as read back. */\nexport interface ClusterManifest {\n readonly kind: string;\n readonly nodeImage: string;\n readonly server: string;\n readonly mode: string;\n readonly docker: string;\n readonly nodes: ReadonlyArray<{\n readonly name: string;\n readonly kubelet: string;\n readonly kernel: string;\n readonly runtime: string;\n readonly os: string;\n }>;\n}\n\n/** An environment manifest is one cluster of a cell: its scenario, what the cluster was, and the images of the lab. */\nexport interface EnvironmentManifest {\n readonly env: number;\n readonly scenario: KindScenario;\n readonly cluster: ClusterManifest;\n readonly images: Readonly<Record<string, string>>;\n /** This block tells the layer, the cloud and the kernel of the record. A record from before it reads through `substrateOf`. */\n readonly substrate?: Substrate;\n}\n\n/**\n * A kind cell result is a cell, its runs over its environments, the manifest of each environment,\n * and its verdict. The parameter `A` is the form of an amount.\n */\nexport interface KindCellResult<A = Quantity> {\n readonly cell: KindCell<A>;\n readonly runs: readonly KindRun[];\n readonly manifests: readonly EnvironmentManifest[];\n readonly loads: readonly LoadSample[];\n readonly verdict: KindVerdict<A>;\n /** This text is the time of the verdict, in ISO 8601. */\n readonly at: string;\n}\n\n/** A kind cell record is the raw record of a cell in the format `/2`: a result with its format. */\nexport interface KindCellRecord extends KindCellResult {\n readonly format: typeof FORMAT;\n}\n\n/** A kind cell record of the format `/1` gives each band, median, main value and time of a fact as a number. */\nexport interface KindCellRecordV1 extends KindCellResult<number> {\n readonly format: typeof FORMAT_V1;\n}\n\n/** These are the parts of the format `/1`, with numbers for amounts. */\nexport type BandV1 = Band<number>;\nexport type PredictionV1 = Prediction<number>;\nexport type TriggerV1 = Trigger<number>;\nexport type KindCellV1 = KindCell<number>;\nexport type KindVerdictV1 = KindVerdict<number>;\nexport type RunCheckV1 = RunCheck<number>;\nexport type RunFactsV1 = RunFacts<number>;\n\nconst time = (value: number | null): Quantity | null => (value === null ? null : seconds(value));\nconst band = (old: BandV1): Band => ({ lo: seconds(old.lo), hi: seconds(old.hi) });\n/** The format `/1` gives each part of `cpu.max` in microseconds. */\nconst microseconds = (value: number): Quantity => ({ value, unit: \"us\" });\n\nconst upgradeTrigger = (trigger: TriggerV1): Trigger => {\n const { cpuMax, ...rest } = trigger;\n return cpuMax === undefined ? rest : { ...rest, cpuMax: { quota: microseconds(cpuMax.quota), period: microseconds(cpuMax.period) } };\n};\n\n/** The format `/1` has no backlog term, but its type does. Each time of the term is in seconds. */\nconst upgradeBacklog = (backlog: NonNullable<WindowPrediction<number>[\"backlog\"]>): NonNullable<WindowPrediction[\"backlog\"]> => {\n const { slowest, ...rest } = backlog;\n return { ...rest, drain: band(backlog.drain), ...(slowest === undefined ? {} : { slowest: seconds(slowest) }) };\n};\n\nconst upgradePermits = (permits: NonNullable<WindowPrediction<number>[\"permits\"]>): NonNullable<WindowPrediction[\"permits\"]> => {\n const { watch, ...rest } = permits;\n return { ...rest, band: band(permits.band), ...(watch === undefined ? {} : { watch: seconds(watch) }) };\n};\n\nconst upgradeWindow = (window: WindowPrediction<number>): WindowPrediction => {\n const { afterReset, propagation, backlog, permits, ...rest } = window;\n return {\n ...rest,\n start: { from: window.start.from, band: band(window.start.band) },\n end: window.end === null ? null : { from: window.end.from, band: band(window.end.band) },\n ...(afterReset === undefined ? {} : { afterReset: { life: seconds(afterReset.life), outcome: afterReset.outcome } }),\n ...(propagation === undefined ? {} : { propagation: band(propagation) }),\n ...(backlog === undefined ? {} : { backlog: upgradeBacklog(backlog) }),\n // the format /1 has no permitted window, but its type does\n ...(permits === undefined ? {} : { permits: upgradePermits(permits) }),\n };\n};\n\nconst upgradePrediction = (prediction: PredictionV1): Prediction => {\n switch (prediction.kind) {\n case \"window\":\n return upgradeWindow(prediction);\n // the format /1 has no prediction `ends`, but its type does\n case \"ends\": {\n const { window, answer, ...rest } = prediction;\n return {\n ...rest,\n band: prediction.band === null ? null : band(prediction.band),\n ...(window === undefined ? {} : { window: upgradeWindow(window) }),\n ...(answer === undefined ? {} : { answer: band(answer) }),\n };\n }\n // the format /1 has no window on `removal` and `leaves`, but their types do\n case \"removal\":\n case \"leaves\": {\n const { window, ...rest } = prediction;\n return { ...rest, band: band(prediction.band), ...(window === undefined ? {} : { window: upgradeWindow(window) }) };\n }\n case \"restarts\":\n return { ...prediction, band: prediction.band === null ? null : band(prediction.band) };\n // the format /1 has no failures on `stays`, but its type does\n case \"stays\": {\n const { failures, ...rest } = prediction;\n return { ...rest, ...(failures === undefined ? {} : { failures: failures.kind === \"window\" ? upgradeWindow(failures) : failures }) };\n }\n // the format /1 has no prediction `reconnects`, but its type does\n case \"reconnects\": {\n const { backoff } = prediction;\n return {\n ...prediction,\n flip: band(prediction.flip),\n probe: seconds(prediction.probe),\n disconnect: band(prediction.disconnect),\n backoff: { ...backoff, initial: seconds(backoff.initial), max: seconds(backoff.max), mandatoryStop: seconds(backoff.mandatoryStop), attempt: seconds(backoff.attempt) },\n setup: band(prediction.setup),\n };\n }\n default:\n return prediction;\n }\n};\n\n/** This function gives a cell of the format `/1` in the format `/2`: its bands in seconds, and its `cpu.max` in microseconds. */\nexport const upgradeCell = (cell: KindCellV1): KindCell => ({\n ...cell,\n trigger: upgradeTrigger(cell.trigger),\n prediction: upgradePrediction(cell.prediction),\n});\n\nconst upgradeFacts = (facts: RunFactsV1): RunFacts => {\n const propagated = (old: Propagated<number> | null): Propagated | null => (old === null ? null : { after: time(old.after), by: seconds(old.by) });\n const byKey = (record: Readonly<Record<string, Propagated<number> | null>>) => Object.fromEntries(Object.entries(record).map(([key, old]) => [key, propagated(old)]));\n const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, cycles, stall, period, reconnects, ...rest } = facts;\n return {\n ...rest,\n intakeAfterDeletion: time(facts.intakeAfterDeletion),\n sliceAfter: time(facts.sliceAfter),\n propagation: byKey(facts.propagation),\n ...(updates === undefined ? {} : { updates: byKey(updates) }),\n ...(healUpdates === undefined ? {} : { healUpdates: byKey(healUpdates) }),\n ...(sliceEmpty === undefined ? {} : { sliceEmpty: seconds(sliceEmpty) }),\n ...(rules === undefined ? {} : { rules: Object.fromEntries(Object.entries(rules).map(([node, old]) => [node, time(old)])) }),\n ...(left === undefined ? {} : { left: seconds(left) }),\n ...(signals === undefined ? {} : { signals: signals.map((old) => time(old)) }),\n ...(closes === undefined ? {} : { closes: Object.fromEntries(Object.entries(closes).map(([client, old]) => [client, time(old)])) }),\n ...(cycles === undefined ? {} : { cycles: cycles.map((old) => ({ empty: time(old.empty), ready: time(old.ready) })) }),\n ...(stall === undefined ? {} : { stall: { start: time(stall.start), held: time(stall.held) } }),\n // the format /1 has no facts of the producers, but its type does\n ...(reconnects === undefined\n ? {}\n : {\n reconnects: {\n ...reconnects,\n flip: time(reconnects.flip),\n gap: time(reconnects.gap),\n returns: reconnects.returns.map((each) => ({ ...each, disconnect: time(each.disconnect), back: time(each.back), setup: time(each.setup) })),\n },\n }),\n ...(period === undefined\n ? {}\n : {\n period: {\n ...period,\n median: seconds(period.median),\n mean: seconds(period.mean),\n low: seconds(period.low),\n high: seconds(period.high),\n byClient: Object.fromEntries(Object.entries(period.byClient).map(([client, old]) => [client, seconds(old)])),\n },\n }),\n };\n};\n\n/**\n * This function gives a record in the format `/2`. A record of `/2` comes back as it is. A record\n * of `/1` gets each amount as a quantity, and each value stays the same:\n * - Each band and each time of a fact is in seconds, as `/1` gives it.\n * - The `cpu.max` of a throttle is in microseconds, as `/1` gives it.\n * - The median and the main value of each run get the unit of the prediction (`unitOf`): seconds,\n * failed requests (`{request}`) or replicas (`{replica}`).\n */\nexport const upgrade = (record: KindCellRecordV1 | KindCellRecord): KindCellRecord => {\n if (record.format === FORMAT) return record;\n const unit = unitOf(record.cell.prediction);\n const amount = (value: number | null): Quantity | null => (value === null ? null : { value, unit });\n const verdict = record.verdict;\n return {\n format: FORMAT,\n cell: upgradeCell(record.cell),\n runs: record.runs,\n manifests: record.manifests,\n loads: record.loads,\n verdict: {\n ...verdict,\n median: amount(verdict.median),\n checks: verdict.checks.map((check) => ({ ...check, value: amount(check.value), facts: upgradeFacts(check.facts) })),\n },\n at: record.at,\n };\n};\n\n/**\n * This function judges a record again, from its cell and its runs, with the judge of this version.\n * It reads a record of `/1` through `upgrade`. The verdict is in the format `/2`.\n */\nexport const judge = (record: KindCellRecordV1 | KindCellRecord): KindVerdict => {\n const current = upgrade(record);\n return judgeKind(current.cell, current.runs);\n};\n","import type { Quantity } from \"@mark1russell7/quantity\";\nimport { format, valueIn } from \"@mark1russell7/quantity\";\nimport { seconds, secondsOf, showBand } from \"./bands.ts\";\nimport type { Band, KindCell, KindRun, Prediction } from \"./cell.ts\";\nimport { middle, quantileOf } from \"./stats.ts\";\nimport type { KindVerdict } from \"./verdict.ts\";\nimport { factsOf, propagationOf, propagationSource, referenceOf, updatesOf } from \"./verdict.ts\";\n\n/** A judged cell is a cell, its runs and its verdict: the part of a result that a report reads. */\nexport interface Judged {\n readonly cell: KindCell;\n readonly runs: readonly KindRun[];\n readonly verdict: KindVerdict;\n}\n\n/** A spread is the count, the extremes, the median and the 99th percentile of a set of times. */\nexport interface TimeSpread {\n readonly count: number;\n readonly min: Quantity;\n readonly median: Quantity;\n readonly p99: Quantity;\n readonly max: Quantity;\n}\n\n/** This function gives the spread of a set of times, or null for none. The percentile is by nearest rank. */\nexport const timeSpread = (times: readonly Quantity[]): TimeSpread | null => {\n if (times.length === 0) return null;\n const sorted = times.map((each) => valueIn(each, \"s\")).sort((a, b) => a - b);\n const median = middle(sorted);\n return {\n count: sorted.length,\n min: seconds(sorted[0]!),\n median: seconds(Math.round(median * 1000) / 1000),\n p99: seconds(quantileOf(sorted, 0.99)),\n max: seconds(sorted.at(-1)!),\n };\n};\n\n/** This function gives a reference with its band, and only the reference when the band is [0, 0] s. */\nconst atBand = (from: string, band: Band): string => {\n const { lo, hi } = secondsOf(band);\n return lo === 0 && hi === 0 ? `the ${from}` : `the ${from} + ${showBand(band)}`;\n};\n\n/** This function gives the prediction of a cell in a short form for a table. A prediction `ends` gives its window after its band. */\nexport const predictionText = (prediction: Prediction): string => {\n switch (prediction.kind) {\n case \"none\":\n return prediction.outcomes === undefined ? \"no failure\" : `no ${prediction.outcomes.join(\", \")}`;\n case \"window\":\n // a window with `each` is a window for each replica that got a deletion, from the references of that replica.\n // A window can open before its reference: a stale SYN_SENT entry fails the paused node up to its life before the intake\n return `failures only from ${atBand(prediction.start.from, prediction.start.band)}${prediction.end === null ? \"\" : ` to ${atBand(prediction.end.from, prediction.end.band)}`}${prediction.each === true ? \", of each deleted replica\" : \"\"}${prediction.flaps === true ? \", in each cycle\" : \"\"}${prediction.nodes === \"paused\" ? \", on the paused node\" : \"\"}${prediction.certain ? \", at least one\" : \"\"}${prediction.outcomes === undefined ? \"\" : `, each one ${prediction.outcomes.join(\" or \")}`}${prediction.afterReset === undefined ? \"\" : `, or a ${prediction.afterReset.outcome} up to ${format(prediction.afterReset.life)} after a reset on its port`}${prediction.propagation === undefined ? \"\" : `, the rules drop the replica in ${showBand(prediction.propagation)}`}${prediction.backlog === undefined ? \"\" : `, the end n × ${showBand(prediction.backlog.drain)} later and ${prediction.backlog.requests.lo}–${prediction.backlog.requests.hi} more failures for each of the n sessions on the target${prediction.backlog.drains === true ? \", and its failures each turn in the drain of the n sessions\" : \"\"}, counted at the measured period${prediction.backlog.slowest === undefined ? \"\" : `, one session draining up to ${format(prediction.backlog.slowest)}`}${prediction.backlog.early === true ? \", the last failure up to one turn before the end\" : \"\"}`}${prediction.permits === undefined ? \"\" : `, and ${prediction.permits.outcomes.join(\" or \")} permitted at ${atBand(prediction.permits.from, prediction.permits.band)}${prediction.permits.watch === undefined ? \"\" : `, the record at least ${format(prediction.permits.watch)} after the ${prediction.permits.from}`}`}`;\n case \"removal\":\n return `Service empty in ${showBand(prediction.band)}${prediction.flaps === true ? \" after each fault, and ready again before the next\" : \"\"}${prediction.window === undefined ? \"\" : `; ${predictionText(prediction.window)}`}`;\n case \"leaves\":\n return `the replica leaves in ${showBand(prediction.band)}${prediction.window === undefined ? \"\" : `; ${predictionText(prediction.window)}`}`;\n case \"restarts\":\n return prediction.band === null ? \"no restart\" : `each replica SIGTERM in ${showBand(prediction.band)}`;\n case \"stays\":\n return `stays ready, no refusal${prediction.failures === undefined ? \"\" : `; ${predictionText(prediction.failures)}`}`;\n case \"stalls\":\n return \"the rollout waits for Redis\";\n case \"ends\": {\n const closes =\n prediction.band === null\n ? \"no socket of a client ends, and each one calls again on its socket\"\n : prediction.of === \"tunnel\"\n ? `the side of the client ends the tunnel of each client in ${atBand(prediction.from, prediction.band)}${prediction.answer === undefined ? \"\" : `, or the peer answers in ${atBand(prediction.from, prediction.answer)}`}, and each one calls again`\n : `the socket of each client ends in ${atBand(prediction.from, prediction.band)}`;\n return prediction.window === undefined ? closes : `${closes}; ${predictionText(prediction.window)}`;\n }\n case \"reconnects\":\n return `another owner in ${showBand(prediction.flip)}, each producer back at the first try of its backoff after it, failures only before it, each one ${prediction.outcomes.join(\" or \")}`;\n case \"measured\":\n return \"measured\";\n }\n};\n\n/**\n * This function gives the main measurement of a cell in a short form: its median and what it\n * counts. For failed requests, it is the middle count of the counted runs.\n */\nexport const medianText = (judged: Judged): string => {\n const { cell, verdict } = judged;\n if (verdict.median === null) return \"\";\n if (verdict.median.unit === \"{request}\") {\n const counted = judged.runs.filter((run) => !run.warmup && run.void === null);\n const failures = counted.map((run) => factsOf(cell, run).failures).sort((a, b) => a - b);\n return `${failures.length === 0 ? 0 : failures[Math.floor(failures.length / 2)]} failed requests`;\n }\n return format(verdict.median, { digits: 4 });\n};\n\n/** This function gives the table of the cells in Markdown. Each row has the cell, its plan cell, its mode, its trigger, the prediction, the verdict, its runs and its median. */\nexport const cellsTable = (judged: readonly Judged[]): string =>\n [\n \"| Cell | Plan id | Mode | Trigger | Prediction | Verdict | Runs | Median |\",\n \"| --- | --- | --- | --- | --- | --- | --- | --- |\",\n ...judged.map((each) => {\n const { cell, verdict } = each;\n const runs = verdict.voided === 0 ? `${verdict.counted}` : `${verdict.counted} (+${verdict.voided} void)`;\n return `| ${cell.name} | ${cell.id} | ${cell.mode} | ${cell.trigger.kind}${cell.trigger.flaps === undefined || cell.trigger.flaps.length === 0 ? \"\" : ` (${cell.trigger.flaps.length + 1} faults)`} | ${predictionText(cell.prediction)} | ${verdict.decision} | ${runs} | ${medianText(each)} |`;\n }),\n ].join(\"\\n\");\n\n/**\n * This function gives the propagation of each calibration, by node. It is the time from the\n * deletion to the poll of the rules of each node without the pod. It also gives the time to the\n * EndpointSlice and to the stop of the intake.\n *\n * For a policy of Istio, the propagation is the LDS update of each server sidecar after the apply,\n * by node (`updatesOf`). Then `heal` is the update after the delete of the policy. `slice` and\n * `intake` are null.\n */\nexport const calibrationOf = (judged: Judged): {\n readonly nodes: Readonly<Record<string, TimeSpread | null>>;\n readonly all: TimeSpread | null;\n readonly slice: TimeSpread | null;\n readonly intake: TimeSpread | null;\n readonly heal?: TimeSpread | null | undefined;\n} => {\n const byNode: Record<string, Quantity[]> = {};\n const slice: Quantity[] = [];\n const intake: Quantity[] = [];\n const counted = judged.runs.filter((each) => !each.warmup && each.void === null);\n if (judged.cell.trigger.kind === \"authorization-policy\") {\n const heal: Quantity[] = [];\n for (const run of counted) {\n const nodeOf = (pod: string): string => run.replicas.find((replica) => replica.pod === pod)?.node ?? pod;\n for (const [pod, update] of Object.entries(updatesOf(run, run.acts.fault))) if (update !== null) (byNode[nodeOf(pod)] ??= []).push(update.by);\n for (const update of Object.values(updatesOf(run, run.acts.heal))) if (update !== null) heal.push(update.by);\n }\n const nodes = Object.fromEntries(Object.entries(byNode).map(([node, values]) => [node, timeSpread(values)]));\n return { nodes, all: timeSpread(Object.values(byNode).flat()), slice: null, intake: null, heal: timeSpread(heal) };\n }\n for (const run of counted) {\n const deletion = referenceOf(run, \"deletion\");\n for (const [node, drop] of Object.entries(propagationOf(run, deletion, undefined, propagationSource(judged.cell)))) if (drop !== null) (byNode[node] ??= []).push(drop.by);\n const facts = factsOf(judged.cell, run);\n if (facts.sliceAfter !== null) slice.push(facts.sliceAfter);\n if (facts.intakeAfterDeletion !== null) intake.push(facts.intakeAfterDeletion);\n }\n const nodes = Object.fromEntries(Object.entries(byNode).map(([node, values]) => [node, timeSpread(values)]));\n return { nodes, all: timeSpread(Object.values(byNode).flat()), slice: timeSpread(slice), intake: timeSpread(intake) };\n};\n","import type { Substrate } from \"@mark1russell7/harness\";\nimport type { Quantity } from \"@mark1russell7/quantity\";\nimport { extentSchema, quantitySchema } from \"@mark1russell7/quantity/schema\";\nimport type { Stage } from \"@mark1russell7/service\";\nimport { z } from \"zod\";\nimport type { EdgeProtocol, KindRun, TriggerKind } from \"./cell.ts\";\nimport type { KindCellRecord, KindCellRecordV1 } from \"./record.ts\";\nimport { FORMAT, FORMAT_V1, upgrade } from \"./record.ts\";\nimport type { Dataplane, KubeProxyMode } from \"./scenario.ts\";\nimport { unitOf } from \"./verdict.ts\";\n\n/**\n * This module holds the zod schemas of a kind cell record, in the formats `/1` and `/2`. It names\n * the stages of the shutdown itself, thus it does not load the service. A test holds the names to\n * the service.\n */\n\n/** These are the stages of the shutdown of the service, in their sequence. */\nexport const STAGES: readonly [Stage, ...Stage[]] = [\n \"fail readiness\",\n \"stop intake\",\n \"drain\",\n \"close transports\",\n \"stop the poller\",\n \"tear down dependencies\",\n \"close the health server\",\n \"flush the output\",\n];\n\nconst TRIGGERS = [\n \"pod-deletion\",\n \"rolling-update\",\n \"node-drain\",\n \"scale-in\",\n \"crash\",\n \"liveness-restart\",\n \"freeze-process\",\n \"rst\",\n \"blackhole\",\n \"peer-gone-without-close\",\n \"app-stall\",\n \"rollout\",\n \"cpu-throttle\",\n \"authorization-policy\",\n \"idle\",\n \"ztunnel-restart\",\n \"certificate-expiry\",\n \"cannot-serve\",\n \"zone-loss\",\n \"latency\",\n \"dns-blackhole\",\n] as const satisfies readonly TriggerKind[];\nconst KUBE_PROXY = [\"iptables\", \"ipvs\", \"nftables\"] as const satisfies readonly KubeProxyMode[];\nconst MODES = [...KUBE_PROXY, \"cilium\"] as const satisfies readonly Dataplane[];\n\nconst time = quantitySchema(\"time\");\nconst extent = extentSchema(\"time\");\nconst count = z.number().int().nonnegative();\nconst gate = z.enum([\"readiness\", \"liveness\"]);\nconst reference = z.enum([\"deletion\", \"intake\", \"fault\", \"resume\", \"heal\", \"restart\"]);\n\nconst probe = z.object({ period: time, threshold: count, timeout: time });\nconst timing = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"debounce\"), interval: time, failAfter: count, recoverAfter: count }),\n z.object({ type: z.literal(\"window\"), failAfter: time, recoverAfter: time.optional() }),\n]);\nconst knobs = z.object({\n connect_bound: time,\n request_timeout: time,\n driver_writeoff_time: extent,\n keepalive_idle: extent,\n heartbeat_interval: extent,\n heartbeat_timeout: time,\n client_retry_window: extent,\n retry_base: time,\n retry_cap: time,\n close_bound: time,\n max_connection_age: extent,\n retrans_giveup_time: extent,\n});\nconst declaration = z.object({\n poll: z.object({ interval: time, jitter: z.number().min(0).lt(1), timeout: time }),\n readiness: timing,\n liveness: timing,\n startup: time,\n phases: z.array(z.tuple([z.enum(STAGES), time])),\n cooperativeWindow: extent,\n couplings: z.array(z.object({ from: gate, to: gate, effect: z.literal(\"fails\") })),\n redis: z.object({ gates: gate.nullable(), knobs, misses: count }).nullable(),\n flag: gate.nullable(),\n watchdog: z.object({ tick: time, threshold: time }).nullable(),\n lameDuck: z.boolean().optional(),\n protocol: z.enum([\"http/1.1\", \"h2c\"] as const satisfies readonly EdgeProtocol[]).optional(),\n sharedGate: z.boolean().optional(),\n});\n\nconst replica = z.object({ pod: z.string(), node: z.string(), ip: z.string(), version: z.string() });\n/** A line keeps each field that its source wrote. The judge reads `ev`, `t` and the fields of its kind. */\nconst line = z.object({ ev: z.string(), t: z.number() }).catchall(z.unknown());\nconst run: z.ZodType<KindRun> = z.object({\n env: count,\n index: z.number().int(),\n warmup: z.boolean(),\n start: z.number(),\n end: z.number(),\n acts: z.object({\n fault: z.number().nullable(),\n heal: z.number().nullable(),\n resume: z.number().nullable(),\n cycles: z.array(z.object({ fault: z.number(), heal: z.number() })).optional(),\n }),\n target: replica.nullable(),\n paused: z.string().nullable(),\n broker: z.string().optional(),\n replicas: z.array(replica),\n void: z.string().nullable(),\n lines: z.array(line),\n dropped: z.record(z.string(), count),\n notes: z.array(z.string()).optional(),\n});\n/**\n * This schema accepts the substrate of a record (`Substrate` of the harness). The entry ./judge loads\n * no module of the harness, thus the schema is here. Its test holds it to the layers and the clouds of\n * the harness.\n */\nexport const substrateSchema: z.ZodType<Substrate> = z.object({\n layer: z.enum([\"E0\", \"E1\", \"E2\", \"E3\", \"E4\", \"E5\", \"E6\"]),\n cloud: z.enum([\"azure\", \"aws\", \"unknown\"]),\n vendor: z.string().nullable(),\n kernel: z.string().nullable(),\n hz: z.number().nullable(),\n kvm: z.boolean().nullable(),\n image: z.string().nullable(),\n});\nconst manifest = z\n .object({\n env: count,\n // A record from before the dataplane `cilium` has no `dataplane`: its dataplane is the mode of its kube-proxy.\n scenario: z\n .object({\n name: z.string(),\n kubernetes: z.string(),\n workers: count,\n dataplane: z.enum(MODES).optional(),\n kubeProxy: z.object({ mode: z.enum(KUBE_PROXY), minSyncPeriod: time, syncPeriod: time }).nullable(),\n cni: z.enum([\"kindnet\", \"cilium\"]),\n podSubnet: z.string(),\n serviceSubnet: z.string(),\n zoned: z.boolean().optional(),\n })\n .transform(({ dataplane, zoned, ...rest }) => ({ ...rest, dataplane: dataplane ?? rest.kubeProxy?.mode ?? \"cilium\", ...(zoned === true ? { zoned } : {}) })),\n cluster: z.object({\n kind: z.string(),\n nodeImage: z.string(),\n server: z.string(),\n mode: z.string(),\n docker: z.string(),\n nodes: z.array(z.object({ name: z.string(), kubelet: z.string(), kernel: z.string(), runtime: z.string(), os: z.string() })),\n }),\n images: z.record(z.string(), z.string()),\n substrate: substrateSchema.optional(),\n })\n .transform(({ substrate, ...rest }) => (substrate === undefined ? rest : { ...rest, substrate }));\nconst load = z.object({ t: z.number(), idle: z.number(), top: z.array(z.string()), foreign: z.array(z.string()), needed: z.number().optional() });\n\n/**\n * This function gives the schema of a record whose amounts have one form. The schema `a` is for a\n * time. The schema `main` is for the main value of a run: a time or a count.\n */\nconst recordOf = <A>(a: z.ZodType<A>, main: z.ZodType<A>) => {\n const band = z.object({ lo: a, hi: a });\n const window = z.object({\n kind: z.literal(\"window\"),\n nodes: z.enum([\"all\", \"paused\"]),\n start: z.object({ from: reference, band }),\n end: z.object({ from: reference, band }).nullable(),\n certain: z.boolean(),\n afterReset: z.object({ life: a, outcome: z.string() }).optional(),\n each: z.boolean().optional(),\n propagation: band.optional(),\n flaps: z.boolean().optional(),\n outcomes: z.array(z.string()).optional(),\n backlog: z.object({ drain: band, requests: z.object({ lo: count, hi: count }), most: count, drains: z.boolean().optional(), slowest: a.optional(), early: z.boolean().optional() }).optional(),\n permits: z.object({ from: reference, band, outcomes: z.array(z.string()), watch: a.optional(), why: z.string() }).optional(),\n why: z.string(),\n });\n const none = z.object({ kind: z.literal(\"none\"), outcomes: z.array(z.string()).optional(), why: z.string() });\n const prediction = z.discriminatedUnion(\"kind\", [\n none,\n window,\n z.object({ kind: z.literal(\"removal\"), band, window: window.optional(), flaps: z.boolean().optional(), why: z.string() }),\n z.object({ kind: z.literal(\"leaves\"), band, window: window.optional(), why: z.string() }),\n z.object({ kind: z.literal(\"restarts\"), band: band.nullable(), why: z.string() }),\n z.object({ kind: z.literal(\"stays\"), failures: z.discriminatedUnion(\"kind\", [window, none]).optional(), why: z.string() }),\n z.object({ kind: z.literal(\"stalls\"), why: z.string() }),\n z.object({ kind: z.literal(\"ends\"), from: reference, band: band.nullable(), window: window.optional(), of: z.enum([\"socket\", \"tunnel\"]).optional(), answer: band.optional(), why: z.string() }),\n z.object({\n kind: z.literal(\"reconnects\"),\n flip: band,\n probe: a,\n disconnect: band,\n backoff: z.object({ initial: a, max: a, mandatoryStop: a, jitter: z.number(), attempt: a }),\n setup: band,\n outcomes: z.array(z.string()),\n why: z.string(),\n }),\n z.object({ kind: z.literal(\"measured\"), why: z.string() }),\n ]);\n const cell = z.object({\n id: z.string(),\n name: z.string(),\n template: z.enum([\"T07\", \"T15\", \"T18\"]),\n stack: z.enum([\"service\", \"grpc\"]).optional(),\n mesh: z\n .object({ flavor: z.enum([\"sidecar\", \"ambient\"]), mode: z.enum([\"sidecar\", \"ambient\"]), ztunnel: z.record(z.string(), z.string()).optional() })\n .optional(),\n substitutes: z.string().nullable(),\n mode: z.enum(MODES),\n workers: count,\n trigger: z.object({\n kind: z.enum(TRIGGERS),\n hold: time.optional(),\n lead: time.optional(),\n cpuMax: z.object({ quota: a, period: a }).optional(),\n account: z.string().optional(),\n middlebox: time.optional(),\n retries: count.optional(),\n quiet: z.boolean().optional(),\n close: z.boolean().optional(),\n partition: z.boolean().optional(),\n serves: z.boolean().optional(),\n flaps: z.array(z.object({ rest: time, hold: time })).optional(),\n delay: time.optional(),\n }),\n pod: z.object({ replicas: count, grace: time, preStop: time, readiness: probe, liveness: probe, startup: probe.nullable() }),\n declaration: declaration.nullable(),\n workload: z.object({\n every: time,\n timeout: time,\n connections: count.optional(),\n sessionCheck: z.object({ keepalive_time: extent, keepalive_timeout: time }).optional(),\n onTarget: count.optional(),\n byName: z.boolean().optional(),\n }),\n prediction,\n calibrates: z.boolean(),\n runs: count,\n vip: z\n .object({\n clients: count,\n announcer: z.enum([\"kube-vip\", \"metallb\"]).optional(),\n memberlist: z.object({ probeInterval: time, probeTimeout: time, suspicionMult: count }).optional(),\n })\n .optional(),\n pulsar: z.object({ clients: count, probe: time }).optional(),\n plannedLoad: z.number().optional(),\n });\n const facts = z.object({\n failures: count,\n outcomes: z.record(z.string(), count),\n byNode: z.record(z.string(), count),\n first: z.number().nullable(),\n last: z.number().nullable(),\n deletion: z.number().nullable(),\n intakeAfterDeletion: a.nullable(),\n sliceAfter: a.nullable(),\n propagation: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()),\n sliceEmpty: a.optional(),\n rules: z.record(z.string(), a.nullable()).optional(),\n left: a.optional(),\n signals: z.array(a.nullable()).optional(),\n deletions: z.array(z.object({ pod: z.string(), intake: z.number().nullable(), deletion: z.number() })).optional(),\n updates: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()).optional(),\n healUpdates: z.record(z.string(), z.object({ after: a.nullable(), by: a }).nullable()).optional(),\n closes: z.record(z.string(), a.nullable()).optional(),\n cycles: z.array(z.object({ empty: a.nullable(), ready: a.nullable() })).optional(),\n sessions: z.object({ onTarget: count, of: count, byClient: z.record(z.string(), count) }).optional(),\n stall: z.object({ start: a.nullable(), held: a.nullable() }).optional(),\n period: z.object({ median: a, mean: a, low: a, high: a, intervals: count, byClient: z.record(z.string(), a) }).optional(),\n reconnects: z\n .object({\n flip: a.nullable(),\n gap: a.nullable(),\n returns: z.array(z.object({ pod: z.string(), disconnect: a.nullable(), back: a.nullable(), setup: a.nullable(), tries: count })),\n failures: z.record(z.string(), count),\n })\n .optional(),\n });\n const verdict = z.object({\n decision: z.enum([\"holds\", \"fails\", \"extend\", \"measured\", \"calibration\", \"void\"]),\n counted: count,\n voided: count,\n failed: count,\n median: main.nullable(),\n why: z.string(),\n checks: z.array(z.object({ ok: z.boolean(), why: z.string(), value: main.nullable(), facts, tail: z.string().optional() })),\n });\n return { cell, verdict, runs: z.array(run), manifests: z.array(manifest), loads: z.array(load), at: z.string() };\n};\n\nconst v2 = recordOf<Quantity>(time, quantitySchema([\"time\", \"count\"]));\nconst v1 = recordOf<number>(z.number(), z.number());\n\n/**\n * This schema accepts a record in the format `/2`. The median and the main value of each run must\n * have the unit of the prediction of the cell (`unitOf`).\n */\nexport const kindCellRecordSchema: z.ZodType<KindCellRecord> = z\n .object({ format: z.literal(FORMAT), ...v2 })\n .superRefine((record, ctx) => {\n const unit = unitOf(record.cell.prediction);\n const values = [record.verdict.median, ...record.verdict.checks.map((check) => check.value)];\n for (const value of values) {\n if (value !== null && value.unit !== unit)\n ctx.addIssue({ code: \"custom\", message: `the main value is in ${value.unit}, and the prediction ${record.cell.prediction.kind} gives ${unit}` });\n }\n });\n\n/** This schema accepts a record in the format `/1`. */\nexport const kindCellRecordV1Schema: z.ZodType<KindCellRecordV1> = z.object({ format: z.literal(FORMAT_V1), ...v1 });\n\n/** This function reads a record of either format from parsed JSON, and gives it in the format `/2`. */\nexport const readRecord = (data: unknown): KindCellRecord => {\n const format = typeof data === \"object\" && data !== null ? (data as { format?: unknown }).format : undefined;\n if (format === FORMAT_V1) return upgrade(kindCellRecordV1Schema.parse(data));\n if (format === FORMAT) return kindCellRecordSchema.parse(data);\n throw new Error(`a kind cell record has the format ${FORMAT} or ${FORMAT_V1}, not ${String(format)}`);\n};\n"],"mappings":"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"}