Skip to content

feat(desktop): make readiness explicit and verify connection identity - #2361

Merged
hidb4ai merged 26 commits into
oceanbase:masterfrom
jackie-cqz:fix/desktop-explicit-readiness
Nov 6, 2026
Merged

hidb4ai merged 26 commits into
oceanbase:masterfrom
jackie-cqz:fix/desktop-explicit-readiness

Conversation

@jackie-cqz

@jackie-cqz jackie-cqz commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Which issue or RFC does this PR close?

Refs #2101, #2103 and #2105. Follows RFC #1455 and RFC #1733 and includes master 20f64d72, Scope statistics and Runtime observations. Remaining local setup handoff and platform acceptance keep the issues open.

Rationale for this change

Passive connection checks and identity revalidation can invoke readiness and probe configured dependencies. Separate explicit diagnostics from identity and authorization so Scope-authorized users can use Memory and statistics when Server observation returns 403.

What changes are included in this PR?

  • Add public GET /v1/connection/identity through normal authentication and access.self. Return deployment, request Principal, authentication state and Access mode. Regenerate Python/Rust/TypeScript contracts, integration operation tables and DSH/Cindy/OpenCode bundles.
  • Require that identity contract for current qualified profiles. Missing identity feature declarations fail closed. Anonymous loopback requires explicit disabled authentication/Access and an empty Principal. Qualified legacy profiles retain their Principal and discovery fences.
  • Revalidate current identity around Scope, Memory, statistics and Runtime observation requests. Keep observation failures independent of authorized business work, with context invalidation, original write targets, uncertain outcomes and input recovery preserved.
  • Add explicit revision/deployment-bound readiness diagnostics with bilingual explanation, separate timestamp and independent admission/UI state. Users can check or activate another connection during a probe, with late results discarded. Share the Access-mode fact between the menu and connection card.
  • Qualify all thirteen operations against exact Server source 7d89a97a3d417326c44b5dd79810d9e9d68f0d4f and one pinned wheel. Preserve historical records and add independently verified authenticated-client evidence for legacy 112db11e and 3cefa45a.
  • Verify the actual immutable wheel bytes before extraction/startup and require native product-path identity and scoped-authorization results. Rebuilt-source runs compare every runtime file with the exact Git archive and report a separate fixture qualification.
  • Reconcile CI conflicts using the current baseline's workflows and migration runner. SeekDB uses three shards, 180-second cases, a 40-minute migration step and an 80-minute job. Selected OceanBase full-Server cases use --test-timeout 300. Required checks, no-skip assertions and incomplete-timeout evidence remain enforced.
  • Fix the model-usage CI test's timing margin. Its first body still exceeds the initial slice, with five-second write and flush budgets for real SQLite retry and commit. Retain the retry, single-record and restored-connection assertions.

Are there any user-facing changes?

Readiness runs through explicit diagnostic actions. Connection checks and ordinary Scope/Memory/statistics work use the lightweight identity contract. Scope-authorized users can operate independently of Server observation permission and switch connections while diagnostics run. Both identity displays use the same Access-mode precedence.

The HTTP operation is additive. Anonymous Servers lacking a qualified identity operation require upgrade. This is an unsigned Desktop preview, with installed-platform acceptance tracked separately.

How was this change tested?

Windows 10 x64, Python 3.11.15 / 3.14.7 and Rust 1.95.0.

  • cargo test --locked --manifest-path desktop/src-tauri/Cargo.toml passes 114 tests, plus the spawned-process proxy recheck. Rust formatting, strict Clippy all targets and IPC drift checks pass.
  • pnpm --dir desktop test passes 195 tests with jsdom/mocked IPC. Frontend lint, generated drift, TypeScript and production build pass.
  • Focused Python API/JS/Desktop/fixture/identity/model-usage tests pass 104 tests. API/JS generation checks pass. The complete model-usage module passes 32 tests on Python 3.14.7, including ten consecutive real SQLite executions of the previously failing test.
  • python desktop/tests/real_server.py --product-qualification sqlite-identity-stats-7d89a97a-v1 passes anonymous loopback, static Bearer, HTTPS CA/base path and enforced Provider modes through the ordinary product manager. Covers identity, explicit readiness, Runtime observations, Scope selection, Memory save/search/exact reads, all statistics periods, unknown usage, uncertain committed writes without replay, identity changes, revocation and pagination.
  • The scoped Provider case verifies native identity, Memory and statistics while real Server discovery returns 403. Usage seeding is synthetic fixture input. The disposable CI qualification also passes all four modes.
  • Both legacy Servers pass three authenticated modes through the explicit rebuilt-source fixture path, with runtime files verified against their archived sources. Their original wheel artifacts were not rerun. Exact evidence and qualification boundaries are recorded in desktop/VALIDATION.md.
  • The new wheel has 738 verified runtime files, SHA-256 bdd26c664afdf966269d2eafb403a7ba05c740837577e2ac954e01878b843d7a, and OpenAPI SHA-256 9aabe2565d9cbd36075be03a83b7370e07e38e9f25232e20dd47812aba65e508. Source and probe hashes are recorded in the validation guide.
  • Rebuilt integration checks pass 448 DSH tests with one platform skip, 110 OpenCode tests and 20 Cindy tests. CI-selection/runner checks pass 143 tests with twelve Linux-only skips.
  • File hooks on the PR's affected files pass. The full Windows type hook reports 88 platform diagnostics plus twelve diagnostics from a baseline symlink checked out as text. Linux-target type checks pass with that placeholder excluded while the actual resource source is checked. Required Linux/backend acceptance remains the current remote CI run.

Installed WebView/vault, IME/accessibility/scaling, signed packages and Windows 11/macOS release acceptance require their corresponding execution evidence.

AI usage statement

OpenAI Codex (GPT-6) assisted with implementation, review, regression tests, real-Server execution and documentation. Validation modes and limitations are recorded above.

Copilot AI balanced review requested due to automatic review settings November 1, 2026 13:41

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

list_artifact_revisions: { method: 'GET', path: '/v1/scopes/{scope_id}/artifacts/{family}/{artifact_id}/revisions', location: "query", scopeMode: 'none', pathParameters: ['scope_id', 'family', 'artifact_id'], queryParams: ['limit','cursor'], headerParams: [], successStatuses: [200], emptyStatuses: [] },
get_prompt_configuration: { method: 'GET', path: '/v1/scopes/{scope_id}/prompts/{prompt_key}', location: null, scopeMode: 'none', pathParameters: ['scope_id', 'prompt_key'], queryParams: [], headerParams: [], successStatuses: [200], emptyStatuses: [] },
generate_prompt_demonstrations: { method: 'POST', path: '/v1/scopes/{scope_id}/prompts/{prompt_key}/demonstrations', location: "body", scopeMode: 'none', pathParameters: ['scope_id', 'prompt_key'], queryParams: [], headerParams: [], successStatuses: [200], emptyStatuses: [] },
get_connection_identity: { method: 'GET', path: '/v1/connection/identity', location: null, scopeMode: 'none', pathParameters: [], queryParams: [], headerParams: [], successStatuses: [200], emptyStatuses: [] },

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.

[P1] 新增公开操作后两个已提交的插件 bundle 没有重建,js-test / cindy-test 判红

本行把 get_connection_identity 写进 dsh 的 src/operations.generated.ts,但同目录里提交进仓库的构建产物 lib/index.js 没跟着重建。head 18d8dd86 的 run 41312505106 / job 124871192360(dsh-package)在 Rebuild 之后对 lib/ 做 diff,直接失败:

diff --git a/integrations/dsh/plugins/powercontext/lib/index.js b/integrations/dsh/plugins/powercontext/lib/index.js
@@ -1600,6 +1600,17 @@ const OPERATIONS = {
+	get_connection_identity: {
+		method: "GET",
+		path: "/v1/connection/identity",
...
make: *** [Makefile:173: js-test] Error 1

同一 run 的 cindy-package(job 124871192469,make cindy-test Error 1)以同样方式失败在 integrations/cindy/plugins/powercontext-hooks/node/worker.cjs —— 而 integrations/cindy/ 在本 PR 里根本没被修改。也就是说:凡是从 openapi/powercontext.yaml 生成、又提交进仓库的 bundle 都必须整体重跑,只补 src/operations.generated.ts 不够。

影响:dsh 与 cindy 两个宿主实际发布的 bundle 里没有该操作的映射(请求会落到未定义操作分支),而 PR 正文「regenerate Python, Rust, TypeScript and integration operation contracts」只覆盖到 src/;同时 gateway/desktop 之外的 JS 侧门禁因此对 head 是红的。

建议:用 scripts/generate_js_operations.py 全量重跑并提交 integrations/{pi,opencode,dsh,cindy}/** 的全部产物(含 lib/、node/*.cjs),本地确认 make js-test 与 make cindy-test 的重建 diff 为空再推。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Confirmed on 18d8dd8 and the latest attempt of run 41312505106: rebuilding adds get_connection_identity to the committed DSH lib/index.js and Cindy node/worker.cjs, so both drift checks still fail. Please rebuild and commit the matching bundles before merging. Reusing this thread for the same unresolved issue.

Comment thread openapi/powercontext.yaml
get:
tags: [access]
summary: Observe the current connection identity without readiness probes
operationId: get_connection_identity

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.

[P1] 新操作的 access.self 分类没有登记,harness-validation / validate 判红

e2e/bub/tests/test_access_audit.py:297 要求 OpenAPI 里所有 x-powercontext-access.action == access.self 的 operationId 集合精确等于 e2e/bub/src/powercontext_e2e/access_audit.py:52 的 ACCESS_OPERATIONS。本行新增的 get_connection_identity 声明了 access.self,但没有登记,head 18d8dd86 的 run 41312505106 / job 124871193100 失败:

E       AssertionError: assert {'check_acces...indings', ...} == frozenset({'c...ources', ...})
E         Extra items in the left set:
E         'get_connection_identity'
e2e/bub/tests/test_access_audit.py:297: AssertionError
========================= 1 failed, 304 passed =========================
make: *** [Makefile:116: harness-check] Error 1

影响:该集合同时承担「哪些操作不返回 Scope 内容」的审计分类,缺项使 make harness-check 在 head 上为红,新操作也不在访问审计的分类表里;server_wide 那条断言通过,说明只需补 Access API 这一侧。

建议:把 get_connection_identity 加进 ACCESS_OPERATIONS(与 get_access_principal 同类:只返回调用者自身、不含 Scope 内容),并在本地跑 make harness-check 复核。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reproduced on 18d8dd8: test_every_server_wide_operation_is_classified_by_whether_it_returns_scope_content still fails because get_connection_identity is absent from ACCESS_OPERATIONS. The latest CI attempt fails at the same assertion, preventing downstream harness Acceptance from running. Please register the new access.self operation in the audit classification. Reusing this thread rather than opening a duplicate.

@hireview001 hireview001 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  • CI failed: CI result (failure).
  • CI failed: harness-validation / validate (failure).
  • CI failed: dsh-package (failure).
  • CI failed: cindy-package (failure).
  • CI failed: Main (failure). Failed steps: cindy-package / Build and test the standalone Cindy archive; dsh-package / Test DSH package; harness-validation / validate / Validate harness and Compose definitions.

@knqiufan knqiufan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed 18d8dd8. Please address the readiness/context interaction inline and the existing unresolved bundle drift and Access audit classification findings, confirmed in their original threads. OCR did not finish 16 of its 40 selected files because of its tool-round limit; the reported findings were independently verified.

Comment thread desktop/ui/src/app/Connections.tsx Outdated
Comment on lines +606 to +607
void action("readiness", () =>
desktopApi.probeReadiness(profile.id, profile.revision),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Keep readiness probes out of global context-pending state

action() calls onPendingChange(true), which App counts as contextPending. With an active connection and selected Scope, start a delayed readiness probe and navigate to Memories: the Scope selector and Memory input/operations remain disabled until the probe finishes, although neither the connection nor Scope changed. I reproduced this with the App component and deferred mocked IPC; the controls recover only when the probe resolves. Use a separate diagnostic busy state so a potentially slow model/dependency probe does not block independently authorized Memory and Scope operations.

Copilot AI balanced review requested due to automatic review settings November 2, 2026 13:12

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@hidb4ai

hidb4ai commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Re-reviewed 6015e058. The previously reported authenticated legacy-profile digest mismatch is addressed by the separate current-client qualification and Bearer/Principal checks.

The current CI run is still blocked: Python 3.14 unit tests failed when test_parent_death_does_not_prove_native_child_exit[systemd-False] read an empty readiness file; other selected jobs were cancelled or skipped, including upgrade acceptance. The failing test and its native-command path are unchanged by this PR, so the log alone does not establish a PR regression. Please rerun the required checks and confirm the resulting upgrade and CI gates.

Copilot AI balanced review requested due to automatic review settings November 4, 2026 04:09

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@hidb4ai

hidb4ai commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Re-reviewed a7ed24bd against base 63e9665c. The authenticated legacy qualification remains present for both previously supported Bearer profiles, and the existing qualification records retain their identities.

The latest required CI is still red: the SeekDB migration jobs for Python 3.11 and 3.14 each hit the 25-minute step timeout. The OceanBase long-query shard reports exit 124 for the 600-term hybrid CJK scenario, although pytest had printed it as passed before the process deadline. The logs do not establish that these failures were caused by this PR. Please investigate or rerun the failed required checks before merging.

Copilot AI balanced review requested due to automatic review settings November 4, 2026 12:42

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@knqiufan knqiufan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address the inline findings before merging. The new identity path still gates authorized Desktop work on observation access, and the product qualification harness can report success against a different wheel. After integrating #2220, verify identity, Memory, and get_stats against the same pinned Server artifact.

});
let discovery = DiscoveryResult::assess(discovery, compatible);
let supported_operations = discovery.supported_operations();
let connection_identity = if supported_operations

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] Preserve authorized Scope and Memory access when observation is denied

A real enforced SQLite Server can return 200 from /v1/connection/identity and allow Scope/Memory requests for a scoped Principal while returning 403 from /v1/server-info. Here the 403 yields no supported operations, so Desktop skips the identity endpoint and cannot activate the qualified business path. The new identity branch also rechecks deployment through the same observation-gated endpoint. Please preserve trusted qualification and deployment/Principal fencing while allowing this supported authorization combination, and cover it through the native client.

Comment thread desktop/tests/real_server.py Outdated
raise HarnessFailure("wheel_count")
wheel = wheels[0]
compatibility = fixture_profile()
compatibility = selected_qualification(desktop, qualification_id, product=product_qualification)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] Verify the actual wheel before reporting product qualification

--wheel and --qualification-profile select independent inputs. All four SQLite modes passed and were labeled bundled-product when the actual wheel digest differed from the selected record's artifactSha256. The native probe compares catalog metadata rather than the wheel bytes. Please reject a mismatch before extracting or starting the Server; label evidence for a rebuilt wheel separately.

error: Some(SafeError::CompatibilityUnverified.into()),
})
} else {
None

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Restrict Principal-only fallback to explicitly qualified legacy profiles

With the bundled sqlite-atomic-afa13bcb-v1 profile and Bearer auth, a Server that retains its server_id but omits connection.identity from discovery still activates and searches using only /v1/access/me. The selected profile requires the new identity contract. Please choose fallback from the selected qualification policy and fail closed for current profiles when their required identity operation is missing or incompatible.

id: &str,
revision: u32,
) -> Result<DesktopState, ApiFailure> {
let _permit = self.probes.try_acquire().map_err(|_| SafeError::Busy)?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Allow a connection switch while another profile is probing readiness

Pausing profile A's /health/ready makes activation of B immediately return Busy because both paths share the same probes permit. Connections also disables activation during the probe. This is separate from the earlier global pending issue: Scope and Memory are available, but users cannot leave a slow Server for a working one. Please let the switch cancel or supersede the old probe and continue rejecting late results.

Comment thread desktop/ui/src/app/TopBar.tsx Outdated
<p className="menu-note">
{t.accessMode}: {report?.identity.value?.mode ?? t.unverified}
{t.accessMode}:{" "}
{report?.connectionIdentity

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Use the same Access mode fact in the menu and connection details

With a successful connectionIdentity and a failed legacy access/me request, this menu displays the new Access mode but the Connections card still renders report.identity and shows an error or unverified. Please use a shared precedence rule for the mode, retaining the legacy fact only for a qualified legacy profile.

@hireview001 hireview001 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  • Resolve merge conflicts with the target branch.

Copilot AI balanced review requested due to automatic review settings November 5, 2026 02:22

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@hidb4ai

hidb4ai commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Re-reviewed 4141311e. The qualified observation-denial, current-identity fallback, readiness-switch and wheel-verification changes address the earlier reported paths in the current source.

The PR is currently blocked by merge conflicts with master (2772b2ab when checked). A local merge calculation identifies .github/workflows/e2e-harness.yml, .github/workflows/master.yml and scripts/run_atomic_memory_clean_migration.py. Please reconcile the CI sharding/deadline behavior with the current baseline without dropping required checks.

The latest CI run also failed in Python 3.14 unit test test_a_body_that_outlives_its_slice_is_repeated_not_dropped; the selected upgrade acceptance was skipped and its release gate failed. That test and implementation are unchanged in this PR, so this log alone does not establish a PR regression. Please rerun the required checks after resolving the conflicts.

Copilot AI balanced review requested due to automatic review settings November 5, 2026 12:11

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

Copilot AI balanced review requested due to automatic review settings November 6, 2026 10:10

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@hidb4ai hidb4ai 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.

LGTM

@hidb4ai
hidb4ai merged commit 842b6c3 into oceanbase:master Nov 6, 2026
77 of 78 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.5.1 v1.5.1 release tracking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants