Synced from monorepo

Synced from monorepo

Changes:
- Workspace server: report `/ready` as failed with dwell on hub connect failure
- Refresh OIDC token for the Grok agent in the shell
- ACP terminal output recorder
- Cross-platform provider auth commands in the shell
- Default `/resume` to Grok sessions with a hint for hidden external sessions
- Resume sessions by title with `--resume`
- Limit app-builder archive size
- Data-driven tag labels for slash commands
- Doctor fixes for tmux
- Custom provider gateways and subprocess environment policy in the shell
- `/tutorial` — opt-in onboarding tour of Grok Build
- Soft and required CLI version checks in the shell
- Privacy banner env overrides survive live settings updates
- Add remote flag to override the image-edit model
- Return profile fields from auth info even when the access token is expired
- Add edit control on queued prompt rows
- Keep fail-closed policy when clearing orphans with no team
- Setting to disable the Ctrl+Space/F8 voice shortcut
- Pass `--raw` to pw-record so Linux dictation works on older PipeWire
- Validate git URLs when adding marketplace entries
- Stop shipping stale tool-doc parameter and tool names
- Re-point dashboard attach after `/fork` only when the parent was attached
- Surface Grok Computer media-generation results as file-path chunks
- Clear web background-task tray on kill and keep the task description
- Show privacy upsell banner in agent view until acted on
- Add tools-server client callback surface
- Protect persistent global hook sources

Source-Revision: 95d84f443eddcbed6cbfd6eed22e2eafe6b3939d
This commit is contained in:
grokkybara[bot] 2026-07-23 17:12:33 +00:00
commit 69f0ba880a
286 changed files with 22939 additions and 9624 deletions

View file

@ -335,6 +335,8 @@ pub fn test_sampler_config(
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
query_params: Default::default(),
env_http_headers: Default::default(),
context_window: 256_000,
client_version: None,
force_http1: false,

View file

@ -1355,6 +1355,155 @@ async fn logout_clears_team_config() {
);
}
/// Seed on-disk fail_closed policy for clear_orphan keep tests.
/// `with_managed_files` writes managed_config + sig sidecars.
/// `with_marker` stamps a fail_closed sync marker for team-ms-fail-closed.
fn seed_fail_closed_orphan_artifacts(
home: &std::path::Path,
with_managed_files: bool,
with_marker: bool,
) {
if with_managed_files {
std::fs::write(home.join("managed_config.toml"), TEAM_MANAGED).unwrap();
std::fs::write(home.join("managed_config.sig.json"), r#"{"key_id":"v1"}"#).unwrap();
std::fs::write(home.join("managed_identity.sig.json"), r#"{"key_id":"v1"}"#).unwrap();
}
std::fs::write(
home.join("requirements.toml"),
format!("fail_closed = true\n{TEAM_REQUIREMENTS}"),
)
.unwrap();
if with_marker {
xai_grok_shell::config::mark_managed_config_synced(xai_grok_shell::config::SyncMarker {
principal: Some("team-ms-fail-closed"),
had_managed_config: with_managed_files,
had_requirements: true,
key_fingerprint: None,
fail_closed: true,
});
}
}
/// fail_closed escape fix: personal (User) auth with leftover MS fail_closed
/// artifacts must NOT be wiped by `clear_orphan` — that was the offline
/// switch-to-personal escape (managed files deleted, session ALLOW unrestricted).
#[test]
#[serial]
fn clear_orphan_keeps_fail_closed_when_switched_to_personal() {
let home = test_home().clone();
reset(&home);
seed_fail_closed_orphan_artifacts(&home, true, true);
// Personal User principal (no team_id) — the escape repro.
let scope = xai_grok_shell::auth::GrokComConfig::default().auth_scope();
let auth = serde_json::json!({
scope: {
"key": "personal-token",
"auth_mode": "oidc",
"create_time": "2026-01-01T00:00:00Z",
"expires_at": FAR_FUTURE,
"user_id": "user-1",
}
});
std::fs::write(home.join("auth.json"), auth.to_string()).unwrap();
xai_grok_shell::managed_config::clear_orphan();
assert!(
home.join("requirements.toml").exists(),
"fail_closed requirements must survive personal identity switch"
);
assert!(
home.join("managed_config.toml").exists(),
"fail_closed managed_config must survive personal identity switch"
);
assert!(
home.join("managed_config.sig.json").exists(),
"sig sidecar must survive personal identity switch under fail_closed"
);
assert!(
home.join("managed_config_cache.json").exists(),
"fail_closed marker must survive personal identity switch"
);
}
/// Signed-out logout with fail_closed still keeps policy (same as personal switch).
#[test]
#[serial]
fn clear_orphan_keeps_fail_closed_when_signed_out() {
let home = test_home().clone();
reset(&home);
seed_fail_closed_orphan_artifacts(&home, false, true);
// No auth.json = signed out.
xai_grok_shell::managed_config::clear_orphan();
assert!(
home.join("requirements.toml").exists(),
"signed-out must not wipe fail_closed requirements"
);
assert!(
home.join("managed_config_cache.json").exists(),
"signed-out must not wipe fail_closed marker"
);
}
/// Marker stripped but requirements still say fail_closed = true: still keep.
#[test]
#[serial]
fn clear_orphan_keeps_fail_closed_requirements_without_marker() {
let home = test_home().clone();
reset(&home);
seed_fail_closed_orphan_artifacts(&home, false, false);
// No marker, no team auth.
xai_grok_shell::managed_config::clear_orphan();
assert!(
home.join("requirements.toml").exists(),
"on-disk fail_closed requirements must be kept even without a marker"
);
}
/// Unreadable requirements (PermissionDenied) with no fail_closed marker must
/// still keep artifacts — cannot confirm disarmed, so clear_orphan must not wipe.
#[test]
#[serial]
#[cfg(unix)]
fn clear_orphan_keeps_unreadable_requirements_without_marker() {
use std::os::unix::fs::PermissionsExt;
let home = test_home().clone();
reset(&home);
seed_fail_closed_orphan_artifacts(&home, true, false);
// No fail_closed marker; requirements exist with fail_closed = true but will
// be made unreadable so the flag cannot be parsed.
let req = home.join("requirements.toml");
std::fs::set_permissions(&req, std::fs::Permissions::from_mode(0o000)).unwrap();
struct RestorePerms<'a>(&'a std::path::Path);
impl Drop for RestorePerms<'_> {
fn drop(&mut self) {
let _ = std::fs::set_permissions(self.0, std::fs::Permissions::from_mode(0o600));
}
}
let _restore = RestorePerms(&req);
assert!(
xai_grok_config::fail_closed_policy_armed_at(&home),
"unreadable requirements must arm fail_closed"
);
xai_grok_shell::managed_config::clear_orphan();
// Restore so exists() / cleanup can inspect the tree.
drop(_restore);
assert!(
home.join("requirements.toml").exists(),
"unreadable requirements must not be wiped by clear_orphan"
);
assert!(
home.join("managed_config.toml").exists(),
"managed_config must survive when requirements are unreadable"
);
}
/// An expired token for a still-signed-in team is not a logout: cold-start
/// tokens are routinely expired before refresh, so the clear is expiry-agnostic.
#[test]