Skip to content

V2 parity: replace the remaining hand-offs to the legacy interface so "New UI only" loses nothing #1722

Open

Description

@paullizer

Summary

The new React interface still sends people to legacy (classic) pages for some features it hasn't rebuilt yet. The legacy routing work moves the legacy interface under /legacy/... and adds a New UI only admin mode. In that mode non-admins can't open legacy pages, so every hand-off below becomes a dead end until it has a native V2 replacement.

Line numbers are from paullizer-react-v2-ui @ f60b982a0 (version 0.261.302) and will drift. Paths are relative to application/v2_ui/src unless noted.

Scope

# Area Gap What V2 does today Evidence Work to close
1 Agents Agent catalogue /agents is a placeholder with an "Open the agent catalogue" link to classic App.tsx:293-302, pages/PlaceholderPage.tsx Build the V2 agent catalogue
2 Chat M365 pending-action card Notices with m365_pending_action open classic chat, the only page that renders the card lib/notificationLinks.ts:361-365 Render pending M365 actions (approve/decline) in V2 chat; route these notices to /chat
3 Chat Aggregate public chat Public directory's chat action opens classic /chats?openSearch=1&scope=public pages/PublicDirectoryPage.tsx:52-56, 236-248 Add an "all public workspaces" chat scope
4 Workspaces File sources: add/configure "Adding and configuring a source is still done in the classic workspace" (personal; group/public via classicPath) pages/workspace/FileSourcesSection.tsx:150-153, lib/fileSourceWorkbench.ts:269, 556, 665 Create/configure flows for personal, group and public sources
5 Workspaces Identities: add "Adding one is still done in the classic workspace" pages/workspace/IdentitiesSection.tsx:110-113, lib/identityWorkbench.ts:167, 307, 374 Identity creation in all scopes
6 Workspaces Endpoint editor V2 lists, enables/disables and deletes endpoints only; the connection editor (provider, API versions, auth, model list) stays in classic pages/workspace/EndpointsSection.tsx:1-6 Endpoint connection editor in V2
7 Group workspace Document tools incl. upgrading legacy documents "Open classic tools for group documents" pages/workspace/DocumentsSection.tsx:61-62, pages/GroupWorkspacePage.tsx:467 Port document upgrade and remaining tools
8 Public workspace Document tools incl. upgrading legacy documents "Open classic tools to upgrade legacy public workspace documents" pages/workspace/DocumentsSection.tsx:112-113, pages/PublicWorkspacePage.tsx:336 Same as #7 for public scope
9 Group workspace Delete group "Delete group (classic)", completed on the classic group page pages/workspace/GroupSettingsSection.tsx:38-43, pages/GroupWorkspacePage.tsx:539 Deletion with prerequisite checks in V2
10 Group workspace Manage an inactive/unknown-status group "Manage group (classic)" button pages/GroupWorkspacePage.tsx:395-398 (activation redirects near :358, :437, verify) Status management and reactivation in V2
11 Public workspace Delete public workspace Confirms, then redirects to classic /public_workspaces/<id> pages/PublicWorkspacePage.tsx:221-242, 326 Deletion in V2
12 Public workspace Tags section Only documents, prompts, identities and sync are native; Tags says it is available in the classic workspace pages/PublicWorkspacePage.tsx:155-160, 348-351, lib/workspaceContext.ts:31-33 Public workspace tag management
13 Workspaces Danger-zone delete (shared settings section) "Open classic" confirm calls onOpenClassic() pages/workspace/WorkspaceSettingsSection.tsx:~814-831 Verify which scopes reach it; implement natively (overlaps #9/#11)
14 Notifications Full notifications list Bell panel "View all" opens classic /notifications; there is no V2 page components/layout/NotificationPanel.tsx:478 V2 notifications page
15 Notifications Unrecognized links classic() fallback for any link without a V2 route lib/notificationLinks.ts:439 A V2 route for every server-emitted link type
16 Workflows Workflow activity page Legacy /workflow-activity has no V2 page; V2 maps only runs it can verify against the notice, otherwise falls back to classic lib/notificationLinks.ts:163-177, 374-377; application/single_app/route_frontend_chats.py:1080 V2 equivalent for the remaining cases
17 Control Center Management section V2 /control-center says it is being built and links to classic /admin/control-center pages/ControlCenterPage.tsx:42-45, components/admin/RefreshScheduleStatus.tsx:143 Complete the V2 Control Center
18 Admin Settings DAI diagnostics A classic_only related link: the diagnostics are drawn only by the classic Scale › Cosmos › DAI Metrics pane application/single_app/admin_settings_fields.py:8313-8319, components/admin/RelatedSectionLink.tsx:41 Render the diagnostics in V2; drop classic_only
19 Admin Settings Requirement links Falls back to classic /admin/settings#<section> when it can't navigate in-page components/admin/SettingsSection.tsx:193-205 Make every requirement target navigable in V2
20 Admin Settings Chat-mode notice Says the single endpoint's address, credentials and deployment are set on the classic page (#model-endpoints) components/admin/ChatModeNotice.tsx:62-67 Verify V2 renders that configuration; link in-page
21 Admin Settings Latest Features shortcuts Shortcuts V2 can't follow in place open classic admin tabs lib/latestFeatures.ts:255-258 Map each shortcut to a V2 section
22 Admin Settings Fallback-scan note Links to classic only when undeclared enable_* keys appear. Today 106 of 107 sections are declared; the remaining one (standard-citations-section) is informational text pages/AdminSettingsPage.tsx:2099-2102, 2412-2418 No action now; keep the admin-settings parity test green
23 Errors Boot failure BootError offers "Open the classic interface" App.tsx:96-100 V2-native recovery (retry / sign out)
24 Cleanup Dead config classicHref: '/profile?tab=groups' / '/profile?tab=public-workspaces' are never read lib/workspaces.ts:68, 121, 152 Remove

Legacy pages with partial or unverified V2 counterparts

Legacy page V2 counterpart Status
/conversations V2 chat conversation list Verify parity (search, bulk actions, export)
/profile tabs (stats, settings, groups, public-workspaces, feedback, violations) /settings tabs (stats, preferences, groups, public, feedback, violations) Tabs exist; verify per-feature parity, especially M365 profile settings, fact memory and stats export
/my_feedback, /safety_violations /settings?tab=feedback, /settings?tab=violations Verify
/agents, /notifications, /admin/control-center None or placeholder #1, #14, #17

Pages with confirmed counterparts: chat, conversation deep links, approvals, content review, support pages, admin feedback and safety review, terms of use and access restricted.

Acceptance Criteria

  • Each row above is replaced by a native V2 flow or explicitly retired
  • After the routing work lands, application/v2_ui/src has no production hand-offs left to /legacy/...
  • The new UI works inside the Microsoft Teams tab (SSO token exchange, frame-ancestors, SameSite=None cookies). TEAMS_SUCCESS_REDIRECT_PATH (default /chats) will follow each user's interface
  • The separately hosted SPA mode (V2_UI_ALLOWED_ORIGIN) is smoke-tested with the root basename
  • Functional tests cover each replaced flow; the admin-settings parity test stays green

Notes

Activity

  1. paullizer commented on Oct 8, 2026

    @paullizer
    ContributorAuthor

    Row 1: native V2 Agent catalogue implementation complete.

    The code is committed locally on paullizer-v2-agent-catalogue as 8f2aee183, version 0.261.305. No PR has been opened or merged yet. This implements row 1 only; the remaining parity gaps and the companion routing/interface-policy work in #1723 are unchanged.

    • /agents now renders the native React catalogue, replacing the placeholder and classic hand-off. User-facing Latest Features shortcuts to /agents also stay inside V2.
    • Browsing includes Popular all-time/30-day usage and administrator promotions, Personal/Group/Enterprise categories, cross-scope search, AND tag filters, remembered list/card view, configured hero/disclaimer, and agent details.
    • GET /api/v2/agents/catalog applies the chat picker's governance policy before usage or promotion annotations. Governance-restricted agents stay hidden, including promoted agents. The response is explicitly allowlisted, instructions are omitted when their display setting is off, and unexpected failures return a logged generic error rather than unchecked agents.
    • Chat launches are native and scope-aware: group agents carry their own group ID rather than the account's active group. Chat refreshes the authorized catalogue before selecting the exact agent; revoked/deleted agents produce a visible error without a name-based fallback.
    • The classic catalogue/API and administrator promotion picker are unchanged. No settings keys, packages, or external browser assets were added. Long names and tags wrap on mobile, including shared dialog headings.
    • Documentation is in docs/explanation/features/V2_AGENTS_CATALOG.md, with the related guide, admin reference, and existing V2 feature documentation updated. Release notes remain unchanged.

    Validation

    Check Result
    npm --prefix application\v2_ui run typecheck and npm --prefix application\v2_ui run build Passed
    python functional_tests\test_v2_agents_catalog_endpoint.py 8/8
    python functional_tests\test_v2_agents_catalog.py 28 executable TypeScript checks
    python functional_tests\test_v2_support_menu.py 8/8, including 27 TypeScript checks
    python -m pytest ui_tests\test_v2_agents_catalog.py ui_tests\test_v2_support_menu.py -q --browser chromium --tracing retain-on-failure 29/29; production SPA/CSS, synthetic APIs, native chat sends in all three scopes, light/dark desktop/mobile, keyboard behavior, retries, and long-content/Markdown safety
    Existing group/public create-dialog keyboard/focus regressions 2/2, with the shared fixtures directory on PYTHONPATH
    V2 API security 5/5
    Route policy inventory, unauthenticated contract, and coverage 14/14, 9/9, 3/3
    Documentation surface coverage and site quality 7/7 and 6/6; regenerated inventory has no semantic change
    Explicit XSS sink scans, design mechanics, and whitespace Passed

    Two selected regression scripts have unchanged baseline failures, not failures introduced by this implementation:

    • test_agents_catalog_feature.py: 11/12; its registration check expects a direct register_route_frontend_agents(app) call, while the existing application uses Blueprint registration.
    • test_admin_settings_sidebar_card_parity.py: 3/4; existing M365 retrieval card/sidebar mismatches and duplicate inbound-MCP card IDs. The tests and affected application/template inputs are unchanged.

    Deferred idea - not implemented

    An optional future administrator opt-in could expose governance-restricted agents with Chat disabled and a proper agent-specific request-access/approval workflow. This implementation deliberately does not do that: restricted agents stay hidden, and no discovery flag, restricted-agent card, request button, or approval type was added.

    The existing Request Access flow addresses a missing base application role, and Approvals has no agent-access request type. Any future design would need to distinguish item-level agent restrictions from feature/scope-wide policy blocks and define how approval changes access. Recording that idea here rather than creating another issue.

  2. paullizer commented on Oct 9, 2026

    @paullizer
    ContributorAuthor

    Gap 2 (Chat: M365 pending-action card) is implemented.

    Branch paullizer-v2-m365-pending-actions (version 0.261.307), rebased on paullizer-react-v2-ui @ 11d8478. No PR opened yet.

    What changed

    • V2 chat now renders Microsoft 365 pending actions (saved outgoing email and calendar actions) with the same Send, Send now and Cancel controls as classic chat.
    • One shared PendingActionCard is used by both the Approvals page and chat. The Approvals test ids are unchanged.
    • Placement matches classic: inline under the reply that saved the action, live while that reply streams, and a conversation-level section (with Load more and Refresh) for actions whose reply isn't on screen.
    • Notices carrying m365_pending_action now route to V2 /chat with a one-shot focus parameter. The page scrolls to the card, highlights it, then strips the parameter. This replaces the classic hand-off at lib/notificationLinks.ts.
    • No backend, schema or settings changes. It uses the existing /api/msgraph/pending-actions endpoints.

    Stop and conversation-switch handling

    • Detaching a stream (Stop, opening another conversation, or starting a new chat) drops its live card, so a stopped reply cannot leave a stale card on screen.
    • The conversation's list is re-read after a reply ends, resumes or is stopped. A card the server saves after Stop appears on the next read.

    Heads-up for UI-test authors

    The new GET /api/msgraph/pending-actions?conversation_id=... request has to be stubbed in any strict UI harness that opens or creates a conversation. I added a shared helper (ui_tests/fixtures/v2_pending_action_stubs.py) and used it in 25 harness files, including the shared workspace_authoring base and chat_context_selection.

    Validation

    • Node: 119/119 (new: 30 logic + 44 store + 34 stream, plus the 11 routing tests I updated).
    • Functional wrapper test_v2_m365_pending_actions.py: 14/14.
    • Browser tests ui_tests/test_v2_m365_pending_action_cards.py: 10/10.
    • Docs checks: test_docs_app_surface_coverage.py 7/7, test_docs_site_quality.py 6/6.
    • npm run typecheck clean. XSS sink scan clean (chatHrefForPendingAction allowlisted in scripts/check_xss_sinks.py).
    • Full UI regression (about 55 files) re-run after the rebase.

    Failures I saw that this change doesn't cause

    The UI ones reproduce identically on a clean export of upstream tip 11d8478. This change touches none of the files involved.

    • test_v2_document_provenance (3 group tests): upstream's group switch now confirms with GET /api/v2/scope, which ui_tests/fixtures/workspace_authoring.py doesn't stub.
    • test_v2_workflow_run_card (1): expects /profile?tab=settings#m365-connection-status, but the code links /settings?tab=preferences&section=m365-workflow-connection (lib/m365Links.ts).
    • test_v2_workflow_alert_notices (1 error) and test_v2_notifications_bell (10 teardown errors): unstubbed Settings endpoints in those harnesses. The 5 bell tests I added pass.
    • functional_tests/test_v2_notifications_bell.py::test_the_administrator_switch_and_the_preference_reach_both_sides: pins the literal "features": _build_feature_flags(...) in route_backend_v2.py, which upstream has since refactored to features = _build_feature_flags(...).
    • test_v2_group_workspace_shell: bare from playwright_connection import ... in v2_admin_settings.py. It passes 30/30 with PYTHONPATH=ui_tests\fixtures.
    • Environmental: classic tests that import semantic_kernel (broken OpenSSL/cryptography install on this machine), content_screening import errors in two orchestration backend tests, script-style UI tests that only run as python ui_tests/<file>.py, and 7 skips that need SIMPLECHAT_UI_BASE_URL.

    Not part of this change

    Workflow-activity M365 notices (they still open classic), the V2 sign-in and approval pause UIs for the m365_sign_in_required / m365_approval_required stream pauses, and data-access approvals.

  3. paullizer commented on Oct 9, 2026

    @paullizer
    ContributorAuthor

    Row 4: file-source create/configure planning update (not implemented yet).

    Investigated the current paullizer-react-v2-ui baseline at 271b30187, application version 0.261.309, in branch paullizer-file-source-configuration.

    The remaining gap is primarily personal sources. Group and public workspaces already use native V2 create/edit dialogs through GroupFileSourcesSection, FileSourceEditorDialog and their explicit scoped APIs. The three file-source adapter classicPath properties are unused. Personal FileSourcesSection still sends configuration to classic, and the personal workbench adapter refuses create/edit/test/browse/ignore.

    Confirmed scope and planned approach

    • Reuse the existing V2 section/dialog for personal, group and public sources, removing file-source classic hand-offs and dead classicPath properties rather than replacing them with /legacy links.
    • Preserve full currently available SMB, Azure Files and Azure Blob configuration: existing eligible identities or source-local credentials, connection tests, browse/selected paths, recursion, schedules, filters, fixed/folder tags and remote-delete policy.
    • Keep connector availability unchanged. Do not enable coming-soon connectors or include identity creation; that remains separate scope.
    • Wire the existing personal APIs and add personal editor-options/single-source reads. Reuse the server's options builder and authorization instead of sending raw settings to the browser.
    • Add backward-compatible personal conditional saves so a concurrent edit keeps the draft and offers reload/merge, matching group/public. Classic clients without revision tokens continue to work.
    • Preserve secrets, scope isolation, role/status gates, and existing sync/history/deletion behavior. Correct shared editor wording and protect required-data loading and late-response handling.
    • Add personal API/adapter/browser regression coverage and rerun group/public workflows, including no legacy navigation; update the native workflow documentation and application version when implementation occurs.

    The implementation plan is prepared for approval. No application code or version has changed, no implementation validation is claimed, and row 4 should remain open.

    The companion routing/interface-policy work in #1723 and every other parity row are outside this change.

  4. paullizer commented on Oct 9, 2026

    @paullizer
    ContributorAuthor

    Planning update for row 3: aggregate public chat. Implementation has not started.

    Confirmed scope:

    • Add native All public workspaces chat: search every existing, chat-available public workspace, including those hidden by directory visibility preferences. Do not rewrite those preferences.
    • Keep Chat with visible as a separate native V2 launch, honoring the existing curated visibility selection and flushing pending saves before navigation.
    • Both modes are public-only, excluding inherited personal/group active scopes. Keep the selected mode for follow-ups until explicitly changed; New chat resets it. Restore the saved mode when reopening a conversation.

    The current backend intersects public IDs with visibility in chat authorization, hybrid search, and search/source services; changing the directory link alone would still exclude hidden workspaces from All mode. The plan therefore includes a shared server-authoritative mode resolver, workspace-status checks, matching public document/tag picker reads, ordinary and orchestrated chat propagation, persisted/replayed search metadata, and explicit empty-set handling with no scope-broadening fallback.

    Coverage will prove native SPA navigation with legacy pages unavailable to non-admins, All versus Visible behavior, unavailable/hidden/empty workspaces, persistence/reset/retry/edit, orchestration, and unchanged single-workspace/mixed-context behavior. Related documentation and the application version will be updated during implementation.

    This work addresses row 3 only; other parity rows and companion routing issue #1723 remain outside this change. No completion checkboxes have been marked.

  5. paullizer commented on Oct 9, 2026

    @paullizer
    ContributorAuthor

    Planning row 6: personal workspace endpoint editor only. No implementation or validation has run yet.

    Confirmed scope:

    • Reuse the native V2 connection manager already used for admin/group endpoints, with a personal API adapter. Remove the classic workspace hand-off.
    • Support personal create/edit, provider and API versions, authentication, manual/discovered models, chat tests, enable/disable, and delete.
    • Include classic advanced endpoint/model token limits, per-model response length, description, and model icons; preserve stored credentials and metadata.
    • Existing personal discovery/test routes deliberately use saved configuration when an endpoint ID is present. Require saving existing-endpoint changes before discovery/testing so a success cannot validate stale settings. New drafts retain the existing transient-request support and server safeguards.
    • Add only public Custom API descriptors to the sanitized personal list response; do not expose admin settings or call admin/group endpoints.
    • Add real-route functional coverage, TypeScript adapter/form tests, production-SPA UI tests, documentation, and an app patch-version bump.

    Group endpoint editing already has a native V2 implementation; group/admin behavior and public workspace scope are unchanged. Other rows in this issue and the routing work in #1723 remain separate. Root-basename/Teams deployment qualification will need to follow the routing work; synthetic UI coverage will not be represented as live-service qualification.

  6. paullizer commented on Oct 9, 2026

    @paullizer
    ContributorAuthor

    Row 5: native workspace identity authoring planning update. Implementation has not started.

    Inspected baseline 1447daae7, application version 0.261.314, on branch paullizer-v2-identity-creation.

    The remaining creation gap is personal scope. Group/public workspaces already have native V2 create/edit dialogs and strict scoped identity APIs. Personal IdentitiesSection still links creation to classic and its adapter refuses create/edit. The three identity adapter classicPath properties are unused.

    Confirmed scope

    • Native creation in personal, group, and public workspaces.
    • Also add personal identity editing, as requested.
    • Add stale-edit protection for personal identities, rather than preserving the existing last-save-wins PATCH.
    • Use a strict, additive native personal API at /api/user/identities, preserving the existing classic personal API contracts.

    Planned approach

    • Reuse the existing identity editor and extract one scope-aware section, with accurate personal/group/public wording. Remove identity classic hand-offs and dead classicPath properties.
    • Add authenticated/user-protected personal list/read/create/update/delete routes. Ownership comes only from the signed-in user. Native edits/deletes require expected_etag; missing/stale tokens are refused without falling back to an unversioned endpoint.
    • Reuse the existing conditional Cosmos and Key Vault staging/cleanup helpers. Capture the editor's original ETag and update it only after explicit conflict refresh/rebase, keeping the user's draft and typed secrets.
    • Preserve stored-secret masking, blank-secret preservation, non-secret credential identifiers, and in-use delete protection.
    • Keep group/public roles, availability/status checks, operation hints, ETags, and scope isolation unchanged. Personal/group identities retain File Sync and Actions usage; public remains File Sync only.
    • Add real-backend API and fixture-parity coverage plus production-SPA browser coverage for authoring, conflicts, authorization, credential round trips, error/retry/discard behavior, and desktop/mobile light/dark layouts. Block legacy page requests to prove the identity workflow no longer depends on them.
    • Update feature/workspace documentation and bump the application patch version at implementation completion.

    Global/admin identity authoring, model-endpoint identity capabilities, inline creation in connector editors, legacy routing/admin-mode implementation, and deployers are out of scope. No implementation validation has been run yet. This closes only row 5 when implemented; it does not close the umbrella issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Created By CopilotP1Priority 1: urgent, address before P2 workenhancementNew feature or request

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions