diff --git a/.github/fork-features.yml b/.github/fork-features.yml index d95b2f8bf60b..a302f562c9f2 100644 --- a/.github/fork-features.yml +++ b/.github/fork-features.yml @@ -3114,16 +3114,16 @@ features: retire_when: Upstream preserves project scope across sidebar state and every new-thread entry point. - id: provider-auto-default - title: Start new threads in Auto where the provider reviews actions + title: Apply an Auto default only where the provider reviews actions status: maintained prs: [928, 930] invariants: - - The built-in default permission mode for new threads is Auto. Configs that never chose a mode, including those that kept the old Full access default, use it. + - The built-in default permission mode for new threads stays Full access, as upstream; Auto as the default is the user's choice. - With Auto as the default, a new thread on a provider whose snapshot does not report its own Auto reviewer (reviewsAutoMode) starts in Full access; Claude, Codex, and Grok report one. An unloaded snapshot or an older server counts as no reviewer. - Web and mobile drafts follow their selected provider until the user picks a mode; the server's bootstrap thread uses the same resolution. Picking Auto for one thread keeps Auto on every provider. - The provider canary's auto scenario fails a release whose Auto turn asks for approval of a routine workspace write, or whose provider does not report applying Auto; providers without reviewsAutoMode skip it. - provider.turn.completed reports approvalRequests, the command, file, and permission approvals the turn raised, alongside its runtimeMode. - rationale: Auto is the safer default where a reviewer approves routine actions, but on a provider without one Auto asks about every action, which would stall threads nobody is watching. + rationale: Auto is the safer default where a reviewer approves routine actions, but on a provider without one Auto asks about every action, which would stall threads nobody is watching. Making Auto the built-in default for everyone was withdrawn before release; approval counts from opted-in users are meant to inform that decision. implementation_paths: - apps/mobile/src/features/threads/new-task-flow-provider.tsx - apps/server/scripts/verify-provider-live.ts @@ -3134,7 +3134,6 @@ features: - apps/web/src/components/ChatView.tsx - packages/contracts/src/providerPolicy.ts - packages/contracts/src/server.ts - - packages/contracts/src/settings.ts - packages/provider-core/src/server/snapshotProbe.ts - packages/provider-grok/src/server/status.ts upstream_paths: @@ -3142,14 +3141,13 @@ features: - apps/server/src/orchestration-v2/ProviderEventIngestor.ts - apps/web/src/components/ChatView.tsx - packages/contracts/src/providerPolicy.ts - - packages/contracts/src/settings.ts tests: - apps/server/src/orchestration-v2/ProviderEventIngestor.test.ts - packages/contracts/src/settings.test.ts upstream: status: unassessed tracking: [] - retire_when: Upstream defaults new threads to Auto on providers with their own reviewer, or styal returns to a Full access default. + retire_when: Upstream starts new threads in Full access on providers without their own reviewer when Auto is the default. - id: provider-auto-updates title: styal managed updates install canary-verified provider versions diff --git a/docs/user/permission-modes.md b/docs/user/permission-modes.md index c658e5985f6f..5628a97e0f39 100644 --- a/docs/user/permission-modes.md +++ b/docs/user/permission-modes.md @@ -5,7 +5,7 @@ composer; it applies to that thread. Set the default for new threads in **Settings → General → New threads → Permissions**. Projects can override the environment default. New threads use this setting rather than the -mode of the thread you were viewing. The initial default is **Auto**. With **Auto** as the +mode of the thread you were viewing. The initial default is **Full access**. With **Auto** as the default, new threads on a provider without automatic review, such as OpenCode or Antigravity, start in **Full access** instead of asking about every action; choose **Auto** in the composer to keep it for one thread. Existing threads and modes you choose in a draft keep their permissions. diff --git a/docs/user/styal-differences.md b/docs/user/styal-differences.md index e33e3dd30661..65cd0ccc6af5 100644 --- a/docs/user/styal-differences.md +++ b/docs/user/styal-differences.md @@ -65,10 +65,10 @@ works. This overview focuses on desktop and web; the mobile app is a work in pro [revision adb0420](https://github.com/pingdotgg/t3code/tree/adb04202b25c1c45255e76be9f03f0b346b9c5c4). [Send while the agent is working](./composer.md#send-while-the-agent-is-working). -- **New threads default to Auto.** Claude, Codex, and Grok threads start in **Auto**, where the - provider's own reviewer approves routine actions and asks about the rest. Providers without - automatic review start in **Full access**. A default you chose yourself still applies. T3 Code - starts new threads in **Full access** as of +- **An Auto default fits each provider.** With **Auto** as the default for new threads, Claude, + Codex, and Grok threads start in **Auto**, where the provider's own reviewer approves routine + actions, and providers without automatic review start in **Full access** instead of asking about + every action. In T3 Code an Auto default makes those providers ask, as of [revision 30afc56](https://github.com/pingdotgg/t3code/tree/30afc56076c86580d5d913897280bea660d44c79). [Permission modes](./permission-modes.md). diff --git a/packages/contracts/src/providerPolicy.ts b/packages/contracts/src/providerPolicy.ts index 8db50c982714..b4bfbbc6a89f 100644 --- a/packages/contracts/src/providerPolicy.ts +++ b/packages/contracts/src/providerPolicy.ts @@ -31,13 +31,6 @@ export const RuntimeMode = Schema.Literals([ export type RuntimeMode = typeof RuntimeMode.Type; export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access"; -/** - * The built-in default for new threads. A provider whose Auto mode has no - * reviewer of its own starts in Full access instead; see - * `resolveNewThreadRuntimeMode`. - */ -export const DEFAULT_NEW_THREAD_RUNTIME_MODE: RuntimeMode = "auto"; - /** * The mode a new thread starts in from the default-permissions setting. Auto * relies on the provider's own reviewer to approve actions; a provider without diff --git a/packages/contracts/src/settings.test.ts b/packages/contracts/src/settings.test.ts index 05a811bc6a99..d832ca5d72aa 100644 --- a/packages/contracts/src/settings.test.ts +++ b/packages/contracts/src/settings.test.ts @@ -133,9 +133,9 @@ describe("ClientSettings rich text composer", () => { }); describe("ServerSettings default permissions", () => { - it("defaults settings that never chose a mode to Auto", () => { - expect(decodeServerSettings({}).defaultRuntimeMode).toBe("auto"); - expect(DEFAULT_SERVER_SETTINGS.defaultRuntimeMode).toBe("auto"); + it("keeps full access for settings saved before a default was configured", () => { + expect(decodeServerSettings({}).defaultRuntimeMode).toBe("full-access"); + expect(DEFAULT_SERVER_SETTINGS.defaultRuntimeMode).toBe("full-access"); }); it("starts a default of Auto in Full access when the provider has no Auto reviewer", () => { diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts index a1ec05ed30ff..aa4d17acd11b 100644 --- a/packages/contracts/src/settings.ts +++ b/packages/contracts/src/settings.ts @@ -31,7 +31,7 @@ import { } from "./model.ts"; import { ModelSelection } from "./modelSelection.ts"; import { ProjectScript, type ProjectMutation } from "./project.ts"; -import { DEFAULT_NEW_THREAD_RUNTIME_MODE, RuntimeMode } from "./providerPolicy.ts"; +import { DEFAULT_RUNTIME_MODE, RuntimeMode } from "./providerPolicy.ts"; import { BrowserProfile, BrowserProfileId, DEFAULT_BROWSER_PROFILE_ID } from "./browserProfile.ts"; import { DEFAULT_PREVIEW_APPEARANCE, @@ -1195,14 +1195,8 @@ export const ServerSettings = Schema.Struct({ defaultModelSelection: Schema.NullOr(ModelSelection).pipe( Schema.withDecodingDefault(Effect.succeed(null)), ), - /** - * The mode new threads start in, resolved per provider by - * `resolveNewThreadRuntimeMode`. The old built-in Full access was never - * persisted (defaults are stripped on write), so configs that never chose a - * mode move to the new built-in. - */ defaultRuntimeMode: RuntimeMode.pipe( - Schema.withDecodingDefault(Effect.succeed(DEFAULT_NEW_THREAD_RUNTIME_MODE)), + Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE)), ), /** * Per-project overrides of the keys in `PROJECT_SCOPED_SERVER_SETTING_KEYS`.