Skip to content

fix(core): restore protocol Rust integration tests (#915) - #928

Merged
LIghtJUNction merged 2 commits into
wip/rust-core-go-extensionsfrom
cursor/fix-protocol-rust-tests-a270
Oct 16, 2026
Merged

LIghtJUNction merged 2 commits into
wip/rust-core-go-extensionsfrom
cursor/fix-protocol-rust-tests-a270

Conversation

@LIghtJUNction

@LIghtJUNction LIghtJUNction commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

变更说明

问题与关联 Issue/PR:

Fixes #915。

默认分支 wip/rust-core-go-extensions tip 278ef81e 上,clippy::result_large_err 已经不存在。protocol 作业仍在 cargo test 退出 101,证据是 PR #925 head f452cdb4d / run 38921283189 的 Rust checks and real database tests:

  1. tests/browser_sessions_independent.rs 三个用例在 runtime_database::check 报 UnsafePrivileges
  2. tests/payments_process.rs 的非忽略用例缺少密封输入 LMM_PAYMENT_CORE_BIN(302 秒用例保持 #[ignore])
  3. oauth2_pi_independent::revoked_expired_stream_retains_original_hold_until_authoritative_reconciliation 在 start_oauth 返回 StaleWorker

本 PR 不改 #925 的 RPC Docker 脚本。

MK-01 identity(run 38928672624)在 head 51d79011 上失败。对照基线 278ef81e 与该 head、在 PostgreSQL 17 上复现后,这些失败在基线上同样存在,与本 PR 的授权脚本改动无关,因此不在这里改测试、目录指纹或 MK-01 workflow。

为什么采用此方案:

  • 浏览器会话测试执行的是官方 grant-core-runtime.sql。该脚本在安装 owner 不存在时会 ROLLBACK,但 \quit 1 被当前 psql 忽略(extra argument "1" ignored),进程仍以 0 退出。测试因此把未授权角色当成授权成功。未执行 REVOKE TEMP 时,has_database_privilege(..., 'CREATE,TEMP') 为真,runtime_database::check 返回 UnsafePrivileges。在补上 NOLOGIN lmm_core_owner 并真正提交 GRANT 之后,同一套官方授权能通过 web_identity + oauth2 的运行时检查。拒绝路径改为在 ON_ERROR_STOP 下 RAISE EXCEPTION,退出码 3。
  • OAuth 恢复用例把租约和硬截止都设成 1 秒。reserve 用秒级 clock_timestamp() 记下租约,随后的 start_oauth 只要跨过这一秒就会按围栏返回 StaleWorker。CI 上 reserve 加串行事务很容易跨秒。同一文件里使用 30 秒默认租约的 start_oauth 是通过的。修复保持“先成功派发,再过期,撤销后的持仓要保留到权威对账”:使用正常租约完成 start_oauth,然后在 SERIALIZABLE 事务里把 lease_until 拨到过去(charging 写入拒绝 read committed)。金额、保留额度、退款和 oauth_source 断言没有放宽。
  • 支付恢复用例本来就要求密封的 Core、Go 宿主和 bootstrap 三组路径与 SHA-256。protocol 步骤只导出了 LMM_MODEL_PROCESS_*。这里复用同一次编译的 lmm-core、前面已经构建的 Go 宿主,以及 go test -c 得到的 payments 测试二进制,不把该用例改成 skip。302 秒用例仍然忽略。

复用了什么,替代或删除了什么:

复用官方授权脚本、现有 runtime_database::check、charging 的显式租约过期,以及 workflow 里已经构建的 Core / Go 宿主。删除的是无效的 \quit 1。没有删除测试或断言。

可能破坏的行为、外部契约或数据路径:

不安全运行时角色执行 grant-core-runtime.sql 时,进程现在以非零退出,而不是回滚后仍显示成功。安全角色的 GRANT 语句没有改。支付用例会在 protocol 的 cargo test 里实际启动 Core 和 Go 进程。

上游来源与许可证影响(不适用时说明):

不适用。没有引入新依赖。

验证证据

审查基点 SHA:278ef81e6e87364891c80de6b03a2c8724934fe1

实际测试的 HEAD 与工作区摘要:

HEAD 51d79011aa9b2b8eb31564f199e86630ad4c70c1,工作区干净,没有新的代码提交。本地 agcc 不可用,未做写监视。Rust 1.99.0。先前的 protocol 自测使用 PostgreSQL 18.6。下面的 MK-01 对照使用 PostgreSQL 17.11(Ubuntu 17.11-1.pgdg24.04+2),监听 127.0.0.1:5432,连接串与 MK-01 workflow 相同。

修复前失败、修复后通过的命令与日志:

修复前:run 38921283189 中上述三个测试目标失败。

授权脚本拒绝路径(超级用户运行时角色):

psql -v runtime_role=deny_super -f deployment/postgres/grant-core-runtime.sql
exit 3
ERROR: Refusing unsafe runtime role or login-enabled installation owner.
ROLLBACK
cd services/core && cargo fmt --all -- --check
# exit 0

node --test scripts/workflow-topology.test.mjs
# 12 passed

DATABASE_URL=... cargo test --locked --test browser_sessions_independent --test oauth2_pi_independent -- --test-threads=4
# browser_sessions_independent: 3 passed
# oauth2_pi_independent: 10 passed; 1 failed(当时的 lease UPDATE 未使用 SERIALIZABLE,25001)

DATABASE_URL=... cargo test --locked --test oauth2_pi_independent -- --test-threads=4
# test result: ok. 11 passed; 0 failed; finished in 5.33s

# 与 CI 相同的三组密封输入:debug lmm-core、go build ./cmd/extensions、go test -c ./internal/modules/payments
DATABASE_URL=... cargo test --locked --test payments_process -- --test-threads=1
# real_core_and_go_payment_accepted_proof_survives_expiry_and_os_restart ... ignored
# real_core_and_go_payment_credit_commit_before_local_receipt_crash ... ok
# test result: ok. 1 passed; 0 failed; 1 ignored; finished in 88.13s

MK-01 失败:基线与 PR head 对照

git diff 278ef81e6..51d79011 只改了 core-protocol.yml、grant-core-runtime.sql、browser_sessions_independent.rs、oauth2_pi_independent.rs。失败用例的源码、services/core/schema、oauth2_balance 和 mk-01-identity.yml 两边相同。目录指纹查询明确不含 owner 与 GRANT。这些失败用例走 tests/common/runtime.rs 里的测试授权,不执行官方 grant-core-runtime.sql。

同一套命令在基线 detached worktree 278ef81e6 和 PR head 51d79011 上各跑一次。Rust +1.99.0,cargo test --locked,PostgreSQL 17.11:

cargo test --locked --lib core_schema::index_tests::current_schema_index_predecessor_upgrade_changes_only_verified_index_and_two_receipts -- --exact
# 两边都是 exit 101
# left  25dd836558a77b4b3b4a4a1d9e2d95d026e676d2f25aa38544f703109ffde1c3
# right 660ddf6f75c0350c93ae2886951312997c82c4bc6ebcf5d79a561de629781bad

cargo test --locked --no-fail-fast --test cli --test model_process --test oauth2_lmm_author --test oauth2_lmm_http --test payments_process -- --test-threads=4
目标 基线 278ef81 PR head 51d7901 MK-01 run 38928672624
index predecessor 失败,哈希同上 失败,哈希同上 失败,哈希同上
cli usage_index_owner_cli_upgrades_only_fresh_prior_fixture_and_rejects_runtime 12 passed, 1 failed,Error: Storage at tests/cli.rs:1093 同左 同左
model_process 0 passed, 7 failed,tests/model_process.rs:94 Option::unwrap() on None(LMM_MODEL_PROCESS_ROOT 未设置) 同左 同左
oauth2_lmm_author 7 passed, 4 failed,Unavailable / balance(...).is_ok() 为假 同左 同左
oauth2_lmm_http tcp_readonly_... 3 passed, 1 failed,status 503,期望 200 同左 同左
payments_process 非忽略用例 0 passed, 1 failed, 1 ignored,缺少 LMM_PAYMENT_CORE_BIN 同左 同左

同一 head 的 protocol 作业使用固定的 postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873,并导出 LMM_MODEL_PROCESS_* 与 LMM_PAYMENT_*。run 38928672599 的 cargo test 中,index predecessor、usage_index_owner_cli_...、model_process(7 passed)、oauth2_lmm_author(11 passed)、oauth2_lmm_http(4 passed)、payments_process(1 passed, 1 ignored)都通过。MK-01 使用未固定的 postgres:17-alpine,且不导出这些密封变量。目录钉 660ddf6f... 对得上 PostgreSQL 18,对不上 PostgreSQL 17 的反解析结果 25dd8365...。CLI 的 Storage 是同一枚钉被升级过程拒绝。OAuth 的 Unavailable / 503 也只在 PostgreSQL 17 上出现。model_process 与 payments_process 则是 MK-01 没有 protocol 那组环境变量。

因此没有把目录钉改成 PostgreSQL 17 的哈希(那会让 protocol 的 PostgreSQL 18 作业变红),也没有放宽断言或改 MK-01 的数据库大版本。

重构的行为保持证据,或明确的业务语义差异:

运行时权限矩阵没有放宽。1 秒租约仍会被 live() 判为 StaleWorker;变的是这个恢复用例不再用 1 秒租约去完成派发。支付 302 秒用例仍被忽略,非忽略用例实际跑过 Core/Go 重启入账。

quick / related / full 的报告、失败、受阻及未执行项目:

未跑 just check、在 PostgreSQL 18 上重跑完整 cargo test --all-targets、Go race、RPC Docker。MK-01 对照只跑了上面列出的失败目标,没有在基线上重跑整个 --all-targets。自测通过的是本 PR 自己的 protocol 用例;MK-01 这些失败保持为基线既有失败。独立验收未执行。

当前 CI(head 仍是 51d79011,本次没有新提交):

用户可见变化的浏览器证据;核心变化的同环境资源对比(适用时):

无前端变化。

必须独立审查的内容

门禁、测试断言、类型配置、阈值、锁文件、基线或例外的变更与理由:

  • grant-core-runtime.sql 的失败退出方式
  • protocol workflow 新增的 LMM_PAYMENT_* 密封输入;未使用 --skip 或 --ignored
  • OAuth 恢复用例改为显式过期,断言未改
  • 本次没有为了让 MK-01 变绿而改目录指纹、断言或 workflow

高风险业务、临时方案的责任人、到期时间与退出条件:

授权脚本和计费恢复属于高风险路径。没有临时开关。

独立审查者与证据(尚未执行请写 pending,作者不能自行批准):

pending

提交前核对

  • 一个明确目标,无夹带格式化、重命名或架构重写;已核对重复工作及被删除内容的消费者。
  • 没有通过跳过测试、删除有效断言、测试专用成功分支或降低门槛换取通过。
  • 模块测试、真实业务验收、未执行与受阻项目已区分;构建成功未冒充完整验收。
  • 已更新受影响的文档和配置;代码及提交证据不含凭据、DSN 或用户私密数据。
Open in Web Open in Cursor 

cursoragent and others added 2 commits October 16, 2026 15:53
The official runtime grant script used psql \quit with an exit status, which
psql ignores, so a refused grant exited 0 after rollback. Browser session
tests then checked an unprovisioned role and failed with UnsafePrivileges.
Create the required NOLOGIN installation owner first, and make refusal fail
under ON_ERROR_STOP.

The OAuth recovery case started on a one-second lease that CI can expire
before dispatch. Start on the normal lease, then expire it explicitly.

Wire sealed Core, Go host, and payment bootstrap binaries into the protocol
Rust test step so the non-ignored payment recovery case runs.

Co-authored-by: LIghtJUNction <lightjunction.me@gmail.com>
Charging updates reject read committed. The recovery test moves
lease_until inside a serializable transaction after a successful start.

Co-authored-by: LIghtJUNction <lightjunction.me@gmail.com>

Copy link
Copy Markdown
Collaborator Author

Bot follow-up (2026-10-17 00:45 Asia/Taipei)

CI on head 51d79011:

已在同一分支启动 CloudAgent bc-2e17ae0c 对比 base 278ef81e 与本 PR 定位根因;若由本 PR 引起则修复(不放宽断言/权限),若为既有问题则在 PR 描述里记录证据。保持 Draft,未合并。

@LIghtJUNction
LIghtJUNction marked this pull request as ready for review October 16, 2026 17:13
Copilot AI balanced review requested due to automatic review settings October 16, 2026 17:13

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ⚠️ Failed 2026-10-16T17:13:37.513371Z 51d7901 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@LIghtJUNction
LIghtJUNction merged commit a901a60 into wip/rust-core-go-extensions Oct 16, 2026
0 of 2 checks 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.

ci(protocol): 默认分支 Rust checks 新失败 — clippy::result_large_err(services/core/src/remote_control.rs:336)

3 participants