Skip to content

fix(upload): opt-in Checkout with startup Guard contract validation (A+B) - #22

Merged
opendev9 merged 8 commits into
devfrom
fix/upload-guard-errors-ab
Oct 21, 2026
Merged

opendev9 merged 8 commits into
devfrom
fix/upload-guard-errors-ab

Conversation

@opendev9

Copy link
Copy Markdown

Supersedes #21 by folding the verifiable advantages of #20 into the opt-in Checkout model.

Scope

  • Disabled Checkout performs no Guard SQL at all (unchanged from fix(upload): keep normal writes independent of unfinished Checkout #21).
  • Enabled Checkout now validates the installed cf_edit_guard contract at startup: 15 reviewed columns and 4 indexes, read from information_schema only. A legacy 029 table fails once with CF_EDIT_SCHEMA_MISMATCH and the SQL package to apply, instead of turning every upload into SQL 1176 retries.
  • C barrier keeps the path-keyed single-table query and FORCE INDEX (cf_edit_guard_active); no cf_resource joins or 029 ledger.
  • Retry contract made explicit and tested: only a moved Branch HEAD is retryable; Guard/schema/ACL/SQL failures fail immediately.

Validation

  • go vet . passes.
  • go test -count=1 -run 'TestCF' . passes, including the new contract tests (legacy columns, text path_hash, missing/reversed active index, old resource key) and the retry regression test.

Not covered: full C/Go build, image build and DEV deployment. Companion Docker PR: fix/upload-guard-errors-ab (fresh-volume DDL initialization + read-only plan/check inventory). Hub #43 is unchanged and still required.

The opt-in model only probed table existence, so a legacy resource-keyed
cf_edit_guard or a missing cf_edit_guard_active index turned every upload into
opaque SQL 1176 retries. Validate the reviewed column/index contract once at
startup when Checkout is enabled and report CF_EDIT_SCHEMA_MISMATCH with the
SQL package to apply. Disabled Checkout still performs no Guard query at all.

The contract test covers the legacy 029 columns, text path_hash, missing and
reversed active index and the old resource primary key.
Extract cfBranchConflictRetryable so the retry contract is testable, and add a
regression test that Guard, schema, ACL, SQL and nil failures are never
retried. No behaviour change: genCommitNeedRetry already retried only ErrConflict.

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

代码评审(2026-10-21):方向认可,Checkout 关闭时不依赖 Guard、启动时验证已安装的 15 列/4 索引、只对 Branch HEAD 冲突重试,均符合本轮修复目标。

建议合并前收敛 fileserver/cf_v2_edit_fence.go 的 cfEditGuardQuery():当前仍按列探测旧 resourceStore,并保留 cf_resource JOIN 分支。既然启用 Checkout 的 Server 启动必经 cfV2GuardRequireCurrent() 并要求 path-keyed V2 Guard,这个旧分支在受支持运行态不可达,也与 PR 所述“无 cf_resource 依赖”不一致。可直接使用已审查的新查询、遇 SQL 故障 fail-closed,避免每次 Branch 更新重复查询 information_schema。补一条旧布局不能回退的回归测试即可。未要求全量编译;真实数据库/镜像验收在集成节点集中完成。

Startup already validates the 15-column/4-index path contract when Checkout is
enabled, so the final Branch transaction no longer re-reads information_schema
and the resource-keyed 029 fallback is removed. Runtime drift still fails
closed: any query error returns errCFEditGuard and the write is refused.
@opendev9

Copy link
Copy Markdown
Author

评审跟进(2026-10-21):

  1. 已删除旧 Guard 兼容分支。cf_v2_edit_fence.go 不再有 resourceStore / cf_resource 关联,提交事务只发一条 reviewed 查询:SELECT path FROM cf_edit_guard FORCE INDEX (cf_edit_guard_active) ... lease_expires_at>... FOR UPDATE。
  2. 已移除每次提交重复读取 information_schema:启动期 cfV2GuardRequireCurrent 已完成 15 列 + 4 索引校验,提交路径不再做元数据探测。
  3. 失败拒绝语义保持不变:Checkout 关闭时不发任何 SQL;开启但不可用、查询失败、路径非法时返回 errCFEditGuard 拒绝写入。
  4. 测试已同步:TestUploadGuardUsesReviewedPathQueryOnly 断言只有一条 Guard 查询且不含 information_schema/cf_resource;TestUploadGuardRefusesGuardFailures 覆盖查询失败、NULL 路径、相对路径。

验证:go vet . 与 go test -count=1 -run 'TestCF' . 通过;GitHub static 检查通过。

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

第二轮复审(b16a392):生产代码的 cfV2EditCheckUnscopedBranch() 已按上一轮要求收敛成单条 V2 Guard 查询,旧 resource fallback 已删除,认可该修复。但本轮新增测试尚不能作为合并通过证据,建议修正后再合并。

问题: 新增用例名为 TestUploadGuardUsesReviewedPathQueryOnly、TestUploadGuardRefusesGuardFailures、TestUploadCheckoutDisabledNeverQueriesGuard、TestUploadEnabledCheckoutRequiresInstalledGuard,此前报告执行 go test -run 'TestCF' 并不会匹配它们。并且 TestUploadEnabledCheckoutRequiresInstalledGuard 使用的 uploadGuardFixture 在 information_schema.COLUMNS 情况下只返回单列 COLUMN_NAME,但生产 cfV2GuardRequireCurrent() 实际 Scan() 五列(COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,IS_NULLABLE,COLUMN_TYPE),因此表存在的正例实际上会错误失败。请将模拟调整成与正式列/索引查询一致的完整 metadata 返回(也包含 STATISTICS 的五列与索引信息),然后执行 go test -count=1 -run 'Test(CF|Cf|Upload)' . 并报告通过结果。无需跑完整 MySQL/镜像构建;本轮只修夹具和测试命令即可。GitHub 当前绿色 static job 不执行这组 Go 单测。

@opendev9
opendev9 merged commit efe3c89 into dev Oct 21, 2026
1 check passed
@opendev9
opendev9 deleted the fix/upload-guard-errors-ab branch October 21, 2026 00:46
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.

2 participants