Persist Automation session provenance for session-list filtering - #337757
Ulugbek Abdullaev (ulugbekna) wants to merge 8 commits into
Conversation
Carry existing AHP automation origins from creation through persistence, listings, notifications, and client caches. Classify sessions from host-owned provenance instead of joining the client run ledger, with evidence-based backfill for retained host history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve Automation session provenance while integrating upstream catalogue metadata, protocol, and provider test changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Provenance backfill failures can break listings or restoration, discard metadata overlays, and leave a downgrade-recovery path dependent on retained run history.
Review effort: Balanced
Findings: None
What changed in this PR
Persists Agent Host Automation provenance so Sessions can reliably classify and filter Automation-created sessions without relying on run history.
Changes:
- Persists and recovers typed
SessionOriginthrough host storage and catalogs. - Propagates provenance through protocol, providers, state, and client caches.
- Filters Automation sessions from the main list and adds regression coverage.
| File | Description |
|---|---|
src/vs/sessions/contrib/sessions/test/browser/sessionsList.test.ts |
Tests list filtering and history opening. |
src/vs/sessions/contrib/providers/remoteAgentHost/test/browser/remoteAgentHostSessionsProvider.test.ts |
Tests remote cache persistence. |
src/vs/sessions/contrib/providers/agentHost/test/browser/localAgentHostSessionsProvider.test.ts |
Tests local origin propagation and hydration. |
src/vs/sessions/contrib/providers/agentHost/browser/localAgentHostSessionsProvider.ts |
Removes run-ledger classification. |
src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts |
Adapts and caches session origin. |
src/vs/sessions/AUTOMATIONS.md |
Documents provenance persistence contract. |
src/vs/platform/agentHost/test/node/protocolServerHandler.test.ts |
Tests listing protocol mapping. |
src/vs/platform/agentHost/test/node/agentService.test.ts |
Tests creation, recovery, and deletion races. |
src/vs/platform/agentHost/test/node/agentHostStateManager.test.ts |
Tests state and notification propagation. |
src/vs/platform/agentHost/test/node/agentHostCatalogSourceResolver.test.ts |
Tests metadata persistence and validation. |
src/vs/platform/agentHost/test/node/agentHostCatalogProjection.test.ts |
Tests catalog encoding and validation. |
src/vs/platform/agentHost/test/node/agentHostCatalogListReader.test.ts |
Tests catalog-only listing. |
src/vs/platform/agentHost/test/node/agentHostAutomationService.test.ts |
Tests full-history provenance recovery. |
src/vs/platform/agentHost/test/electron-browser/agentHostProtocolClient.test.ts |
Tests client protocol preservation. |
src/vs/platform/agentHost/node/shared/persistSessionMetadata.ts |
Defines the origin metadata key. |
src/vs/platform/agentHost/node/protocolServerHandler.ts |
Maps origin into list responses. |
src/vs/platform/agentHost/node/agentService.ts |
Creates, persists, backfills, and restores provenance. |
src/vs/platform/agentHost/node/agentHostStateManager.ts |
Carries origin through state summaries. |
src/vs/platform/agentHost/node/agentHostCatalogSourceResolver.ts |
Resolves persisted catalog origin. |
src/vs/platform/agentHost/node/agentHostCatalogProjection.ts |
Adds origin to catalog payloads. |
src/vs/platform/agentHost/node/agentHostCatalogListReader.ts |
Reads origin from catalog rows. |
src/vs/platform/agentHost/node/agentHostAutomationService.ts |
Indexes retained run membership. |
src/vs/platform/agentHost/common/state/sessionState.ts |
Copies origin into session state. |
src/vs/platform/agentHost/common/agent.ts |
Extends session metadata with origin. |
src/vs/platform/agentHost/browser/agentHostProtocolClient.ts |
Maps listed origin into client metadata. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Forward the existing catalogue row, including a known missing row, into provenance resolution instead of reading it again during fallback listing. Preserve the one-read coalescing invariant and cover catalogue results independently of listing eligibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve metadata overlays and session restoration when optional provenance backfill fails, and omit concurrently deleted entries without rejecting the entire listing. Cover the failure paths and configure catalog test modes before provider registration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
An eligible row's origin backfill already synchronizes the session database and catalogue. Do not dirty the row again and trigger another provider metadata read. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Version the provenance-aware projection so older origin-less rows cannot hide persisted origin on the first listing. Preserve old central-only metadata through migration-only decoding and verify that repaired listings return to the catalogue-only fast path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Invalidating all v1 catalog rows can make existing sessions disappear when provider metadata is temporarily unavailable.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (1)
|
|
||
| export const AGENT_HOST_CATALOG_PAYLOAD_VERSION = 1; | ||
| // Version 1 writers did not consult persisted session origin before projecting a row. | ||
| export const AGENT_HOST_CATALOG_PAYLOAD_VERSION = 2; |
Keep validated v1 catalogue metadata available to the fallback reader until provider migration completes. Preserve ordinary central-only session titles, read/archive state and multi-root metadata without unnecessary provider metadata reads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve conflicts on top of upstream remote-session delegation while retaining Automation origin persistence and regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| for (const run of this._runs.values()) { | ||
| const origin: SessionOrigin = { kind: SessionOriginKind.Automation, automation: run.automation, run: run.resource }; | ||
| for (const session of run.sessions) { | ||
| this._legacySessionOrigins.set(session, origin); | ||
| } |
| }, { | ||
| kind: SessionOriginKind.Automation, | ||
| automation: run.automation, | ||
| run: run.resource, | ||
| }), |
| const decoded = catalog && decodeAgentHostCatalogPayload(catalog.payload, { forMigration: true }); | ||
| if (decoded && !decoded.ok) { | ||
| this._logService.warn(`[AgentService] Failed to read session origin from catalog for ${session}: ${decoded.error}`); | ||
| } | ||
| recovered ??= (decoded?.ok ? decoded.value.data.origin : undefined) | ||
| ?? this._automationService.getLegacySessionOrigin(session.toString()); | ||
| if (!recovered || (origin && (!decoded?.ok || equals(decoded.value.data.origin, origin)))) { | ||
| return recovered; | ||
| } | ||
| // Share the catalogue's deletion fence without recreating missing session databases. | ||
| return await this._catalogSyncService.runMigrationExclusive(session, async (database, synchronize) => { | ||
| if (await this._sessionRegistry.isTombstoned(session)) { | ||
| throw new ProtocolError(AHP_SESSION_NOT_FOUND, `Session not found: ${session}`); | ||
| } | ||
| const persistedOrigin = readPersistedSessionOrigin(await database?.object.getMetadata(SESSION_ORIGIN_KEY)); | ||
| const currentCatalog = await this._orchestratorDatabase.getSessionV2(session.toString()); | ||
| const current = currentCatalog && decodeAgentHostCatalogPayload(currentCatalog.payload, { forMigration: true }); |
Screenshot ChangesBase: Changed (4)1 insignificant change(s) omitted (≤20 px, Δ≤2). See CI logs for details. |

Summary
Use the existing typed AHP session origin to identify Automation-created sessions instead of joining the client session list against currently available run history.
Compatibility and scope
Sessions without recoverable origin remain visible by design. This does not add AHP protocol fields, promotion behavior, or a new host visibility mechanism. Legacy renderer-owned Automation execution is not changed by this PR.
Validation
Previously executed on this patch:
npm run transpile-clientandnpm run typecheck-clientpassed.git diff --checkpassed; pre-commit hygiene passed when committing.Tests cover host creation and persistence, restart and historical recovery, deletion races, protocol and cache propagation, ordinary-list exclusion, and history opening. No live Agents Window walkthrough or real remote/Dev Container end-to-end validation was performed.
Outstanding review findings
This draft publishes the current implementation as-is. These findings from the static Opus 5.5 review remain unresolved: