Distinguish Guardian review threads from subagents (#40221)

## Why

Guardian reviews were reported with the generic `subagent` thread source, making them indistinguishable from other delegated threads in persisted metadata and analytics.

## What changed

- Add the `guardian_review` thread source to the core protocol and app-server schema.
- Assign it to Guardian reviewer sessions and propagate the configured source through turn metadata, rollouts, and analytics.
- Continue treating Guardian reviews like subagents for paginated history and trusted-provenance checks.

## Testing

- Cover protocol round trips, delegate source selection, emitted analytics, request metadata, and persisted rollout metadata.

GitOrigin-RevId: 07480c122715812874c9d3b48bb39fc5c86b2367
This commit is contained in:
Dylan Hurd authored and copyberry committed 2026-08-23 10:06:57 +00:00
1 parent 83d1fe0e67
commit c9b19deb09
16 files changed
+74 -28

No files matched your search

+7 -2
View File
@@ -229,12 +229,13 @@ async fn guardian_delegates_do_not_inherit_parent_extensions() {
.services
.extensions = Arc::new(extensions.build());
for (subagent_source, expected_thread_starts) in [
for (subagent_source, expected_thread_starts, expected_thread_source) in [
(
SubAgentSource::Other(crate::guardian::GUARDIAN_REVIEWER_NAME.to_string()),
0,
ThreadSource::GuardianReview,
),
(SubAgentSource::Review, 1),
(SubAgentSource::Review, 1, ThreadSource::Subagent),
] {
let mut config = parent_ctx.config.as_ref().clone();
config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);
@@ -263,6 +264,10 @@ async fn guardian_delegates_do_not_inherit_parent_extensions() {
expected_thread_starts
);
assert_eq!(thread_starts.load(Ordering::SeqCst), expected_thread_starts);
assert_eq!(
session.thread_config_snapshot().await.thread_source,
Some(expected_thread_source)
);
io.shutdown_and_wait()
.await
.expect("delegate session should shut down");