From dc7c631105f47fdfd7b1e3f48011a0259fee82c1 Mon Sep 17 00:00:00 2001 From: frf12 Date: Fri, 9 Oct 2026 16:07:12 +0800 Subject: [PATCH 1/3] fix: address artifact search review edge cases --- desktop/README.md | 4 +- desktop/README.zh.md | 4 +- desktop/ui/src/app/Connections.tsx | 46 ++++++- desktop/ui/src/app/connection-messages.ts | 14 ++ desktop/ui/tests/connections.test.tsx | 127 +++++++++++++++++- .../oceanbase/topic_memory_index.py | 2 + .../persistence/sqlite/topic_memory_index.py | 2 + .../test_topic_memory_oceanbase.py | 25 ++++ tests/e2e/test_topic_memory_generic_api.py | 54 ++++++++ 9 files changed, 271 insertions(+), 7 deletions(-) diff --git a/desktop/README.md b/desktop/README.md index 7d0dc741e5..36ebeca4c1 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -116,4 +116,6 @@ The CI-only lifecycle scenario forcibly ends its own installed Desktop process a Installed boundary checks exercise an 8192-byte Unicode note, reject over-budget input, display zero and capped-ten search results, and verify cancel/confirm behavior when disconnecting with an unsaved draft. Each result requires its matching remote report. -After upgrading from the earlier preview, select `sqlite-6e237568-v1` and recheck your connection. The previous `sqlite-1.1.1-v1` / `sqlite-63f918b7-v1` / `sqlite-ab43e3a7-v1` / `sqlite-f1089f4e-v1` selection is not silently upgraded to a different contract. See [current qualification](VALIDATION.md). +After upgrading from an earlier preview, open Connections and select your saved connection. Compare the tested Server build with your deployment, choose `sqlite-legacy-58f7f4f6-v1` under “Available for this Desktop build”, save, then check and explicitly use the connection again. This profile matches the bundled Desktop contract; new connections still start with no compatibility selection. + +Profiles for earlier contracts, including `sqlite-6e237568-v1`, appear as disabled historical records. A saved incompatible or unavailable selection remains visible with an explanation until you explicitly replace it; it is not silently upgraded. The earlier `sqlite-1.1.1-v1` / `sqlite-63f918b7-v1` / `sqlite-ab43e3a7-v1` / `sqlite-f1089f4e-v1` selections also require explicit replacement. Historical qualification records and evidence are retained; see the [validation guide](VALIDATION.md). diff --git a/desktop/README.zh.md b/desktop/README.zh.md index b25e78d593..fdcdd0e234 100644 --- a/desktop/README.zh.md +++ b/desktop/README.zh.md @@ -98,4 +98,6 @@ Windows GitHub Actions 会构建未签名安装包,安装到临时中文路径 安装版边界测试覆盖 8192 字节 Unicode 正文、超限输入禁止提交、搜索无结果和最多 10 条的提示,以及未保存草稿时取消或确认断开连接的行为。是否通过以对应远程报告为准。 -从早期预览版升级后,请选择 `sqlite-6e237568-v1` 并重新检查连接。旧的 `sqlite-1.1.1-v1` / `sqlite-63f918b7-v1` / `sqlite-ab43e3a7-v1` / `sqlite-f1089f4e-v1` 选择不会静默升级为另一份契约。当前验证范围见[验证说明](VALIDATION.md)。 +从早期预览版升级后,请打开「连接」并选中已保存的连接。先核对已测试的 Server 构建与实际部署,再从「此 Desktop 构建可用」中选择 `sqlite-legacy-58f7f4f6-v1`,保存后重新检查并明确使用此连接。该配置与当前 Desktop 打包的契约匹配;新连接仍默认不选择兼容配置。 + +`sqlite-6e237568-v1` 等使用旧契约的配置会显示为不可选择的历史验证记录。已保存的不匹配或不可用配置仍会显示,并说明原因,须由你明确改选,不会静默升级。更早的 `sqlite-1.1.1-v1` / `sqlite-63f918b7-v1` / `sqlite-ab43e3a7-v1` / `sqlite-f1089f4e-v1` 选择也须明确替换。完整历史验证记录和证据予以保留,详见[验证说明](VALIDATION.md)。 diff --git a/desktop/ui/src/app/Connections.tsx b/desktop/ui/src/app/Connections.tsx index cba0bf0caf..c691e2dad2 100644 --- a/desktop/ui/src/app/Connections.tsx +++ b/desktop/ui/src/app/Connections.tsx @@ -22,6 +22,7 @@ import type { StorageChoice, Fact, } from "../generated/ipc"; +import { contractSha256 } from "../generated/operations"; import { desktopApi } from "../shared/ipc"; import { connectionMessages, connectionError } from "./connection-messages"; import { messages, type Language } from "./messages"; @@ -155,6 +156,18 @@ export function Connections({ state, language, onState, onDirty }: Props) { (profile.credentialState === "stored" || profile.credentialState === "session_only") && !invalidated.current; + const availableProfiles = state?.compatibilityProfiles.filter( + (p) => p.contractSha256 === contractSha256, + ); + const historicalProfiles = state?.compatibilityProfiles.filter( + (p) => p.contractSha256 !== contractSha256, + ); + const selectedCompatibility = state?.compatibilityProfiles.find( + (p) => p.id === compatibility, + ); + const unavailableCompatibility = + compatibility !== "" && + selectedCompatibility?.contractSha256 !== contractSha256; return (
@@ -315,14 +328,39 @@ export function Connections({ state, language, onState, onDirty }: Props) { }} > - {state?.compatibilityProfiles.map((p) => ( - + {availableProfiles.map((p) => ( + + ))} + + )} + {!!historicalProfiles?.length && ( + + {historicalProfiles.map((p) => ( + + ))} + + )} + {compatibility && !selectedCompatibility && ( + - ))} + )}

{t.compatibilityHint}

+ {unavailableCompatibility && ( +

+ {selectedCompatibility + ? t.profileContractMismatch + : t.profileMissing} +

+ )}
{t.ca}