Every performance ceiling in the plugin subsystem either never runs or cannot fail #116
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#116
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
From the #76–#79 audit. Two independent mechanisms, filed together because they are one class and fixing them separately would leave the class half-closed: the plugin subsystem has performance ceilings, and not one of them can currently report a regression.
This matters more here than the count suggests. The project's hardest-won operational finding is that correctness gates cannot see slowdowns — a 3.2× cold-index regression passed ~1950 tests and CI 10/10 three times, and only a wall-clock ceiling caught it. So the ceilings are not garnish; they are the only instrument for an entire class of defect.
Mechanism 1 — the benches do not run at all
All seven
#78performance benches are#[ignore]d and appear in no CI job.The one that matters most is
bench_promotion_lock. Promotion holds the writer lock ~7s at 100k files (2.5–3.0 µs/row, linear, no knee) — and that number is disclosed to operators byplugin enable. So we publish a figure to users whose backing measurement is never executed. If it drifts, the disclosure becomes false silently.Also unmeasured behind the same gap: rollback latency and GC cost. And no 100k-file fixture exists, so even a dispatched run would not exercise the shape the number describes.
Mechanism 2 — the ceiling that does run cannot fail
WARM_ROUND_TRIP_CEILINGis 100 ms. Measured warm round trip: 0.053 ms. That is 1887× of headroom.The decisive part is not the ratio, it is this: the ceiling's own comment names the two regressions it exists to catch, at roughly 18 ms and 15 ms. Neither would breach 100 ms. So the ceiling cannot fail for either reason it was written, and it is the comment itself that proves it — no external judgement required.
Two further gaps in the same file: CPU is bounded nowhere committed, and the mixed-load section bounds neither latency nor throughput.
MIXED_FLEETis four wasm packages with no builtin, so it cannot see a package starving the builtin path — which is the contention shape an operator would actually hit.The rule this should be fixed against
Ask of every threshold: which direction does the likely bug push this number? A bound that the failures it was written for cannot reach is decorative. Where a harness's likely errors all push the measurement the same way, ship a floor as well as a ceiling — the startup payload gate (
STARTUP_PAYLOAD_MIN_TOKENS) and the wasm-vs-native A/B (grammar_ab.rs) both do this, and the A/B's ceiling mutation survived while its floor mutation went red. That is the pattern to copy.What closing this looks like
MIXED_FLEET, and bound latency and throughput in the mixed-load section.Related
#109 (the crons fire; their weekly jobs skip — same family: a gate that never executes), #113 (the #84 cost band was blessed on a loaded box and needs re-blessing isolated), #45 (generation-aware ratchets), #41 (scale ceilings).
#![cfg(unix)]file-wide, so its properties are ungraded on the Windows we ship #117EMBEDDED_DISPATCH_SEMANTICS_VERSION = 0, so no file can carry two producers and #77's criterion 2 is unexercisable #119Fixed — and the headline is that we were publishing a false number to operators.
plugin enable's disclosed figure was wrong, and wrong in the one direction it may not beMEASURED_LOCK_NS_PER_GENERATION_ROW = 4000is the constantcode-index plugin enablediscloses to operators. Measured at the scale it publishes, on an idle box (load 1.44 → 1.62), one process, four sizes:The recorded 2.5–3.0 band reproduced. The two claims built on it did not:
Raised to 6 000 by the file's own sanctioned procedure — its failure text says "re-measure the table and move the constant with it" — with the 100k row, the knee, the contended figures and the conditions now in
promotion.rs. Deliberately not sized for the saturated 9 380, with the reason written down.And the fixture existed all along. The comment saying a 100k-file shape was unbuildable rested on a recorded "126 s to index 8 000 files, superlinear". Re-measured idle: 0.65 / 3.5 / 8.1 s for 500/2 000/8 000, 133 s for 100 000 — roughly linear and 15× faster than recorded. That stale number was the entire argument for why the seven-second figure had to stay an extrapolation.
Rollback latency, previously absent, is now measured and bounded — which turns
promotion.rs's structural claim ("the same transaction with the generations swapped") into a measurement: rollback tracks promotion within 10% at every size and is the cheaper of the two.Mechanism 2: the ceiling that could not fail
WARM_ROUND_TRIP_CEILING24.5ms exceeds 5ms. At 100 ms this passes.WARM_ROUND_TRIP_FLOOR39ns is UNDER the floor. The ceiling read greener as the harness broke.COLD_FIRST_REQUEST_CEILINGMIXED_TAIL_OVER_MEDIAN_CEILINGMIXED_WALL_OVER_REQUESTS_CEILINGMIXED_WORKER_CPU_OVER_WALLceiling/floor/procoffsets → under floorBUILTIN_STARVATION_CEILINGThe warm ceiling's proof is now self-contained and runs per push: the table prints both regressions its own doc names — grammar JIT 15.0 ms, spawn+first 18.0 ms — and asserts neither breaches 100 ms while both breach 5 ms.
A builtin is now in the mixed fleet (native
tree-sitter-rustparse plus full-tree walk on its own thread), so starvation is finally a statement about concurrency rather than about four wasm packages.Three results recorded rather than smoothed over
minas denominator. The measurement is written at the call site.BUILTIN_STARVATION_CEILING = 4.0SURVIVED a real starvation injection at 3.21×. Tightened to 2.5.MIXED_WORKER_CPU_OVER_WALL_FLOORdoes not catch an unreaped fleet — deletingretire_all()read 0.52 and passed, becauseRETIRE_EVERYhas already reaped most of the CPU. A floor tight enough (0.60 against a 0.70 observation) would trip on a contended nightly. The doc's claim was narrowed to what was measured, rather than the bound tightened to what would be nice.Honestly unsettable, stated plainly
COLD_FIRST_REQUEST_CEILINGcannot honestly catch a 2× cold-path regression on this hardware — 83% of the cold path is cranelift JIT ofgrammar.wasm(15.0 of 18.0 ms), which varies several-fold with machine, grammar and wasmtime version. A bound tight enough to see a doubling would be a bound on the runner. It catches an extra compile or process, not a slower one, and that is written into the constant.MIXED_TAIL_OVER_MEDIAN_CEILINGhas only 1.7× headroom over the worst of five observations — named in the doc as the least comfortable constant in the file, with 36 samples meaning "p99" is the max.CI
bench_promotion_lockandbench_read_epochadded to the nightlyplugin-path-costjob, registered inrelease_gate.rs::TIMING_GATES, pinned to--release --ignored --test-threads=1. Run 576 (workflow_dispatch, master): 13/13 green.Stated rather than glossed: the new steps could not themselves be dispatched, because a dispatch runs the ref's committed
ci.ymland these are uncommitted. They are verified by local release runs plus the source-shape gates only.Not done
collectdeletes rows a superseded generation owns, and in the total-carry case the bench is built around it owns none. The mirror fixture is written into the file as the next step.bench_cold_index,bench_watcher_latency,bench_find_references,bench_search_symbols. They carry absolute wall-clock bounds (120 s cold index, 1 500 ms watcher p95) never measured on the runner. Adding them blind, with no ability to dispatch, would add four unverified gates — the trap this issue is about. They belong in the change that can dispatch.One more mutation-method finding
A mutation applied to the wrong site and read as "survived":
replace(..., 1)onAtomicBool::new(false)hit an unrelated pre-existing occurrence 1 200 lines earlier. Caught only by printing the patched line. Line-anchored thereafter.Also:
cargo fmt --allis a concurrency hazard here — it reformats other lanes' in-flight files. Targetedrustfmton own files instead.