flowchart TD
A["User clicks Pick threshold codelens on avg check"] --> B["LSP runs prepare_session"]
B --> C["family_for avg returns RANGE"]
C --> D["TuningSession sent with existing_must_be_key"]
D --> E["Webview boots: pickRenderer range returns rangeRenderer"]
E --> F["renderBody emits chart slot, mode toggle, rangeInner, verdict"]
F --> G["bootRangeRenderer wires inputs and toggle"]
G --> H{"mode toggle position"}
H -->|"range"| I["lowerInput, upperInput, paired quick-picks visible"]
H -->|"one_sided"| J["primaryInput, single quick-picks, operator radios"]
I --> K["User adjusts upper to 1050"]
J --> L["User picks operator lte and value 100"]
K --> M["scheduleRecompute fires after 100ms"]
L --> M
M --> N["computeDraft returns draftConfig, verdict, traces, mustBeKey"]
N --> O["repaintChart, repaintVerdict, repaintDiff"]
O --> P["User clicks Apply"]
P --> Q["host posts apply with draftConfig"]
Q --> R["per-check snapshot guard validates"]
R --> S{"draft_config kind"}
S -->|"RangeConfig"| T["apply_draft_to_check_block, Range branch"]
S -->|"FlatThresholdConfig and family is RANGE"| T
T --> U["clear_sibling_range_keys removes the five other Range keys"]
U --> V["flat-key splice writes the kept key on one line"]
V --> W["Range mode writes mustBeBetween flow mapping"]
V --> X["One-sided writes single mustBe operator"]
W --> Y["host posts applied ok true; panel reloads session"]
X --> YsequenceDiagram
actor User
participant Editor as VSCode editor
participant LSP as Turbine LSP host
participant Panel as Pick Threshold panel
participant Boot as bootRangeRenderer
participant Apply as apply_draft_to_check_block
User->>Editor: click Pick threshold codelens on avg check
Editor->>LSP: tune.prepareSession uri checkName
LSP->>LSP: family_for avg returns RANGE
LSP->>LSP: snapshot_check uri check
LSP->>Panel: TuningSession with existingMustBeKey
Panel->>Panel: pickRenderer range, renderBody
Panel->>Boot: boot wires inputs and toggle
Boot->>Boot: runRecompute first tick
Boot->>Panel: computeDraft returns draftConfig verdict traces
Panel->>User: chart band, verdict 88 of 90 days fell in the band
User->>Boot: drag upperSlider to 1050
Boot->>Boot: scheduleRecompute debounce 100ms
Boot->>Panel: computeDraft new tick
Panel->>User: chart band redraws, diff updates to mustBeBetween mapping
User->>Boot: toggle to One-sided
Boot->>Boot: swap rangeInner innerHTML, re-bind listeners
Boot->>Panel: computeDraft for one_sided mode
Panel->>User: single hline chart, diff shows mustBeLessThanOrEqual 100
User->>Panel: click Apply
Panel->>LSP: apply draftConfig flat lte 100
LSP->>LSP: per-check snapshot guard validates
LSP->>Apply: apply_draft_to_check_block
Apply->>Apply: clear_sibling_range_keys keep mustBeLessThanOrEqual
Apply->>Apply: flat-key splice writes mustBeLessThanOrEqual 100
LSP->>Panel: applied ok true
Panel->>User: success banner, diff returns to no changeclassDiagram
class FamilyRenderer {
<<Protocol>>
+family : ThresholdFamily
+renderBody(ctx) string
}
class FamilyRenderContext {
<<dataclass>>
+session : TuningSession
+checkType : string
+family : ThresholdFamily
+existingMustBeKey : MustBeKey
+savedDraft : object
}
class rangeRenderer {
+family : string
+renderBody(ctx) string
}
class RangeQuickPick {
+label : string
+lower : number
+upper : number
}
class QuickPick {
+label : string
+value : number
}
class RangeConfig {
<<pydantic>>
+lower : float
+upper : float
+negate : bool
}
class FlatThresholdConfig {
<<dataclass>>
+value : float
+operator : ThresholdOperator
}
class BetweenRange {
<<pydantic>>
+greater_than : float
+greater_than_or_equal : float
+less_than : float
+less_than_or_equal : float
}
class VerdictText {
<<dataclass>>
+headline : string
+rate : string
}
class CheckDef {
<<dataclass>>
+check_type : string
+source_range : TextRange
}
class clearSiblingRangeKeys {
<<function>>
+call(content, line, indent, keep) str
}
class formatRangeYaml {
<<function>>
+call(config) dict
}
class rangeRate {
<<function>>
+call(alerts, days) str
}
class verdictText {
<<function>>
+call(family, alerts, days) VerdictText
}
rangeRenderer ..|> FamilyRenderer
rangeRenderer ..> FamilyRenderContext : reads
rangeRenderer ..> RangeQuickPick : emits
rangeRenderer ..> QuickPick : emits one_sided
RangeConfig ..> BetweenRange : serializes to
FlatThresholdConfig ..> CheckDef : applied to
RangeConfig ..> CheckDef : applied to
rangeRenderer ..> VerdictText : produces
formatRangeYaml ..> RangeConfig : consumes
clearSiblingRangeKeys ..> CheckDef : pre-cleans
verdictText ..> rangeRate : delegates on RANGE