Skip to content

fix(desktop): search fixture-seeded transcripts for content hits - #3069

Merged
Astro-Han merged 4 commits into
apache:mainfrom
1625567290:fix/e2e-fixture-thread-search
Aug 22, 2026
Merged

fix(desktop): search fixture-seeded transcripts for content hits#3069
Astro-Han merged 4 commits into
apache:mainfrom
1625567290:fix/e2e-fixture-thread-search

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

Fixture windows seed transcripts into the workspace store. After the Runtime Host migration, search:thread still listed those sessions from the Host catalog (so a title query could hit) but read messages through openSession / loadTranscript. A Host miss is swallowed as null, so content search returned no hits and no turnId — which is what blocked e2e from driving search → navigate-to-a-specific-turn against a seeded transcript (#2305).

The original sessions:readMessages fixture bypass is gone. This restores the same contract on the current IPC: when MAKA_E2E_FIXTURE is set, search reads the store writeSession wrote. Production still reads the Host transcript.

long-transcript is gone; the lock uses the existing chat-prompt-rail seed (第 3 个问题turn-prompt-rail-3).

Fixes #2305

Verification

  • npm --workspace @maka/core run build
  • npm --workspace @maka/desktop run build:main
  • node --test apps/desktop/dist/main/__tests__/runtime-host-search-ipc-main.test.js apps/desktop/dist/main/__tests__/thread-search.test.js15/15
    • fixture store + failing Host still returns the content hit with turnId
    • without the fixture reader, Host transcripts still work
    • without the fixture reader, a Host miss stays title-only / empty
  • Not run: full desktop Playwright e2e (the new fixture-thread-search.spec.ts is the window-level lock; CI should run it)

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope:

Grok authored the implementation, tests, and this PR description.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

Fixture windows write transcripts into the workspace store. Thread
search listed those sessions from the Host catalog but read messages
through openSession/loadTranscript, so a Host miss became a title-only
hit with no turnId. Give search the same store read the fixture wrote.

Fixes apache#2305

Generated-by: Grok
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ed94e9c0-90fd-4848-b2dd-538d52636528

📥 Commits

Reviewing files that changed from the base of the PR and between b7bb9b7 and bbcf749.

📒 Files selected for processing (2)
  • apps/desktop/src/main/__tests__/runtime-host-search-ipc-main.test.ts
  • apps/desktop/src/main/runtime-host-search-ipc-main.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/main/runtime-host-search-ipc-main.ts

📝 Walkthrough

Summary

This PR fixes desktop thread search for fixture-seeded transcripts. When MAKA_E2E_FIXTURE is set, search reads messages from the workspace store created by writeSession. This restores content matches and turnId results when the Runtime Host cannot load the transcript. If the fixture store returns no messages, search falls back to the Runtime Host. Production search continues to read transcripts through the Runtime Host.

The change extends the existing fixture workspace store. It does not create a parallel transcript source for production. The fixture reader is injected only in fixture mode. This is the smallest coherent solution because it preserves the production path and adds only the fallback required by the fixture environment.

The new readE2eFixtureSessionMessages helper closes the store after each read and returns null for a read failure or miss. The IPC tests cover fixture reads, Runtime Host reads, Runtime Host misses, session cleanup, and result shapes. The chat-prompt-rail fixture provides coverage, so the unused long-transcript fixture was removed. No deletion or simplification is evident without reducing regression coverage.

Validation

  • Core build passed.
  • Desktop main build passed.
  • Fifteen targeted tests passed.
  • The e2e test verifies a Chinese content match with the expected summary, session ID, turn ID, and sequence.
  • Full desktop Playwright e2e was not run.
  • Required check status remains unverified without direct check results.

Review-relevant risks

The change affects desktop search behavior in fixture mode and adds the exported readE2eFixtureSessionMessages API. Material changes in these user-visible and public-contract areas require independent human review under repository policy.

No security, licensing, release, or governance effect was identified in the current diff. The person performing the merge must review the final diff, and a maintainer makes the final determination.

Walkthrough

Fixture-backed thread search now reads seeded session messages from SQLite during E2E runs. Runtime search retains Host transcript fallback and cleanup behavior. Unit and Playwright tests cover result metadata, failures, and Chinese content queries.

Changes

Fixture-backed thread search

Layer / File(s) Summary
Fixture message reader
apps/desktop/src/main/e2e-fixture/seed-helpers.ts, apps/desktop/src/main/e2e-fixture.ts
Reads seeded session messages from the operational-state store, closes the store, and re-exports the reader.
Search IPC message loading
apps/desktop/src/main/runtime-host-search-ipc-main.ts, apps/desktop/src/main/runtime-host-boot.ts
Uses fixture messages when an E2E fixture is active. Otherwise, reads Host transcripts and closes sessions.
Search behavior validation
apps/desktop/src/main/__tests__/runtime-host-search-ipc-main.test.ts, apps/desktop/e2e/fixture-thread-search.spec.ts
Tests fixture hits, Host transcript results, cleanup, failure handling, result shapes, and Chinese queries.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to bbcf7

The change restores fixture-backed transcript content search while preserving production transcript behavior, and no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant ThreadSearch
  participant RuntimeHostSearchIPC
  participant FixtureMessageReader
  participant OperationalStateSQLite
  participant HostTranscript

  ThreadSearch->>RuntimeHostSearchIPC: Search thread
  RuntimeHostSearchIPC->>FixtureMessageReader: Read fixture messages
  FixtureMessageReader->>OperationalStateSQLite: Read session messages
  OperationalStateSQLite-->>FixtureMessageReader: Return StoredMessage[]
  FixtureMessageReader-->>RuntimeHostSearchIPC: Return fixture messages
  RuntimeHostSearchIPC->>HostTranscript: Read transcript when no fixture reader
  HostTranscript-->>RuntimeHostSearchIPC: Return transcript or null
  RuntimeHostSearchIPC-->>ThreadSearch: Return search results
Loading

Possibly related issues

  • Issue maka-agent/maka-agent#2305: The change makes thread search read fixture-seeded messages and support content hits during E2E runs.
🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the desktop fix for searching fixture-seeded transcripts for content hits.
Description check ✅ Passed The description includes the required summary, issue reference, verification results, AI-use selection, and checklist status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Ai Use Disclosure ✅ Passed The description selects substantive generative tooling, names Grok and its scope, and both introduced commits contain standalone consistent Generated-by: Grok trailers.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 907abb43-7fc8-4802-a060-bc662b3907c0

📥 Commits

Reviewing files that changed from the base of the PR and between 5c11151 and b7bb9b7.

📒 Files selected for processing (6)
  • apps/desktop/e2e/fixture-thread-search.spec.ts
  • apps/desktop/src/main/__tests__/runtime-host-search-ipc-main.test.ts
  • apps/desktop/src/main/e2e-fixture.ts
  • apps/desktop/src/main/e2e-fixture/seed-helpers.ts
  • apps/desktop/src/main/runtime-host-boot.ts
  • apps/desktop/src/main/runtime-host-search-ipc-main.ts

Comment thread apps/desktop/src/main/runtime-host-search-ipc-main.ts Outdated
A bound fixture reader used to skip the Host transcript entirely.
Treat a null store read as a miss so a later Host-written session in
the same fixture window is still searchable.

Generated-by: Grok
@Astro-Han

Copy link
Copy Markdown
Contributor

Thanks for digging into the fixture search gap — the direction is right and the test scaffolding is solid. The review surfaced two issues worth resolving before merge.

Conclusion: needs work — two P1s.

P1-1 — the two new tests pin behavior that main has already changed.

The PR's base (5c1115132) predates both. After a rebase onto current main these assertions fail, so the PR would land red (verified against current main sources). Rebasing and updating the two assertions should resolve this.

P1-2 — the premise of the fix may not hold: the Host already serves fixture-seeded transcripts.
writeSession in seed-helpers.ts and the Host's SqliteSessionStore write the same SQLite store (createSqliteSessionMetadataStore(join(workspaceRoot, OPERATIONAL_STATE_DATABASE_NAME))). The renderer renders fixture transcripts through the same client.openSession path, and the prompt-rail e2e suite proves that works on main CI. search:thread reads messages through the same openSession/loadTranscript path, so there's no obvious reason it fails where rendering succeeds. Note that #2305 (the issue this PR fixes) analyzed the pre-migration code, where runtime.getMessages did not read the store at all.

Suggested verification: revert the 4 production files, keep only fixture-thread-search.spec.ts, and run it. If it passes (expected), the production change can be deleted entirely — the e2e spec alone is the lock. If it fails, the fix becomes a workaround rather than a root-cause fix, and the fallback in the second commit still looks like dead code either way (catalog sessions always exist in the same store, so ?? readHostTranscript never fires).

Optional nits (P3): tests 3/4 in the new suite exercise unchanged paths; if (!Array.isArray(outcome)) return; in the spec is dead code (the expect above throws first).


AI-assisted review disclosure: this review was produced with AI assistance (pi review subagents on ollama-cloud/deepseek-v4-flash, read-only). The subagents traced the Host transcript-read path and the store writes; I verified the P1-1 assertions and the shared-store claim against current main sources myself. The P1-2 "spec passes without the production change" outcome is a prediction, not something I ran — the verification steps are above. Please weigh these findings with your own judgment.

中文摘要(AI 辅助审查)

结论:FAIL,需要返工。两个 P1:① 两个新测试钉死了 main 已改掉的行为——单测断言 '会话标题'#3033 已改为 '任务标题',e2e 断言裸 sessionId 但 #3097 已做 desktopSessionKey 映射;PR 的 base 早于这两个提交,rebase 后必红,需更新断言。② 修复前提存疑:fixture 的 writeSession 与 Host 的 SqliteSessionStore 写的是同一个 SQLite 文件,渲染器走同一 client.openSession 路径渲染 fixture transcript 在 main CI 通过,search 走同一路径没有理由单独失败;#2305 分析的是迁移前代码(getMessages 不读 store),根因在迁移后已不存在。建议:revert 4 个生产文件只留 e2e spec 验证;第二个 commit 的 fallback 无论如何都是死代码。P3 可选:测试 3/4 测的是未改动路径、spec 中死代码。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intended regression lock is useful, and the Host reader keeps correct session cleanup. Production still defaults to the Host path and the focused old-base checks are green.

Against current main, however, the new assertions are stale (desktopSessionKey projection and 任务标题), so the merged test result fails even though GitHub can merge the text cleanly. More importantly, the fixture and Runtime Host use the same runtime.sqlite; the Host transcript reader already reads that store, and a current-main 120-turn fixture is fully visible through loadTranscript(). From first principles, Runtime Host must remain the sole transcript authority. The smallest solution is to keep the E2E assertion, delete the new Desktop-main SQLite reader/wiring, and fix any actual Host readiness issue only if the E2E still fails.

Reviewed with Codex using two independent reviewer agents; I verified the latest head, current-main contracts, shared store/Host reader path, active-overlay behavior, existing discussion, and live CI.

中文

这条回归锁本身有价值,Host reader 的 session cleanup 也正确;生产默认仍走 Host,旧 base 上的聚焦检查全绿。

但相对当前 main,新增断言已经过期(desktopSessionKey 投影和 任务标题),所以即使 GitHub 文本上可干净合并,合并后的测试仍会失败。更重要的是,fixture 与 Runtime Host 使用同一个 runtime.sqlite,Host transcript reader 本就读取该 store;在 current main 上,120-turn fixture 可完整通过 loadTranscript() 读取。按第一性原理,Runtime Host 必须保持唯一 transcript authority。最小方案是保留 E2E 断言,删除新增的 Desktop-main SQLite reader/wiring;只有 E2E 仍失败时再修真实的 Host readiness 根因。

本次由 Codex 配合两个独立 reviewer agent 审查;我核验了最新 head、current-main 契约、共享 store/Host reader 路径、active overlay 行为、已有讨论和实时 CI。

Comment thread apps/desktop/e2e/fixture-thread-search.spec.ts Outdated
Comment thread apps/desktop/src/main/runtime-host-search-ipc-main.ts Outdated
@Astro-Han

Copy link
Copy Markdown
Contributor

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Fixture errors bypass Host fallback 🐞 Bug ☼ Reliability
Description
readMessages awaits readFixtureMessages without the existing fallback wrapper, so any rejection
aborts search:thread instead of trying the Host transcript. The production fixture reader can
reject while acquiring or constructing its SQLite store because those operations occur before its
try/catch.
Code

apps/desktop/src/main/runtime-host-search-ipc-main.ts[R35-37]

+      readMessages: async (sessionId) =>
+        (await deps.readFixtureMessages?.(sessionId)) ??
+        readHostTranscript(deps.client, sessionId),
Relevance

●●● Strong

Recent accepted PR #3111 requires acquisition and dependent construction to be covered by error
handling; this fixture path violates that fallback contract.

PR-#3111

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The dependency contract says a fixture read failure returns null and falls through to the Host,
but the changed expression directly awaits the callback. runThreadSearch also directly awaits
readMessages, while readE2eFixtureSessionMessages starts its catch only after database
acquisition and store construction, both of which can throw; the existing readWithFallback helper
already implements the intended non-reconnectable failure behavior. PR #3111 documents the same
unsafe pattern of acquiring an owner and opening the dependent resource before entering
try/finally.

apps/desktop/src/main/runtime-host-search-ipc-main.ts[17-25]
apps/desktop/src/main/runtime-host-search-ipc-main.ts[35-37]
apps/desktop/src/main/e2e-fixture/seed-helpers.ts[93-108]
apps/desktop/src/main/search/thread-search.ts[218-219]
apps/desktop/src/main/ipc-reconnect-policy.ts[42-51]
PR-#3111

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A rejected fixture-reader promise escapes `search:thread`, although the new dependency contract says fixture read failures must fall through to the Runtime Host transcript.

## Issue Context
Reuse the existing `readWithFallback` seam around the optional fixture read before applying nullish fallback to `readHostTranscript`. Add a regression test with a rejecting fixture reader and verify the Host transcript is still searched; no new configuration or public surface is needed.

## Fix Focus Areas
- apps/desktop/src/main/runtime-host-search-ipc-main.ts[35-37]
- apps/desktop/src/main/__tests__/runtime-host-search-ipc-main.test.ts[99-150]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: This changes runtime IPC search behavior and fixture-vs-Host transcript authority, with fallback and lifecycle semantics across boot and storage paths; it carries real correctness risk but is not dense enough to warrant redundant extended passes.

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more'

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread apps/desktop/src/main/runtime-host-search-ipc-main.ts Outdated

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @1625567290 — re-reviewed at exact head 10d0597c441cb357eb59d53334b8f432850fe40f. The earlier round was against bbcf749c; both points raised there are addressed at this head. No findings; approving.

Previously raised, now resolved

  • The E2E assertion no longer uses a bare sessionId or the old 会话标题 wording; it goes through desktopSessionKey({hostId, sessionId}) and 任务标题, matching the current identity contract.
  • The second fixture-reading branch is gone. readMessages now has a single path — openSession()loadTranscript() through readWithFallback, with close in a finally — and a failed read returns null rather than falling through to a direct fixture read. Nothing bypasses the active-overlay path.

On the risk specific to a tests-only change

A PR that only touches test files can weaken coverage while appearing to strengthen it, so that was checked directly rather than assumed. This change is purely additive — no existing assertion was modified or removed — and the new assertions are strict rather than permissive: the E2E case uses toBe on the summary and toEqual on the full target object, and the unit cases use assert.deepEqual on the whole target plus a closed === 2 count that pins resource cleanup.

The other failure mode for a fixture-backed search test is that it asserts a string the fixture itself hard-codes, which would prove only that the seed round-trips. That is not the case here: the seeded turns are generated as real conversation text by scenarios-chat.ts, the asserted substring is part of that generated user message, and the search runs through the real IPC path into Host listSessions / openSession / loadTranscript. The seed builds no index and installs no bridge shortcut, so a hit can only be produced by the actual search chain.

The two files do not overlap: the E2E case drives a real fixture-seeded window, the unit case drives the IPC handler against a mock client, including the Host-failure-yields-no-hits path.


This review was AI-assisted. It is not a substitute for independent human review by a committer.

@Astro-Han
Astro-Han merged commit 4ffc823 into apache:main Aug 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(e2e): fixture-seeded transcripts return no content hits from thread search

2 participants