Repository navigation
feat(desktop): make readiness explicit and verify connection identity - #2361
Conversation
There was a problem hiding this comment.
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: [] }, |
There was a problem hiding this comment.
[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 为空再推。
There was a problem hiding this comment.
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.
| get: | ||
| tags: [access] | ||
| summary: Observe the current connection identity without readiness probes | ||
| operationId: get_connection_identity |
There was a problem hiding this comment.
[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 复核。
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
- 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
left a comment
There was a problem hiding this comment.
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.
| void action("readiness", () => | ||
| desktopApi.probeReadiness(profile.id, profile.revision), |
There was a problem hiding this comment.
[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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
Re-reviewed The current CI run is still blocked: Python 3.14 unit tests failed when |
There was a problem hiding this comment.
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.
|
Re-reviewed 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. |
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
[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.
| raise HarnessFailure("wheel_count") | ||
| wheel = wheels[0] | ||
| compatibility = fixture_profile() | ||
| compatibility = selected_qualification(desktop, qualification_id, product=product_qualification) |
There was a problem hiding this comment.
[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 |
There was a problem hiding this comment.
[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)?; |
There was a problem hiding this comment.
[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.
| <p className="menu-note"> | ||
| {t.accessMode}: {report?.identity.value?.mode ?? t.unverified} | ||
| {t.accessMode}:{" "} | ||
| {report?.connectionIdentity |
There was a problem hiding this comment.
[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
left a comment
There was a problem hiding this comment.
- Resolve merge conflicts with the target branch.
There was a problem hiding this comment.
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.
|
Re-reviewed The PR is currently blocked by merge conflicts with The latest CI run also failed in Python 3.14 unit test |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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?
GET /v1/connection/identitythrough normal authentication andaccess.self. Return deployment, request Principal, authentication state and Access mode. Regenerate Python/Rust/TypeScript contracts, integration operation tables and DSH/Cindy/OpenCode bundles.7d89a97a3d417326c44b5dd79810d9e9d68f0d4fand one pinned wheel. Preserve historical records and add independently verified authenticated-client evidence for legacy112db11eand3cefa45a.--test-timeout 300. Required checks, no-skip assertions and incomplete-timeout evidence remain enforced.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.tomlpasses 114 tests, plus the spawned-process proxy recheck. Rust formatting, strict Clippy all targets and IPC drift checks pass.pnpm --dir desktop testpasses 195 tests with jsdom/mocked IPC. Frontend lint, generated drift, TypeScript and production build pass.python desktop/tests/real_server.py --product-qualification sqlite-identity-stats-7d89a97a-v1passes 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.desktop/VALIDATION.md.bdd26c664afdf966269d2eafb403a7ba05c740837577e2ac954e01878b843d7a, and OpenAPI SHA-2569aabe2565d9cbd36075be03a83b7370e07e38e9f25232e20dd47812aba65e508. Source and probe hashes are recorded in the validation guide.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.