sparkles:test-runner — Benchmark-measurement delivery plan
Companion to SPEC.md: the milestones that make the marked target sections true. Each milestone is independently green (builds + tests + lints). Two tracks interleave: the M-track (workload harness — the I/O-bench roadmap's M4–M11) and the B-track (native PMU backends — the research backend proposal's milestones 1–6, referenced here as B1–B6 to keep both numbering schemes unambiguous). The audit of the shipped layer is sparkles-baseline.md; the gap-to-milestone mapping is the delta table.
Shipped: M1-M3 and riders
Merged via PR #88 and audited by the baseline page:
- M1 — metric catalog (
metrics.d):MetricDescriptor/MetricCell/MetricClass,--metrics/--list-metrics, transitive source opening (SPEC §5). - M2 — tier-0 counters (
tier0.d):getrusage+/proc/self/iodeltas with calibrated self-cost subtraction (SPEC §6.1). - M3 — syscall tracepoints (
syscalls.d): in-processstrace -cviaperf_eventtracepoints, tracefs-root-gated (SPEC §6.1, §9). - Riders:
--bench-json+--bench-min-time,skipTest,--group-by/--sort-by, the live results ticker, per-pass enabled/running multiplex deltas, raw-tick timing,benchCasematrix benchmarks (SPEC §3, §4, §7, §8).
The delta-table row "grouped counting, exact" is closed ("none — matches"); every other row maps to a milestone below.
Design invariants
Carried from the original roadmap, amended by the research:
- The catalog seam composes everything (SPEC §5): a new source is one
Nullable!XStatsfield, three lifecycle lines, and a cells/family pair. - Two source shapes (SPEC §6.1): bracketed (per-iteration ioctl window) and snapshot/delta (window-friendly). Degrade, never fail; capability is a runtime probe result, never a compile-time assumption.
- Quantitative vs diagnostic is structural (SPEC §1): reported/gated numbers read only quantitative fields; diagnostic renders separately.
- Acquisition stays pure D. druntime's
core.sys.linux.perf_eventmodels the full ring-buffer/record/mmap-page ABI — even the B6 sampler needs no C shim. C libraries enter only as soft dependencies that degrade to advertised absence: libpfm4 (B2) and libdw (B6) via dlopen or an opt-in build config; never libnuma (nonuma.pc, the syscalls are not in glibc — call rawget_mempolicy/move_pages); no libtraceevent (it decodes caller-supplied buffers only — M9 scopes a small pure-D decode core instead). Naming data is offline-only: LIKWID / intel-perfmon / kernel pmu-events JSONs are references to harvest, never runtime deps. Nix: nixpkgs libpfm ships no.pc→ devshellbuildInputs+NIX_LDFLAGS, needed in both the shellHook and theciwrapper (the research probes' proven CI path); elfutils (tested 0.194) entersbuildInputslikewise if B6 takes the link-time arm. - Verification-bed honesty (SPEC §9): the hardware beds are Zen 4 Linux (Ryzen 9 7940HX,
perf_event_paranoid = −1) and an Apple MacBook Pro M4 Max running macOS (unprivileged transcripts). ARM-Linux, RISC-V, Intel PEBS, multi-node NUMA, and Windows have no hardware bed — those aspects ship source-verified/literature-gated, withskipTestdegradation and no[hw-verified]claims. All paranoid > −1 behavior is literature-derived until probed (open-issues § O1). - Units seam (SPEC §5.3): symbol-as-label,
Modeas the rate stand-in; all format semantics behindscaled/fixedso thesparkles.quantitiesconvergence is localized (open-issues § O6).
Milestone order
Interleaved by value; B-track numbers alias backend-proposal.md §2–§7.
| # | ID | Milestone | Gate / permissions |
|---|---|---|---|
| 1 | B1 | Capability seam (Capability/CapabilityReport, backend trait) | none |
| 2 | B2 | Linux counting depth (raw events, naming, labeled scaling, rdpmc) | none (soft libpfm4) |
| 3 | M4 | @workload window mode + wall decomposition | none |
| 4 | M5 | PSI stall integrals | CONFIG_PSI |
| 5 | B3 | macOS floor (proc_pid_rusage counting tier) | none (Apple MacBook Pro M4 Max verification) |
| 6 | M6 | Page-cache regime control + residency verify | drop_caches = root |
| 7 | M7 | Storage provenance fingerprint | none |
| 8 | M8 | cgroup-v2 isolation + memory.max sweep | root / systemd delegation |
| 9 | B5 | Precise memory tier (IBS-first) + NUMA oracles + LatencyHistogram | paranoid; IBS hardware |
| 10 | B6 | Sampling & symbolization (--bench-profile) | paranoid; perf_event_mlock_kb; soft libdw |
| 11 | M9 | Off-CPU profiler (rebuilt on B6) + biolatency floor | tracefs root (Tier B) |
| 12 | M10 | CO-safe open-loop load generator | none |
| — | B4 | Windows floor (CycleTime; ETW elevated tier) | blocked: no Windows hardware |
| — | M11 | Gated spikes (eBPF, block tracepoints, SCHED_FIFO, ARM SPE/BRBE, RISC-V) | caps / hardware |
Sequencing rationale: B1 is pure reporting value and gives every later milestone one absence vocabulary; B2 deepens the mode the harness lives in today (raw events make wired's per-byte tables µarch-portable); M4 is the keystone the workload track (M5–M8) hangs off; B3 kills the "all counters vanish off Linux" cliff cheaply; B5/B6 add the where dimension and are the only milestones with new soft C dependencies; M9 is deliberately after B6 so its Tier B reuses the sampling infrastructure instead of hand-rolling one; M10 is independent and can move earlier if needed. Each milestone gets a detailed re-plan when reached.
Milestones that cite SPEC sections make those (target) passages true; milestones without a citation (M7, M8, M10, M11) fold their surface into SPEC as new sections when they land.
B1 — Capability seam
Shipped (branch
feat/test-runner-capability-seam):capability.d(enum, report, trait, host probes), per-tiercapabilities()observers, theCounterGroupsmerge, the--list-metricsblock, and the report-derived bench-header notes. One design deviation from the research sketch, recorded in SPEC §6.2:tryOpenkeeps returning the group (arities diverge; call sites depend on it) andcapabilities()is a separate const observer; the reason map is an ordered absence array, not an AA. Acceptance verified on the dev box:preciseMemoryabsent with a "hardware present (ibs_op PMU)" reason,eventTracingabsent via the tracefs gate,--perftable rendering unchanged.
(backend-proposal §2; SPEC §6.2.) Capability bitflag enum (one flag per survey concern plus real-world sub-splits: counting, countingRaw, countingScaled, selfMonitoring, ipSampling, preciseMemory, symbolization, eventTracing, numaAttribution, eventNaming); CapabilityReport { available; unavailableBecause }; a DbI isCounterBackend trait making CounterGroups' implicit contract nameable, with optional primitives detected by presence. --list-metrics gains a per-backend capability block; the bench header prints one line per absent-but-requested capability.
Hardening from the grounding ledger: the proposal's D sketches are uncompiled design artifacts (ledger P2) — compile-validate the trait against metrics.d before freezing the seam. Workload-track sources (M5 PSI, M6 regime, M8 cgroup) adopt CapabilityReport too.
Acceptance: on the dev box the report reproduces the survey's findings — preciseMemory present via ibs_op, eventTracing absent (tracefs 0700); --perf table output unchanged.
B2 — Linux counting depth
Shipped (branch
feat/test-runner-capability-seam, four commits — one per capability):raw.d(--metrics=raw:r<hex>columns in their own counter group),--perf-scaledlabeled estimates (≈cells,estimatedMetricsin schema-2 JSON — O4 resolved; sub-millisecond scaled passes render unavailable),event_naming.d(dlopen-soft libpfm4 with the ENCODE_INACTIVE + table-prefix recipe;pfm:<name>selectors), andrdpmc.d(the selfMonitoring primitive + the O2 bracket-cost measurement: ioctl pair 2.2 µs vs rdpmc read 30 ns vs read(2) 551 ns on the dev box — the rdpmc case asserts each read is real, not the index-0 early exit). Switching the counting pass to the rdpmc bracket remains open-issue O2. A post-B2 adversarial review round (9 confirmed findings) hardened the estimate thresholds, the raw column visibility/dedup/ truncation contracts, sort-by-header support, and the bracketCost measurement itself. Thewiredrunner-validation follow-ups landed as B2 riders: the bench header discloses degraded-but-available perf modes (LLC drop / user-only / scaled — the validation's B1 acceptance gap),benchProvenancestamps suite-controlled facts into the header andmeta.provenance(former O10), and--perf-iters+ per-rowcountIterationsmake counting-pass totals pinnable and auditable (former O11); O9/O12's documentation parts landed in the benchmark how-to.
(backend-proposal §3; SPEC §6.3, §7.) Four capabilities, all probed:
countingRaw—raw:r<hex>selectors →PERF_TYPE_RAW; unlocks umask-qualified µarch events.eventNamingvia soft libpfm4, with the proven recipe: encode throughPFM_OS_PERF_EVENT(privilege modifiers land inattr.exclude_*, not config bits); force tables from CPUID — stock libpfm 4.13.0 misses Zen 4 model 0x61 — usingLIBPFM_ENCODE_INACTIVE=1plus an explicittable::prefix, notLIBPFM_FORCE_PMU(exclusive: it breaks genericcycles/instructionsresolution); the D binding must pinpfm_perf_encode_arg_tat exactly 40 bytes on LP64 (the ABI0 size check). Reference implementation:pfm4-name-roundtrip.d. Absent libpfm →eventNamingadvertised absent; numeric selectors still work.countingScaled(opt-in, labeled): enabled/running scaling per the uAPI formula, with the SPEC §6.3 quality gates —running == 0renders "not counted", never 0; sub-millisecond running slices are flagged (the probe measured a 5.7× scale error on a 0.58 ms slice);--bench-jsonmarks estimated cells (open-issues § O4). Default stays exact-or-drop. The seam includes the group-refused branch (RISC-V refuses unplaceable groups outright).selfMonitoring— rdpmc mmap-page seqlock fast path for very short bodies;cap_user_rdpmcis arch-set and policy-disableable, so probe and keep theread(2)fallback; PMUSERENR (ARM) /scounteren(RISC-V) share the flag per-ISA. Measure the "~10× cheaper" literature claim on-host before advertising it (open-issues § O2).
M4 — @workload window mode
Shipped (branch
feat/test-runner-workload, six commits): the@workload/@workload(reps: N)marker +isWorkloadtraits (combining with@benchmarkis a discovery-time error), cumulativeGroupSnapshotedges inperf_group.d(the gate/scale tail factored out and shared with the counting pass, plus the window-only never-enabled →nangate), per-tiersnapshot/windowStats/enable/disable(all four tiers now satisfyhasSnapshot), andworkload.d:WallSource(thread-scoped on Linux —RUSAGE_THREADas a local ABI enum +/proc/thread-self/schedstat; cross-thread CPU disclosed from the process-wide reading), pureassembleDecomposition(silent-clamp budget = one scheduler tick — rusage's tick-sampled user/kernel split smears on short windows), in-bodyworkloadWindowvia a TLS context, and the single-passrunWorkloaddriver (whole-body candidate window; the body is never re-run for counting). Renders as oneworkloadstable;--list-metricsgains awallblock;--bench-jsongains thewindowssibling array — O7 resolved as option (A), the bump absorbed into the never-released schema 2. Verified by the hardware honesty pair (spin → on-CPU dominates; sleep → residual, never a fabricated cause) and a perf-attached window-totals test on the dev box.
(SPEC §1, §3, §4.) New @workload marker + isWorkload trait; WorkloadWindow (deliberately not BenchStats — its per-iteration fields misrepresent a single window), runWorkload, in-body workloadWindow; the phase-model driver and WallDecomposition with its honesty caveats (only runqueue + disk are true per-cause durations; PSI-io can overlap runqueue, so the residual clamps at 0 with a status note). Renders as its own table. Research amendments: sources report through B1's CapabilityReport; never assume 4 KiB pages / 64 B lines in window accounting (Apple Silicon: 16 KiB / 128 B). JSON serialization of windows was open-issue O7 (resolved — see the shipped note).
M5 — PSI stall integrals
Shipped (branch
feat/test-runner-psi, four commits) — with one user-approved retarget recorded in SPEC §4: the original "feedsWallDecomposition.offCpuDisk" predates M4's thread-scoping decision and is unsound —/proc/pressureis system-wide, so any attribution (raw or capped by the thread's off-CPU time) reports other processes' stalls as the workload's and deterministically fails M4's shipped sleep-honesty test on a host with background IO (the dev box idles at ~80 % iosomepressure; a pure CPU spin's 30 ms window shows ~22 ms of concurrent system io stall). M5 therefore ships the integrals as diagnostics:psi.d(parsePsiFileover the monotonictotal=<µs>accumulators, averages ignored;PsiSourcesnapshot-shaped likeWallSource, absence as a reasonedCapabilityAbsence), window deltas asWorkloadWindow.psi(subtracted in long µs before the ns conversion — the absolutes near 2⁵³ as ns on long-uptime hosts), theio-stalltable column placed afterother(context, not a decomposition part), and the JSONpsiobject withscope: "system".offCpuDiskstays nan and moves to M8, whose cgroup-scoped*.pressure(identical file shape) reusesparsePsiFileverbatim and makes attribution real.
(SPEC §4.) PsiSource (snapshot/delta): parse the monotonic total=<µs> accumulator from /proc/pressure/{io,memory,cpu} (ignore the decaying averages); window delta = stall-time integral, reported as a $(B system-wide diagnostic) — the original "feeds WallDecomposition.offCpuDisk" target was retargeted to M8 by the SPEC §4 recorded judgment (system scope cannot attribute to the measured thread). Per-cgroup *.pressure reuses the parser under M8. CONFIG_PSI=n → absence via B1's vocabulary.
B3 — macOS floor
Shipped (branch
feat/test-runner-macos-floor, three commits + docs):perf.dgains aversion (OSX)body — the samePerfGroupsurface backed byproc_pid_rusage(RUSAGE_INFO_V4)'sri_instructions/ri_cycles(ABI pinned by static asserts, sizeof 296 / offsets 248/256, verified against the SDK header and a live probe on the T6041), with tier-0-style per-bracket calibration (netOfCosthoisted platform-neutral), an enable/disable window-arming latch (the counters free-run; preserves the SPEC §4 never-enabled → nan gate),degraded() == openedso every run disclosures the process-wide scope, and the survey-language capability ads (kpc root+allowlist, xctrace-only sampling). Riders: a darwin tier-0 body (getrusage BSD tail declared over druntime'sru_opaque[14],ri_diskio_*bytes;deltaStats' -1 guard extended to all io fields so absent analogs are nan, never zeros) and thehw.nperflevelsP/E-core status suffix (M7's provenance stamp supersedes it). Acceptance on the M4 Max (Darwin 25.3): the full impl suite passes live (169, zero skips),--bench --perfrendersinstr/iter 97.1 │ IPC 0.92for the median benchmark with br/cache em-dashed and the header line--perf: process-wide fixed counters (proc_pid_rusage) — not per-bracket events; P/E-core host (2 perf levels)…; a@workloadwindow reports 646M instructions at IPC 4.77 over a 30 ms spin. One recorded judgment (SPEC §6.2): the counters staydiagnosticclass — per-OS class changes would break schema stability, and process-wide counts are not gate-safe. Stale facts corrected: darwin CI exists (macos-latestrunsdub test— it exercises the VM degrade path), and dub works on Apple MacBook Pro M4 Max again (the fork-ENOMEM is gone; the storeldc-1.41.0+dub-1.39.0pair built everything directly).
(backend-proposal §4; SPEC §9.) proc_pid_rusage(RUSAGE_INFO_V4) → ri_instructions/ri_cycles as a snapshot-pair tier: true unprivileged instructions/cycles/IPC — richer than Linux tier-0 — with the honest scope note (process-wide fixed counters, not per-bracket configurable events). Capability ads for the rest: kpc is root-or-blessed-pid with the RESTRICT_TO_KNOWN allowlist (102 events on T6041) and single-owner EBUSY (Instruments running) as a distinct status; no DTrace cpc provider exists — never plan that route; sampling is xctrace-brokered only. kpep-plist parsing (world-readable, keyed by hw.cpufamily) is the naming groundwork — never hardcode Apple selectors: M4/M5 chips remapped the common events onto PMUv3 architected numbers while M1–M3 use Apple numbers, and the fixed-counter count is itself unresolved (open-issues § O8). Portability rider shared with M7: on P/E-core hosts (hw.nperflevels) record per-run core-type provenance. Verification: Apple MacBook Pro M4 Max transcripts for the live path (see the shipped note) plus the macos-latest CI leg for the VM degrade path.
M6 — Page-cache regime control
Shipped (branch
feat/test-runner-cache-regime, five commits):CacheRegime {steadyState, warm, cold}(steadyState first for.initcorrectness — enum-order deviation recorded) + the marker'sregimefield;cache_regime.d(local statfs/fadvise declarations — druntime's POSIX_FADV surface is docs-only; fdatasync before DONTNEED, dirty pages don't evict; mincore residency page-weighted with sysconf stride; the pureresolveStamppolicy); in-bodyworkloadFileswith the candidate-refresh (prep is setup — proven by a deterministic sleep-then-prep-then-work test), replace-not-merge stamps, a truly-inert foreign-runner path, and prep-skip notes undermeasuring; theregimetable column + JSONregimeobject (schema 2, still unreleased). Deviations, all recorded in SPEC §3/§4: no drop_caches ever (system-global root-only sledgehammer; fadvise + verify + downgrade-note is the honest per-file scope — cgroupmemory.maxis M8's scoped successor); stamps attach only to rows at/after aworkloadFilescall (a fabricated "steadyState, verified" on regime-less rows would violate the degradation religion); the post-body residency-verify phase dissolved into the call site; regime is an actuator, not a source — no capability block, andCacheRegimeStampdeliberately does not adoptCapabilityReport. Empirical guardrails baked into the policy: this dev box's /tmp is ZFS, where mincore is blind in BOTH directions (ARC serves reads without populating the page cache) — residency thresholds are suppressed there with notes; the cold-vs-warm acceptance (cold rd-bytes ≥ size/2 and > 10× warm's) is fs-gated to plain filesystems and runs on CI's ext4. The louder suite also exposed two pre-existing load-flaky tests (tier0 calibration comparison; the M4 spin-honesty test vs GC stop-the-world) — both de-flaked by asserting their actual contracts.
(SPEC §4.) CacheRegime { cold, warm, steadyState }; in-body workloadFiles(regime, paths); cold = posix_fadvise(DONTNEED) per file (drop_caches only as root, else downgrade + note); warm = explicit preload; residency verified via mmap + mincore before/after, stamped on every row (CacheRegimeStamp{requested, effective, residentFraction*, note}). Validity probes: tmpfs ⇒ cold impossible (effective = steadyState); zfs ⇒ cold partial (ARC survives — noted). Amendments: page-size portability (16 KiB pages change mincore stride and working-set math); B5's data-source columns are the future diagnostic "why" for regime effects.
M7 — Storage provenance fingerprint
Run-level StorageProvenance{fsType, mountOptions, ioScheduler, deviceClass, readaheadKb, thpState, ioModel} from pure /proc + /sys reads; declared (not sniffable) properties render "declared, not measured"; prints as a header banner; degrades field-by-field. Amendment: re-probe topology per boot — SNC/NPS BIOS modes multiply visible NUMA nodes and re-scope uncore counters; never cache node counts across configuration changes.
M8 — cgroup-v2 isolation and memory.max sweep
CgroupV2{tryCreate, moveSelfIn, setMemoryMax, readStat, destroy} + CgroupStat (workingset_refault, file, ioR/Wbytes, cpuUsageUs, memPressureTotalUs). Inherits offCpuDisk from M5 (SPEC §4 recorded judgment): the per-cgroup io.pressure/memory.pressure files have the same shape as /proc/pressure — psi.d's parsePsiFile reuses verbatim — and a cgroup holding only the workload process makes the stall integral attributable, so the decomposition's disk slot finally fills here (the JSON psi.scope becomes "cgroup"). Two uses: clean per-window accounting, and memoryMaxSweep(caps, body) → a performance-vs-cache-size curve rendered as sibling rows. Permission reality: root or systemd user delegation (systemd-run --user --scope -p Delegate=yes); anything less → tryCreate fails → keep per-process counters, report absence via B1.
B5 — Precise memory tier
(backend-proposal §6; SPEC §8.1, §9.) Engine-select-then-configure: probe the ibs_op sysfs PMU before cpu/caps/max_precise — gating on max_precise alone silently excludes all AMD. The hw-verified IBS recipe: sample_type = IP|ADDR|DATA_SRC|WEIGHT|PHYS_ADDR; privilege filtering via the swfilt bit (config2:0) — bare exclude_kernel is EINVAL on Zen 4 and exclude_hv is never accepted; the degrade ladder drops PHYS_ADDR first (the privilege-gated field); hardware load-latency pre-filter (config1 threshold in [128, 2048] cycles) iff IBS_CAPS_OPLDLAT. One vendor-neutral perf_mem_data_src decoder (the composite mem_lvl_num/mem_remote/mem_hops/mem_snoopx fields, not the deprecated PERF_MEM_LVL_* namespace). WEIGHT latency aggregates only over DC-miss load samples (valid-bit gating); hit/miss level histograms render separately. Page→node attribution via raw get_mempolicy(MPOL_F_NODE|MPOL_F_ADDR)/move_pages (per-arch syscall numbers tabulated in the probe). libpfm strips precise attrs on AMD — the IBS-vs-PEBS split lives in backend logic, not the naming layer. The PEBS branch is structurally present but Intel-hardware-gated (skipTest); SPE is deferred (AUX buffer + MIDR-dispatched decode tables; no aarch64-linux bed). Cross-node classification tests skipTest on single-node hosts. Reference implementation: mem-latency-numa.d. All columns diagnostic. Introduces the shared GC-free LatencyHistogram module (log-linear buckets) as its percentile carrier — M9 and M10 consume it later (first consumer introduces, keeping every milestone green).
B6 — Sampling and symbolization
(backend-proposal §7; SPEC §7, §8.1.) --bench-profile: a third pass (like counting — never touching the timing pass) that turns "IPC fell" into "IPC fell in sumSquares at readers.d:137".
- Pure-D ring consumer: acquire-load
data_head, process, release-storedata_tail; accountPERF_RECORD_LOSTso aggregates are never silently biased. Ring size gated byperf_event_mlock_kb. - Address-space model synthesized from
/proc/self/mapsat enable time —PERF_RECORD_MMAP2arrives only for mappings created while enabled (hw-verified: zero records for pre-existing code) — with build-id validation modeled on perf'sdso__build_id_mismatch(the stale-binary hazard is a bench-harness reality: rebuilt binary vs old-run comparison). - Symbolization via soft libdw:
dwfl_report_elf→dwfl_module_addrinfo(offset/symarguments non-NULL — NULL segfaults, hardware-hit) →dwfl_module_getsrc; inline attribution from day one (dwarf_getscopeschains, innermost-first) — benchmark binaries are-Obuilds, so hot LDC-inlined leaves otherwise misattribute to their callers;pc -= 1before symbolizing non-activation caller frames. Absent libdw ⇒symbolizationadvertised absent, samples still counted. - Optional DWARF-CFI unwind (
REGS_USER+STACK_USER; hw-verified 5-frame backtrace on a--frame-pointer=nonebuild); the perf→DWARF register map is x86-64-only — per-ISA gate. - Output: per-case flat top-N profile (with inline chains) as a
diagnosticsection. Reference implementations:sampling-symbolize.d,unwind-stack-user.d.
M9 — Off-CPU profiler and biolatency floor
Rebuilt on B6. Tier A (zero-perm floor): helper-thread sampling of /proc/self/task/*/{stat,wchan} → off-CPU %-by-state + wchan histogram. Tier B: B6's ring consumer pointed at sched:sched_switch — callchain at switch-out, switch-out→in pairing per tid, symbolization from B6 (the old hand-rolled maps/symtab/demangle layer is dropped). Tier B additionally needs what B6 does not provide: typed tracepoint decode of the PERF_SAMPLE_RAW blob against the tracefs format schema — name-based field lookup, never fixed struct casts (offsets shift across kernels), plus a string/array getter (prev_comm) — scoped as a small pure-D decode core (libtraceevent's decode split without the C dependency; it does no tracefs I/O anyway). Tier B's gate is tracefs readability (root-only 0700 on hardened hosts — the same gate as --syscalls, independent of paranoid). biolatency here is the /proc/diskstats delta floor only; the block-tracepoint tier stays in M11. Consumes B5's LatencyHistogram. Rendered as labeled blocks below the numeric table.
M10 — Open-loop load generator
driveOpenLoop(request, LoadSchedule): precomputed intended send times (fixed or Poisson), absolute-deadline wakeups (clock_nanosleep(TIMER_ABSTIME)), latency measured from the intended send time — the structural coordinated-omission fix; a naive actual-send clock is prohibited. Overload surfaces as queue depth + schedule skew, never silent throttling. Driver hot path is allocation-free; server counters are per-tid or cgroup-scoped so driver overhead never pollutes them. Intended latency histogram (B5's LatencyHistogram) is the quantitative headline; service latency and backpressure are diagnostic.
B4 — Windows floor (blocked)
(backend-proposal §5; SPEC §9.) Blocked on a Windows hardware bed — the Wine cross pipeline only proves the degrade path, and nothing on this platform is hw-verified. Scope when unblocked: driver-free CycleTime via EnableThreadProfiling/ReadThreadProfilingData (winbase.h, Win 7+); elevated ETW PMC tier (admin + SeSystemProfilePrivilege; 3–4 PMC hard budget with no enabled/running scaling — size groups to fit or split runs); QueryWorkingSetEx as the move_pages analog for NUMA groundwork; bindings vendored from the windows-d generated modules, not hand-written extern(Windows). Explicit infeasibility verdicts to encode: public PEBS-class sampling absent; arbitrary event registration is system-global only (out of scope). Version floors: LBR Win10 19H1+, raw ProfileSource 1903+.
M11 — Gated spikes
Feasibility-spike-first items, each behind a runtime permission probe:
- eBPF off-CPU (in-kernel aggregation): pursue only after a spike proves cross-kernel verifier acceptance and the permission probe passes; dead by default where
unprivileged_bpf_disabled=2. - Block-tracepoint biolatency (system-wide; paranoid ≤ 0 / CAP_PERFMON).
- Load-gen follow-ons: subprocess/socket targets,
SCHED_FIFOdriver pinning (CAP_SYS_NICE), client-tail ↔ server-PSI correlation. - ARM-Linux validation bundle (when an aarch64-linux bed exists): big.LITTLE cpumask-PMU discipline plus a "counted 0 with enabled > 0" sanity check (wrong-cluster opens count zero silently);
exclude_idleisEOPNOTSUPPon PMUv3; event presence is three-tier (PMCEID*bitmaps for the common0x00–0x3Fset;0x40+IMPDEF;0x4000+arch-extension); SPE and BRBE as separate gated items. - RISC-V bundle (spec-driven; no hardware): a capability subset by construction — counting always (SBI), sampling iff Sscofpmf,
exclude_*iff Sscofpmf, precise/data-source permanently absent, branch records blocked until ariscv_ctr.cconsumer lands; skid on the sampledxepcis unremovable (document, don't fix); event names only from vendored kernel pmu-events JSON (libpfm4/PAPI/LIKWID have no RISC-V tables).
Cross-cutting honesty
Ship these caveats; never paper over them:
- Quantitative vs diagnostic is enforced structurally — reductions producing reported/gated numbers read only quantitative fields.
- "Not counted" is not zero; multiplex estimates are labeled everywhere they appear, including
--bench-json. - Off-CPU by cause without eBPF is partial: runqueue + disk are real durations; lock/sleep is a count annotation on a clamped residual.
- Cache regime is stamped
effective(tmpfs ⇒ cold impossible; zfs ⇒ partial; drop_caches ⇒ root) so mismatched runs are never compared. - Coordinated omission is an invariant (intended-time latency mandatory).
- Permissions degrade, never fail — and the paranoid/tracefs/per-field gates are independent axes, each probed separately; the paranoid > −1 matrix is literature-derived until probed.
- The MMAP2/build-id stale-binary hazard applies to every self-profiling feature: synthesize mappings, validate build-ids.
- The event vocabulary is harness-owned — no naming layer spans OSes.
- User-stack quality is build-flag dependent, softened by B6's CFI unwind; big.LITTLE wrong-cluster opens count zero silently — keep the sanity check.
Verification
Every milestone lands as independently green commits: full suites (dub test :test-runner-impl -- --self-test, dub test :base, nix run .#ci -- --test --fail-fast), plus per-milestone gates:
- B1 —
--list-metricsshows the capability block; on the dev box the report matches the survey (preciseMemory viaibs_op; eventTracing absent);--perftable output unchanged. - B2 —
--metrics=raw:r<hex>counts on the dev box; libpfm-absent build still passes witheventNamingreported absent; scaled cells carry the estimate marker; rdpmc bracket cost measured and recorded. - M4/M5 — window rows render with decomposition; Σ(parts) ≤ wall with clamped residual; PSI-less kernel degrades with a reason.
- B3 — Apple MacBook Pro M4 Max transcript shows instructions/cycles/IPC columns unprivileged; Linux/stub builds unchanged.
- M6–M8 — regime stamps present on every row; tmpfs downgrade observed; unprivileged cgroup run reports absence and still passes.
- B5/B6/M9 — parity runs against the research probes (
mem-latency-numa.d,sampling-symbolize.d,unwind-stack-user.d);skipTeston hosts lacking IBS/paranoid headroom; profile sections render below tables, never as columns. - M10 — CO self-test: an injected stall shows up in intended-time latency; schedule-skew reported.
Every backend ships its Linux (or per-OS) body plus an identical-surface stub, and environment-dependent tests call skipTest(reason).