sequenceDiagram
    autonumber

    participant User as User / Dashboard
    participant K8sAPI as Kubernetes API<br/>6443/TCP HTTPS
    participant Webhook as odh-notebook-controller<br/>Webhook 8443/TCP HTTPS
    participant KFCtrl as kf-notebook-controller
    participant ODHCtrl as odh-notebook-controller
    participant Route as OpenShift Route<br/>443/TCP HTTPS
    participant OAuthProxy as oauth-proxy sidecar<br/>8443/TCP HTTPS
    participant OAuthServer as OpenShift OAuth Server<br/>443/TCP HTTPS
    participant Jupyter as Jupyter Notebook<br/>8888/TCP HTTP
    participant Culler as CullingReconciler

    rect rgb(230, 245, 255)
        Note over User,ODHCtrl: Flow 1: Notebook Creation (OAuth-Enabled)
        User->>K8sAPI: POST Notebook CR<br/>HTTPS TLS 1.2+ / Bearer Token
        K8sAPI->>Webhook: Mutating admission<br/>HTTPS TLS (service CA) / API server cert
        Note right of Webhook: Injects oauth-proxy sidecar,<br/>OAuth annotations, TLS volumes
        Webhook->>K8sAPI: Return mutated Notebook<br/>HTTPS TLS 1.2+ / SA token
        K8sAPI-->>KFCtrl: Watch event (Notebook created)
        KFCtrl->>K8sAPI: Create StatefulSet (replicas=1)<br/>HTTPS TLS 1.2+ / SA token
        KFCtrl->>K8sAPI: Create ClusterIP Service<br/>HTTPS TLS 1.2+ / SA token
        K8sAPI-->>ODHCtrl: Watch event (Notebook created)
        ODHCtrl->>K8sAPI: Create Route (re-encrypt TLS)<br/>HTTPS TLS 1.2+ / SA token
        ODHCtrl->>K8sAPI: Create OAuthClient<br/>HTTPS TLS 1.2+ / SA token
        ODHCtrl->>K8sAPI: Create NetworkPolicy<br/>HTTPS TLS 1.2+ / SA token
        ODHCtrl->>K8sAPI: Create OAuth Secrets<br/>HTTPS TLS 1.2+ / SA token
        ODHCtrl->>K8sAPI: Create workbench-trusted-ca-bundle<br/>HTTPS TLS 1.2+ / SA token
    end

    rect rgb(255, 245, 230)
        Note over User,Jupyter: Flow 2: Notebook Access (OAuth)
        User->>Route: GET https://{notebook-route}<br/>HTTPS TLS 1.2+ / None
        Route->>OAuthProxy: Forward (re-encrypt TLS)<br/>HTTPS / OAuth token
        OAuthProxy->>OAuthServer: Validate token / authorize<br/>HTTPS TLS 1.2+ / OAuth client creds
        OAuthServer-->>OAuthProxy: Token valid + SAR check<br/>(verb=get, resource=notebooks)
        OAuthProxy->>Jupyter: Forward request<br/>HTTP 8888 / None (localhost, pre-authed)
        Jupyter-->>OAuthProxy: Notebook response
        OAuthProxy-->>Route: Response (re-encrypt)
        Route-->>User: Notebook UI response
    end

    rect rgb(255, 235, 235)
        Note over Culler,Jupyter: Flow 3: Idle Notebook Culling
        loop Every IDLENESS_CHECK_PERIOD (default 1 min)
            Culler->>Jupyter: GET /api/kernels<br/>HTTP 8888/TCP / None (in-cluster)
            Jupyter-->>Culler: Kernel list + last_activity
            Culler->>Jupyter: GET /api/terminals<br/>HTTP 8888/TCP / None (in-cluster)
            Jupyter-->>Culler: Terminal list + last_activity
        end
        Note right of Culler: If idle > CULL_IDLE_TIME (default 1440 min)
        Culler->>K8sAPI: Set kubeflow-resource-stopped annotation<br/>HTTPS TLS 1.2+ / SA token
        KFCtrl->>K8sAPI: Set StatefulSet replicas=0<br/>HTTPS TLS 1.2+ / SA token
    end
