Skip to content

fix(mobile): open briefing session links in the briefing's scope - #8268

Merged
iscekic merged 2 commits into
mainfrom
drain/briefing-session-scope
Oct 21, 2026
Merged

iscekic merged 2 commits into
mainfrom
drain/briefing-session-scope

Conversation

@iscekic

@iscekic iscekic commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

What changes

A briefing's session rows and its activity/cost/blocker evidence rows now build their agent-chat destination with getAgentSessionPath, the helper every other session entry point in the app already uses (agents list rows, share gate, notifications, system search). The row's destination therefore carries the report's organization on the route, and a personal report stays on the unscoped route.

Two consequences:

  • The opened session runs in the briefing's scope from its first frame instead of depending on the selected-organization switch that precedes the push, and the route no longer has to read the session back just to learn its scope.
  • The selected organization is still switched to the report's scope, so the rest of the app follows the briefing as before.

The evidence-row root resolution moved into the same small module (briefing-session-href.ts), unchanged in behaviour: an activity, cost, or blocker row opens the root session of the group it was recorded under (the session the Agents section names), falling back to the source's own session when the report no longer lists that group, and a pull-request or artifact row still opens its external URL.

Verification

Local stack + Android emulator (omp36), app language Japanese, owned fake account, organization briefing produced by pnpm dev:seed app:agent-briefing <fake-email> --organization-id=<org> (Personal and organization reports, plus a read-only session carrying a 60-message paged fixture).

  • With the selected scope on 個人, opening the organization briefing and tapping a session row opened that session and rendered its 40-message transcript (read-only footer, no composer error).
  • With the selected scope already the organization, the same row opened the same way.
  • The route's unscoped metadata read is gone for organization sessions: dev/logs/nextjs.log shows cliSessionsV2.getWithRuntimeState and cliSessionsV2.getSessionMessagesPage after the tap, and no cliSessionsV2.get — the query the detail route runs only when it has no organization from the route.
  • Tapping an evidence row (Session status changed) opened the group's root session with the same transcript.
  • A personal briefing row opened its session as before.

Unit coverage: apps/mobile/src/components/agent-briefing/briefing-session-href.test.ts asserts the report organization on a named session, the unscoped personal path, root resolution for an evidence row, the fallback to the source session, and null for an external-link row. pnpm --filter kilo-app run typecheck, oxlint, and oxfmt are clean on the changed files.

Limitation: a live cloud-agent session cannot be created on the work VM (no container/DO runtime), so that session type is exercised only through its organization parameter on the shared route helper.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: Outcome: the finding did not reproduce on main d26988c. On the local dev stack (Android emulator, app in Japanese, fake account, org briefing seeded with dev:seed app:agent-briefing --organization-id), tapping a briefing session row opened the session and rendered its transcript; this held with the app scope already the org, and with the app scope on 個人 so the row performs the organization switch first. The exact error screen the explorer saw (このセッションを読み込めませんでした。/ セッションの詳細を読み込めませんでした。 + 再試行) is the session body's transport-error state, which could only be produced by stopping the session-ingest worker; after restarting it, 再試行 opened the same row with its 40-message transcript. The briefing handler's setOrganizationId + push matches the notification/deep-link pattern, and the session route derives the session's own organization from its metadata read. Limitation: a real cloud-agent session cannot be created on this VM (no container/DO runtime), so that session type was untested. How should this work item end?
    Answer: Ship the navigation hardening instead
    Confidence: 0.60 · Precedent: Autonomy: 'If a defect does not reproduce in your environment, ship the reasonable fix and close the task' (an earlier session, owner chose 'Merge fix(mobile): polish quick chat composer edge and session list loading rows #7613 and close this'). Ending as no_change needs proof against the current code, and the cloud-agent path is still untested.

The condition that later answers from the proxy extend or replace this section.

A briefing's session and evidence rows pushed the agent-chat route without the
report's organization, so an opened session depended on the selected
organization switch that precedes the push and the route had to read the
session's metadata back to learn its scope.

The rows now build their destination with the same helper the app's other
session entry points use, which carries the report organization on the route
(personal reports stay unscoped). Evidence rows keep resolving to their
session group's root through that helper, so an activity, cost, or blocker row
opens the session the Agents section names, and an external-link row still
opens its URL.

Verified on the Android emulator against the local stack, app in Japanese: with
the selected scope on Personal, a session row in an organization briefing opens
that session with its transcript, and the route's own unscoped metadata read no
longer runs; a personal briefing row still opens its session.
@iscekic iscekic added drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer labels Oct 20, 2026
@iscekic

iscekic commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android E2E proof for the briefing session links, app language Japanese, local dev stack, owned fake account and seeded Personal + organization briefings.

Exercised: with the selected scope on 個人, opened the organization briefing from ブリーフィング履歴 and tapped the session row 経費精算バッチのタイムゾーン境界を修正 🧾. The session route opens that session and renders its 40-message read-only transcript; dev/logs/nextjs.log after the tap shows cliSessionsV2.getWithRuntimeState and cliSessionsV2.getSessionMessagesPage and no cliSessionsV2.get, i.e. the route opened with the report's organization instead of reading the session back unscoped. Tapping an evidence row (Session status changed) opened the group's root session with the same transcript, and a Personal briefing row still opened its own session.

Organization briefing Agents section with session rows, app in Japanese

Session opened from the briefing row with its transcript

@kilo-code-bot

kilo-code-bot Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change is a type-only refactor that replaces the local briefing aliases with the contract-derived types, so no runtime behavior or link resolution changed.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0

The previous suggestion is resolved: briefing-session-href.ts now derives BriefingLinkReport from the router output (BriefingReport) and BriefingLinkSource from the shared BriefingSource (kind: 'activity' | 'pull_request' | 'blocker' | 'cost' | 'artifact'), so the narrowed isSessionSourceKind check stays in sync with the shared enum. The test fixture was widened to satisfy the same contract with no assertion changes in behavior.

Verified in the incremental diff: briefingSessionHref still builds getAgentSessionPath(sessionId, context.organizationId ?? undefined), and briefingSourceHref still resolves the group root by source.id with a fallback to source.sessionId and null for non-session kinds. Callers in briefing-detail-screen.tsx pass the full report and source objects, which satisfy the narrower Pick types.

Files Reviewed (2 files)

  • apps/mobile/src/components/agent-briefing/briefing-session-href.ts - 0 issues
  • apps/mobile/src/components/agent-briefing/briefing-session-href.test.ts - 0 issues
Previous Review Summary (commit 2b3244a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 2b3244a)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The navigation change is behavior-preserving and matches the route contract; the only finding is a maintainability suggestion to reuse the shared briefing types instead of duplicating them.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/components/agent-briefing/briefing-session-href.ts 13 Local BriefingSessionRef/BriefingSourceRef/BriefingLinkReport copy the shared briefing schema and widen kind to string, contrary to apps/mobile/AGENTS.md. Use BriefingReport/BriefingSource from @kilocode/app-shared/agent-briefing (type-only, as src/lib/agent-briefing-state.ts already does).
Files Reviewed (3 files)
  • apps/mobile/src/components/agent-briefing/briefing-detail-screen.tsx - 0 issues
  • apps/mobile/src/components/agent-briefing/briefing-session-href.ts - 1 issue
  • apps/mobile/src/components/agent-briefing/briefing-session-href.test.ts - 0 issues

Verified behaviors: session and evidence rows now build the same getAgentSessionPath route the rest of the app uses, with the report org as organizationId and undefined for personal reports; the agent-chat route only runs its own unscoped cliSessionsV2.get when organizationId is absent, which this change removes for org briefings. Evidence-row resolution (activity/cost/blocker → group root, fallback to source session, external link → openExternalUrl) is unchanged, and the shared schema confirms pull_request/artifact are the only non-session kinds. No new subscriptions, timers, or listeners were added, so the change introduces no memory-leak surface.

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash-1017 · Input: 39.4K · Output: 3.4K · Cached: 290.8K

Review guidance: REVIEW.md from base branch main

The briefing link helpers declared local copies of the report and source
shapes. Deriving them from `BriefingReport` and `BriefingSource` keeps the
helpers in step with the router output: a contract change now fails the
typecheck instead of drifting silently. Behaviour is unchanged.
@iscekic iscekic added merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. merge:human Substantive functional risk requires human review. merge:blocked and removed merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. labels Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer merge:human Substantive functional risk requires human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants