feat(runtime-host): add Gitoxide candidate and accepted-tree read data plane - #3857
Conversation
8de92c3 to
699e12d
Compare
|
Thanks for the adversarial review. I reworked the boundary around the findings instead of adding more checks to the previous combined capability model. The updated head is The main changes are:
Regression coverage now includes accepted/candidate separation, stale-base rejection before writes, exact retry, corrupt base-tree storage, typed no-change, owner-bound candidate proof, legacy helper feature rejection before destination claim, and HFS alias rejection. Verification for this head is green:
The PR remains Draft while this authority boundary is reviewed. 中文说明感谢这次对抗性审查。这轮没有继续给原来的混合 capability 叠加校验,而是重新划分了 owner 边界。当前 head 为 主要调整如下:
新增回归覆盖 accepted/candidate 分离、写入前 stale-base 拒绝、exact retry、损坏 base tree、typed no-change、owner-bound candidate proof、旧 helper feature 在 destination claim 前拒绝,以及 HFS alias 拒绝。 当前 head 的验证全部通过:Gitoxide helper 的 Ubuntu/macOS/Windows、Windows recovery,以及完整 CI(build、typecheck、format、Runtime Host、Desktop e2e、Storybook、CLI release candidate)。 PR 继续保持 Draft,等待这次 authority 边界复审。 |
|
Thanks for the adversarial re-review. I addressed the three protocol blockers at their shared evidence-owner boundary in 1. Candidate construction now consumes verified tree bytesThe helper no longer calls
A regression performs the full verified walk, replaces a nested loose tree object under the old OID, and proves candidate editing fails instead of deriving from the replacement bytes. 2. Published and no-change now share one linear outcome authorityBoth success dispositions now create a deterministic receipt commit and CAS the same operation-derived candidate ref. The receipt binds a domain-separated request digest covering accepted ref, base commit/tree, candidate ref, path, and result bytes. This means:
Runtime Host issues one 3. Candidate outcome is bound to the exact accepted lineageThe private capability record now binds:
Consuming an outcome now requires presenting both owner tokens and the original accepted capability. A regression proves an outcome from repository A cannot be consumed with repository B's capability even when both repositories contain identical Git objects. Additional P1/P2 hardening
Durability scopeThe Git receipt commit/ref is durable, while accepted/candidate capabilities remain process-local in this slice. The architecture document now states this explicitly. Cross-Host reissuance remains owned by the later durable workspace-receipt/lifecycle layer, which must reopen the exact repository, revalidate the accepted ref/commit/tree, inspect the operation receipt, and then reissue capability. This PR no longer overstates same-process exact retry as cross-process reopen. Verification
The PR body has also been updated so it no longer claims that no-change omits a commit/ref, and it accurately records the deferred cross-Host reopen boundary. 中文说明感谢这轮对抗性复审。这次没有继续分别补条件,而是把三个协议级问题统一收敛到 candidate evidence owner:
同时完成了:
跨 Host 的 capability 重签发没有假装在本 PR 中完成:Git receipt commit/ref 已耐久,但 capability 仍是进程内 authority;后续 durable workspace receipt/lifecycle owner 需要重开 exact repository、重验 accepted identity、检查 operation receipt 后再签发。文档和 PR body 已明确这个范围。 验证方面,Rust 59 个测试通过;Ubuntu/macOS/Windows 三平台真实 helper gate 与 Windows recovery 均通过。通用 CI 的 build、typecheck、Runtime Host tests 也已通过,当前只剩仓库统一 Desktop e2e 仍在运行。 |
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found no blocking issues.
Implements two bounded capacities: immutable candidate result per operation (never touches accepted ref, TOCTOU double-check) and single UTF-8 read from owner-bound accepted tree (8MiB, canonical path). Hosted test/audit/owner/package/windows all SUCCESS.
No P0-P3.
简体中文
该头无阻断。Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.
08df97b to
16405e1
Compare
16405e1 to
e7356d9
Compare
|
Thanks for the careful re-review. I addressed the direct-ref blocker and the bounded follow-ups in
Verification on the rebased head:
中文说明感谢这轮细致复审。
重放到最新 |
e7356d9 to
26b4c4a
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for taking the Gitoxide boundary seriously here. The accepted ref remains the sole repository authority, candidate creation returns a bounded receipt, and the read path validates object identity instead of introducing a parallel repository state. That overall direction is sound.
I reviewed exact head 26b4c4a31777c6b37b82362ac82b354cc627a311 and found two reachable issues:
- P1 — category ②, reasonable release/capability mismatch:
admitGitoxideRepositoryInternal()invokesinspect_repositorywithout requiring that operation in the helper’s attested capability set. Likewise,importAdmittedGitoxideRepositoryInternal()checks onlycreate_candidateandread_tree_filebefore invokingimport_source_head. The invocation layer verifies the artifact but does not enforce operation support, so a helper can be accepted and then asked to execute an operation it never attested. Because operation-level release attestation is a load-bearing authority in this design, please require the actual operation at each entry point and add negative tests for a helper that lacksinspect_repositoryorimport_source_head. - P2 — category ②, reasonable crash/object-store recovery path: candidate retry and the new self-check compare the result blob OID recorded in the tree, but do not load and checksum-verify that blob. A missing or corrupt blob can therefore still let the operation report success. Please verify the blob through the existing verified-object path, retain the 64 MiB bound, and cover missing/corrupt blob cases.
The first issue needs to be closed before approval; the second should be fixed but does not independently block. The rest of the authority model is notably clean, and I do not think this needs a broader redesign.
Review analysis was assisted by Codex and independent @reviewer agents; Astro-Han verified the exact-head call graph, capability checks, failure reachability, and CI state and owns this review.
中文对照
感谢你认真处理 Gitoxide 的权威边界。accepted ref 仍然是唯一的仓库权威,candidate creation 返回有界 receipt,读取路径也验证对象身份,没有引入平行的仓库状态;整体方向是对的。
我审查了当前提交 26b4c4a31777c6b37b82362ac82b354cc627a311,发现两个可达问题:
- P1 — ② 合理的发布/能力不匹配路径:
admitGitoxideRepositoryInternal()调用inspect_repository前,没有要求 helper 的能力证明中包含该 operation;同样,importAdmittedGitoxideRepositoryInternal()在调用import_source_head前只检查了create_candidate和read_tree_file。调用层只验证 artifact,没有校验 operation 支持,因此 helper 可能被接受后,又被要求执行它从未证明支持的操作。既然 operation 级发布证明是该设计中的关键权威,请在每个入口要求实际会调用的 operation,并补 helper 缺少inspect_repository或import_source_head的负向测试。 - P2 — ② 合理的崩溃/对象存储恢复路径: candidate retry 和新的 self-check 会比较 tree 中记录的结果 blob OID,但不会真正加载并校验该 blob。这样在 blob 丢失或损坏时,操作仍可能报告成功。建议通过现有 verified-object 路径验证 blob,保留 64 MiB 上限,并覆盖 blob 丢失/损坏的用例。
第一个问题需要在 Approve 前关闭;第二个应该修,但它本身不单独阻塞。其余 authority 设计比较干净,我不认为需要更大范围的重构。
本次分析由 Codex 和独立的 @reviewer agents 协助;Astro-Han 核验了当前提交的调用图、能力检查、故障可达性和 CI 状态,并对本次评审负责。
|
从奥卡姆剃刀的角度重新捋了一遍,我认为这个 PR 的核心问题其实很简单,而且方向没有问题: 这个 PR 只拥有 stage,不拥有最后的 promote。因此 candidate creation 不能推进
所以我不认为这里需要重新设计更小的核心模型。当前更需要改进的是实现闭环和文档表达:
总结:stage + CAS + later promote 的问题定义已经足够简单;核心架构成立。当前阻塞点是 attestation 没有在实际 operation 入口闭环,完整性改进点是 result blob 没有被真正读取并 checksum 验证。 |
|
Addressed both findings at their owning boundaries in
Local verification:
中文说明
本机 Runtime Host 构建和定向测试通过;Biome、rustfmt、Windows inventory、ASF header 与 diff check 通过。本 Windows 环境缺少 MSVC linker,因此新增 Rust 可执行测试交由正在运行的三平台 Gitoxide CI 验证。 |
|
Follow-up: the first Ubuntu run exposed a portability issue in the new corruption fixture, not in the verifier. Gitoxide creates loose objects read-only on Linux, so the test could not overwrite the object ( 中文说明补充:首次 Ubuntu CI 暴露的是新增损坏夹具的跨平台权限假设,并非 verifier 失败。Gitoxide 在 Linux 上创建的 loose object 是只读文件,旧夹具直接覆盖时先触发 |
dee348f to
444481b
Compare
|
Thanks for the precise retry-integrity review. The finding was valid: the prior exact-retry path proved the requested path/blob edge and general policy, but it did not prove that the receipt tree was exactly the deterministic one-path successor of the verified base. I fixed this at the candidate-tree owner boundary in
Two production-shaped real-helper regressions now forge otherwise valid receipt commits while preserving the parent, signatures, request digest, path, and result blob:
Both exact retries fail closed. The full Rust suite passes: 14 unit + 54 real-repository tests (68 total). I also rebuilt the complete PR stack onto current 中文说明感谢这次精确定位 exact retry 的完整性缺口。这个问题成立:旧实现虽然证明了目标 path/blob edge 和通用 tree policy,却没有证明 receipt tree 恰好是 verified base 的唯一单路径 successor。
新增两条真实 helper 回归:在保留 parent、signature、request digest、path 和 result blob 均合法的前提下,分别伪造“额外文件”和 同时整个 PR 已重建到当前 |
444481b to
2dfa1d8
Compare
|
The failed general CI was isolated to Desktop WorkHub e2e, not the Gitoxide data plane. All dedicated Gitoxide and Windows recovery gates passed. The first run failed two late WorkHub rendering/reconstruction assertions; a failed-job rerun failed three WorkHub UI assertions, while build, typecheck, workspace tests, and Runtime Host tests all passed both times. The branch was one commit behind current
中文说明通用 CI 的失败已定位到 Desktop WorkHub e2e,与 Gitoxide 数据面无关;专用 Gitoxide 三平台和 Windows recovery 均通过。首次运行有两个 WorkHub 渲染/重建断言在末段失败,重跑又有三个 WorkHub UI 断言失败,但两次的 build、typecheck、workspace tests 和 Runtime Host tests 都通过。 分支当时比最新主线少一个 Runtime Host/session-context message/turn 变更,而当前
|
|
CI follow-up after the latest-main rebuild: the general job remains red only in unrelated Desktop WorkHub e2e. Evidence:
The repeated failures are 中文说明更新到最新主线后,通用 CI 仍只在无关的 Desktop WorkHub e2e 变红:
重复失败集中在 |
likun666661
left a comment
There was a problem hiding this comment.
Approved. The core boundary is appropriately narrow: construct immutable staged candidate B from accepted A, publish the operation receipt through CAS, and leave acceptance/promotion to the later lifecycle owner. The latest changes close the reviewed evidence gaps: exact operation attestation is enforced at each invocation, candidate result blobs are loaded and checksum-verified, and exact retry proves the entire deterministic one-path successor tree rather than only the requested path/blob edge. Dedicated Gitoxide checks pass on Ubuntu, macOS, and Windows, and Windows recovery passes. The remaining general-CI failure is isolated to unrelated WorkHub e2e and should still be handled according to repository merge policy.
2dfa1d8 to
650c5a3
Compare
650c5a3 to
58badae
Compare
Summary Add a Gitoxide candidate/read data plane on top of repository admission and source import from #3561. This revision intentionally keeps filesystem projection out of the protocol. It provides two bounded capabilities: - publish an operation-bound immutable candidate outcome without advancing the accepted ref; - read one bounded UTF-8 file directly from an owner-bound accepted tree. ## Primary invariant An accepted-repository capability represents one exact accepted SHA-1 commit/tree at the fixed
refs/maka/acceptednamespace. Accepted and candidate refs must be direct refs to verified commit objects; symbolic refs and annotated tags are rejected. Candidate creation may publish only an operation-specific receipt ref and owner-bound outcome capability. A later SQLite acceptance/promotion owner remains the only component allowed to establish a new accepted head. ## Ownership and atomic boundaries - Source import captures the verified helper, managed repository, fixed accepted ref/commit/tree, and managed-tree policy v3. - The release claim must attestcreate_candidateandread_tree_filebefore destination import is claimed. - Candidate requests bind the exact accepted capability/repository, helper artifact, policy, base commit/tree, operation-derived candidate ref, path, request digest, result SHA-256, and Git object identities. - A checksum-verifying tree finder owns every tree load used by candidate construction. - Published and no-change outcomes both create a deterministic receipt commit and linearize atrefs/maka/candidates/<sha256(operationId)>. - Existing candidate receipts are checked before any object write. Exact retries recompute the unique expected candidate tree from the verified base tree, inherited target mode, canonical path, and result blob without writing objects, then require the receipt tree to match exactly. They also revalidate the direct ref, receipt commit, parent, signatures, request digest, path, and result blob; conflicting requests returncandidate_request_conflictwithout creating new objects. - CAS failures that cannot establish a readable direct receipt returncandidate_publication_indeterminate. - Direct reads verify every traversed tree/blob identity and independently recompute the returned blob identity from the returned bytes. - Managed-tree policy v3 path semantics have one owner: the Rust helper. TypeScript enforces transport bounds and exact response correlation. ## Fail-closed behavior - Symbolic accepted/candidate refs and tag/non-commit targets fail closed with stable direct-ref errors. - Corrupt or replaced commit/tree/blob storage fails checksum verification. - The same operation cannot publish both no-change and changed outcomes. - Candidate ref conflicts never overwrite an existing outcome and are rejected before new object writes when already observable. - A candidate outcome cannot be consumed with a different accepted-repository capability, even when both repositories contain identical commits. - Helper timeout, abort, malformed output, result/blob mismatch, request-digest mismatch, artifact mismatch, or capability mismatch cannot issue an outcome capability. The second accepted-ref check and candidate-ref CAS are not one multi-ref transaction. Accepted-head drift in that narrow window may leave stale candidate evidence bound to the old base, but cannot advance accepted truth. The later SQLite acceptance owner must revalidate the canonical head and reject stale evidence. ## Durability scope Candidate receipt commits and refs are durable. Accepted and candidate capabilities are intentionally process-local in this enabling slice. Cross-Host reopen requires the later durable workspace-receipt owner to hold the storage-root lease and revalidate the exact repository, direct accepted/candidate refs, receipt checksum, request digest, base parent, candidate tree, and path/result blob before SQLite acceptance. Candidate retention/GC belongs to that later owner; this PR does not claim cross-Host reopen or GC. ## Verification - Rust unit and production-shaped helper tests: 68 passed on the current source (14 unit + 54 real-repository tests). - Runtime Host TypeScript build passed. - Focused Host boundary tests: 14 passed; 16 real-helper/platform tests remain conditionally selected by their required helper environment. - Rust formatting andgit diff --checkpassed locally. - The branch was rebased ontomain@6fca2f51e.中文说明
## 概要 本 PR 在 #3561 的 repository admission/source import 基础上,提供 Gitoxide candidate outcome 与 accepted-tree direct read 数据面;filesystem projection 仍留给后续 owner。 ## 主要不变量 accepted-repository capability 只代表固定refs/maka/accepted下的一个 exact SHA-1 commit/tree。accepted ref 与 candidate ref 都必须直接指向经过校验的 commit;symbolic ref 和 annotated tag 会被拒绝。candidate 只能发布 operation-specific receipt ref 与 owner-bound outcome capability,新的 accepted head 仍只能由后续 SQLite acceptance/promotion owner 建立。 ## 本轮收口 - 四个 ref 读取点统一改为 direct commit ref 校验; - 新增 symbolic accepted/candidate ref 与 annotated-tag target 的真实 helper 回归; - candidate ref 已存在时,在任何 object write 前重验 receipt;相同请求会从 verified base tree、目标继承 mode、canonical path 与 result blob 纯计算唯一 expected tree OID,并要求 receipt tree 完全一致;不同请求稳定返回candidate_request_conflict; - publication 状态无法确定时返回candidate_publication_indeterminate,不再混入笼统错误; - base tree inventory 在 successor walk 前释放,避免两套大型路径集合同时驻留; - 文档收窄 stale-ref 承诺:第二次 accepted 检查与 candidate CAS 不是同一个多 ref transaction,窗口内可能留下绑定旧 base 的 stale evidence,但不能推进 accepted truth,后续 SQLite owner 必须重新核验 canonical head。 ## 耐久范围 candidate receipt commit/ref 跨进程耐久,但 capability 仍是进程内 authority。跨 Host 重开需要后续 durable workspace-receipt owner 持有 storage-root lease,并重验 repository、direct refs、receipt checksum、request digest、base parent、candidate tree 与 path/result blob;candidate GC 也由该 owner负责。本 PR 不虚称已完成 cross-Host reopen 或 GC。 ## 验证 - Rust unit + production-shaped helper:68/68 通过(14 unit + 54 real-repository); - Runtime Host TypeScript 构建通过; - focused Host 边界:14 通过,16 个依赖真实目标平台 helper 的条件测试按环境选择; - Rust format 与git diff --check通过; - 分支已重放到main@6fca2f51e。