Skip to content

vps2: resolve per-view state without persisting/exposing secret-bearing provider settings, and load it before the first state post #2152

Open

Description

@easonLiangWorldedtech

Context

Two CodeRabbit pre-merge errors on the vps2 view-state series' owner unit (#1546, F1a) describe the same architectural debt: viewLocalState does not exist on upstream main (git grep viewLocalState upstream/main is empty), so the series introduces it, and the owner unit is the right place to fix it once instead of in each replayed branch.

1. Secret-bearing provider settings in the view-local state (Security Boundaries)

ClineProvider stores full provider settings in viewLocalState.apiConfiguration (profile loading copies getProfile()), and the public ClineProvider.getValues() result can therefore carry nested provider configurations (including secrets) beyond the sidebar they belong to. The review asks to remove secret-bearing settings from the public getValues() result, or to recursively sanitize every nested provider configuration before API.getConfiguration() returns it, and to add a regression test that activates a profile.

2. Late async loadViewState() in the constructor (Persistence Integrity)

The provider starts void this.loadViewState() in its constructor, but loadViewState() returns early because the stable view identity is not known until the webview launch message arrives; the state is therefore loaded later than the first postStateToWebview(). The review's resolution: send the stable view identity in the webview launch message, await provider.setViewStateId(message.viewStateId) before the first postStateToWebview(), and overlay viewLocalState onto getState() for mode, currentApiConfigName, etc.

Why a follow-up issue instead of an in-PR patch

  • Both changes move the series baseline (viewLocalState is shared by all replay units); landing them in seven branches would produce seven divergent copies.
  • Fix 1 changes the shape of a public provider API (getValues()) and needs a decision about where per-view overrides are resolved (store the profile NAME and resolve at read time vs store settings and sanitize on read).
  • Fix 2 changes the launch/state ordering that the claim-token work in security: bind view-state ids to a host-minted claim token (cross-view secret disclosure) #2151 already touches; the two should be designed together.

Acceptance criteria

  • Decide the overlay model: per-view state stores the profile name (and mode/selection) only, or getValues()/API.getConfiguration() sanitizes nested provider settings before exposing them.
  • Regression test: activate a profile in one view and assert that getValues()/API.getConfiguration() for another view (or the shared path) carries no secret-bearing nested configuration.
  • The stable view id is known before the first postStateToWebview() (launch-handler await setViewStateId(...) before the post), and loadViewState() no longer races the constructor.
  • Test: the first posted state after launch already reflects the persisted per-view state for mode/currentApiConfigName.
  • Replayed units inherit the fix via refresh (no second implementation).

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions