Skip to content

[multi-team P3a-1] Scope the AI autonomy accessor to the window's team - #15443

Merged
IsaiahWitzke merged 11 commits into
masterfrom
factory/multi-team-p3a-ai-autonomy
Aug 23, 2026
Merged

[multi-team P3a-1] Scope the AI autonomy accessor to the window's team#15443
IsaiahWitzke merged 11 commits into
masterfrom
factory/multi-team-p3a-ai-autonomy

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

crux of pr is making ai_autonomy_settings & is_ai_autonomy_allowed require a team scope...

lots of threading through is then required: view context/handle -> exchange for team context -> feed into ai autonomy settings

@cla-bot cla-bot Bot added the cla-signed label Aug 22, 2026
@warp-agent-staging

Copy link
Copy Markdown
Contributor Author

This PR was generated with Warp.

Comment @warp-factory on this PR to send it follow-up work.

View run View conversation

@warp-agent-staging
warp-agent-staging Bot marked this pull request as ready for review August 22, 2026 08:24

@warp-agent-staging warp-agent-staging Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

P3a-1 scopes the AI autonomy accessor to the window's team, keeping AiAutonomySettings as the effective-policy shape and lowering the team shape into it rather than pushing EnforceableSetting/SplitListSetting through ~25 call sites. The architecture was verified independently against both the server merge and the client conversion and is sound; the defects found are going back to the author. One question below needs your call rather than a fix.

Concerns

  • app/src/workspaces/user_workspaces.rs:1067-1090 — the new accessor spans every workspace where the old one read only the current one, and its two halves disagree about scope. is_ai_autonomy_allowed read current_workspace(); all_teams_allow_ai_autonomy iterates self.workspaces.iter().flat_map(|w| w.teams.iter()), so a team in a different workspace configuring nothing can now switch autonomy off for a user whose current workspace's team did configure it — a real behaviour change for multi-workspace members, which the PR body says does not exist and the tests do not cover. Meanwhile tier_allows_autonomy still reads current_workspace() alone, so entitlement is workspace-local while policy is global. The all-workspaces shape does mirror teams_allow_codebase_context, which the contract names as the reference, so it may be deliberate — but for a safety gate the two halves should agree, and which way they agree is your call.
  • Related, smaller: has_any_team() (user_workspaces.rs:1039-1044) also spans all workspaces while team_from_scopeteam_from_uid (:362-365) searches only the current one. So a user whose current workspace has no teams but who belongs to a team elsewhere never gets the workspace-layer fallback, even though for that workspace the settings genuinely are team-neutral. Worth settling on the same axis as the above.
  • Summary-level: the empty-allowlist hazard is reachable today, not only on a future data migration. Because the server merges allowlists by intersection, two admin layers with disjoint allowlists yield values: [] with both entry lists non-empty; the lowering reads that as "no override", and an allowlist is deny-by-default, so it becomes maximally permissive. Being fixed in this PR — flagged here only because the PR body currently states the opposite, and because it turns out StringListSettingInfo.isConfigured already exists on the wire for exactly this purpose but the client's vendored schema copy is stale.

Verdict

Checks: build pass, tests pass (104/104 local, 9/9 new), CI green except MacOS pending, visual proof n/a

Found: 0 critical, 4 important, 2 suggestions — the scope question above is yours; the rest are with the author.

warp-agent-staging Bot and others added 10 commits August 23, 2026 01:18
Migrate the AI autonomy settings accessor and the autonomy-allowed gate off
ambient workspace state, and reconcile the workspace and team settings shapes
so that call sites keep consuming one policy type.

`AiAutonomySettings` becomes the effective-policy shape both admin layers lower
into, with a `From<&TeamAiAutonomySettings>` conversion. The team wire shape's
`EnforceableSetting` / `SplitListSetting` structure records which admin layer
contributed a value, which is an admin-UI concern rather than policy, so it does
not survive the conversion.

`ai_autonomy_settings_for_scope` reads the scope's team, treats a scope with no
team as governed by no policy rather than substituting another team's, and falls
back to the workspace layer only for a user with no teams at all.

`is_ai_autonomy_allowed` becomes `all_teams_allow_ai_autonomy`: its only consumer
has no window anywhere in its call chain, so it reads across every team,
conservatively. The tier policy stays workspace-level, being billing entitlement.

Onboarding's autonomy-enforcement flag now resolves from the root view's handle
and refreshes on `WindowTeamChanged`, which it previously ignored. Applying
onboarding choices captures a scope for the write.
Also drops the remaining P0 dead-code markers on TeamScope, TeamContext,
team_context and new_for_test, each of which now has a real call site.
…ompile, and a non-discriminating test

The "the team wire shape cannot express an enforced-empty list" premise was
wrong. Allowlists merge by intersection server-side (util.IntersectLists), so
two admin layers with disjoint allowlists produce empty `values` while both
entry lists are populated. Reading only `values` treated that as no override,
which is the permissive answer to a deny-by-default setting and is reachable
by configuration today. SplitListSetting::is_configured now consults all three
lists. One case remains indistinguishable and needs the server's isConfigured.

all_teams_allow_ai_autonomy lowered the whole team shape to ask six is_some()
questions, compiling every org regex on a render and per-action path only to
discard it, and turning one malformed org regex into a report_error! per frame.
TeamAiAutonomySettings::configures_any_policy answers without lowering, and a
test locks the two implementations together.

The merged-values test used disjoint layers, where `values` and the layers
concatenated are the same list, so it could not detect the violation it
existed to catch. The layers now overlap.

Also: match UserWorkspacesEvent exhaustively per AGENTS.md rather than with a
wildcard, and refresh on TeamsChanged and CurrentWorkspaceChanged, which are
more common staleness than the window switch.
The lowered check ignores three fields, not two. computer_use is the likeliest
of them to drift: the lowering carries it into AiAutonomySettings, so it reads
as an omission from the check rather than a field the check has no view of.
Adding it to autonomy_allowed_by_policy previously left every test passing.

Also drops caller descriptions from the two new doc comments, per AGENTS.md.
Co-Authored-By: Warp <agent@warp.dev>
Co-Authored-By: Warp <agent@warp.dev>
@IsaiahWitzke
IsaiahWitzke force-pushed the factory/multi-team-p3a-ai-autonomy branch from 1acd835 to 2027abe Compare August 23, 2026 05:22
@IsaiahWitzke
IsaiahWitzke enabled auto-merge (squash) August 23, 2026 05:22
@IsaiahWitzke
IsaiahWitzke force-pushed the factory/multi-team-p3a-ai-autonomy branch from 2027abe to ec85be0 Compare August 23, 2026 05:42
@IsaiahWitzke
IsaiahWitzke merged commit 8e5bb1f into master Aug 23, 2026
41 of 43 checks passed
@IsaiahWitzke
IsaiahWitzke deleted the factory/multi-team-p3a-ai-autonomy branch August 23, 2026 06:15
warp-agent-staging Bot added a commit that referenced this pull request Aug 23, 2026
…indow's team

Squashed for rebase onto master post-#15443. See PR description for the
full account of the rework.
warp-agent-staging Bot added a commit that referenced this pull request Aug 23, 2026
…indow's team

Squashed for rebase onto master post-#15443. See PR description for the
full account of the rework.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants