flowchart TD
  User["User clicks Run Validate Codelens"] --> Cmd["VS Code command turbine.runValidate"]
  Cmd --> Disp["dispatchOnboardingAction kind=run_validate"]
  Disp --> Cmds["vscode.commands.executeCommand"]
  Disp --> Note["TurbineClient.actionInvoked"]
  Cmds --> Req["LSP request turbine/validateSchema"]
  Req --> VS["ValidateSchema.run_with_snapshot"]
  VS --> Pub1["tour_service.publish_action_invoked run_validate"]
  Note --> Handler["OnboardingActionInvoked handler"]
  Handler --> Pub2["tour_service.publish_action_invoked run_validate"]
  Pub1 --> Stream["ActionInvokedStream.publish"]
  Pub2 --> Stream
  Stream --> Watcher["ActionFired watcher subscribed for run_validate"]
  Watcher --> Edge["false to true edge"]
  Edge --> Bus["EventBus.publish StepCompleted"]
  Bus --> Notify["server notify_step_completed"]
  Notify --> Wire["turbine/onboarding/stepCompleted notification"]
  Wire --> Engine["tour-engine receives stepCompleted"]
  Engine --> Latch["unlockedSteps.add stepId"]
  Latch --> Panel["post tour-step-unlocked to panel"]
  Panel --> View["tour-view re-renders"]
  View --> Enabled["Next button enabled"]
sequenceDiagram
  actor User
  participant Panel as Onboarding Panel webview
  participant Engine as TourEngine extension
  participant Disp as dispatchOnboardingAction
  participant Client as TurbineClient
  participant Service as tour_service
  participant Stream as ActionInvokedStream
  participant W as ActionFired watcher
  participant Bus as EventBus
  User->>Panel: open tour at run-validate step
  Panel->>Engine: tour-next-step
  Engine->>Client: watchStep tourId stepId
  Client->>Service: watch_step
  Service->>W: completion.watch ctx
  W->>Stream: subscribe handler
  W->>Service: returns Watcher
  Note over Service: gated=true sent on stepDto
  User->>Panel: clicks Run Validate Codelens chip
  Panel->>Disp: kind=run_validate command args
  Disp->>Client: actionInvoked tourId stepId run_validate
  Disp->>Client: validateSchema uri
  Client->>Service: actionInvoked routed to publish_action_invoked
  Client->>Service: validateSchema also calls publish_action_invoked
  Service->>Stream: publish run_validate
  Stream->>W: handler kind=run_validate
  W->>Bus: publish StepCompleted
  Bus->>Service: notify_step_completed
  Service->>Client: notification turbine/onboarding/stepCompleted
  Client->>Engine: stepCompleted tourId stepId
  Engine->>Engine: unlockedSteps.add stepId
  Engine->>Panel: tour-step-unlocked
  Panel->>User: Next button enabled
classDiagram
  class StepCompletion {
    <<Protocol>>
    +watch(ctx) Watcher
  }
  class Watcher {
    <<Protocol>>
    +stop()
  }
  class WatchContext {
    <<dataclass>>
    +tour_id : str
    +step_id : str
    +yaml_parser : YamlParser
    +diagnostics : DiagnosticSource
    +introspection_source : IntrospectionSource
    +scheduler : Scheduler
    +event_bus : EventBus
    +action_invoked_stream : ActionInvokedStream
    +translate_uri : Callable
    +buffers : Mapping
  }
  class FieldEquals {
    <<dataclass>>
    +file : str
    +yaml_path : str
    +expected : str
    +watch(ctx) Watcher
  }
  class FieldPresent {
    <<dataclass>>
    +file : str
    +yaml_path : str
    +watch(ctx) Watcher
  }
  class DiagnosticCleared {
    <<dataclass>>
    +file : str
    +code : str
    +watch(ctx) Watcher
  }
  class IntrospectionPopulated {
    <<dataclass>>
    +watch(ctx) Watcher
  }
  class ActionFired {
    <<dataclass>>
    +kind : StepActionKind
    +watch(ctx) Watcher
  }
  class Timer {
    <<dataclass>>
    +ms : int
    +watch(ctx) Watcher
  }
  class StateBasedWatcher {
    +stop()
  }
  class TimerWatcher {
    +stop()
  }
  class ActionFiredWatcher {
    +stop()
  }
  class Step {
    <<dataclass>>
    +id : str
    +completion : StepCompletion
    +action : StepAction
    +skip : SkipAction
  }
  class TourService {
    +watch_step(tour_id, step_id)
    +unwatch_step()
    +publish_action_invoked(kind)
  }
  StepCompletion <|.. FieldEquals
  StepCompletion <|.. FieldPresent
  StepCompletion <|.. DiagnosticCleared
  StepCompletion <|.. IntrospectionPopulated
  StepCompletion <|.. ActionFired
  StepCompletion <|.. Timer
  Watcher <|.. StateBasedWatcher
  Watcher <|.. TimerWatcher
  Watcher <|.. ActionFiredWatcher
  FieldEquals ..> StateBasedWatcher : returns
  FieldPresent ..> StateBasedWatcher : returns
  DiagnosticCleared ..> StateBasedWatcher : returns
  IntrospectionPopulated ..> StateBasedWatcher : returns
  Timer ..> TimerWatcher : returns
  ActionFired ..> ActionFiredWatcher : returns
  Step --> StepCompletion : has-a
  TourService --> Step : iterates
  TourService --> WatchContext : builds
  TourService --> Watcher : stores active