Skip to content

feat(git): add approval-gated advanced workflows - #120

Merged
Qiyuanqiii merged 1 commit into
mainfrom
codex/issue-117-git-advanced
Aug 20, 2026
Merged

Qiyuanqiii merged 1 commit into
mainfrom
codex/issue-117-git-advanced

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Aug 20, 2026 •

Copy link
Copy Markdown
Member

摘要

  • 新增严格版本化的 git-advanced.v1:以封闭 operation union、capability、preview、typed failure、conflict、receipt 和兼容版本替代 raw Git argv;模型、HTTP、CLI 与 Desktop 均不能提供 Shell、可执行文件、环境、host path、任意 ref expression 或自定义 test command。
  • 实现内容寻址的 hunk stage/unstage/revert。hunk identity 同时固定 base/index blob、整文件 worktree SHA-256、上下文和 exact patch;执行前重新生成 diff,selected-hunk 的 before/after hash(含 no-final-newline)必须与 preview 一致,旧行号或漂移 preview 不可执行。
  • 实现 stash create/list/show/apply/pop/drop:使用 exact stash OID 和 parent role,不接受不稳定的 stash@{n};tracked/index/untracked 分开投影,ignored 永不进入 stash;apply/pop 在 review 与 Git 调用前均复核 ignored file/directory collision,冲突时 pop 保留原 stash。
  • 实现可持久恢复的 rebase/cherry-pick/bisect state machine。start/continue/skip/abort/mark/reset 固定 original ref、target、HEAD、sequencer digest、conflict graph 和 generation;重启只观察和收敛,不重放未知命令;自动 bisect 仅允许两种 Go-owned recipe、1–128 step、1–900 秒 timeout 和 whole-process-tree reap 证据。
  • 实现受管 worktree list/create/lock/unlock/remove/prune。目标路径只能由 Go 在 managed root 下推导,永久绑定 common-dir/name/branch/commit/Run/Workspace;create 不复用路径/branch/name,remove 无 force 且复核 live HEAD/branch/common-dir 与 tracked/untracked/ignored clean,prune 不接触未登记的外部 worktree。
  • Schema v123 新增 immutable operation、generation-CAS sequence 与 never-reused managed-worktree registry;每项 mutation 使用一次性 git.advanced Approval、Workspace Checkpoint、operation-key、proposed -> running CAS、common-dir 单一 running fence、append-only events 与 typed terminal receipt。
  • 打通 cyberagent git-advanced、read/control bearer HTTP/OpenAPI、Desktop/React 高级 Git面板和 startup reconciliation;公共 DTO 隐藏 lease ID、managed host path、raw persistence JSON、argv、环境和进程身份。
  • review 升级到 1.4.0,focused-checks 升级到 1.1.0;合并 Issue feat(code-intel): Go-owned LSP Runtime 与只读语义工具 #116 的 LSP 主线后,同时消费 source-bound LSP evidence 与完整 merge-base diff、stable hunk、base/ours/theirs、worktree/recovery evidence。

Closes #117.

协议与操作矩阵

git-advanced.v1 是 closed protocol,不是 Git command transport。每个 operation 只接受自己的字段,跨 operation 字段、重复 identity、非规范路径、非 exact OID、未知字段和超限输入在 review 前失败。

Family Operations 精确输入 恢复与默认拒绝
Hunk hunk_stage / hunk_unstage / hunk_revert SHA-256 hunk IDs、可选 literal paths 全仓 binding 重验;每次写入前 Checkpoint;binary/combined/symlink/submodule/ambiguous index stage 拒绝
Stash stash_create / stash_apply / stash_pop / stash_drop audit message 或 exact stash OID tracked/index/untracked role;ignored 不包含;冲突 pop 不 drop;ignored collision 双重 fence
Rebase rebase_start / continue / skip / abort exact upstream/onto 或 durable sequence ID clean attached local branch;protected/shared/detached rewrite 拒绝;不提供 force push
Cherry-pick cherry_pick_start / continue / skip / abort ordered exact single-parent commits 或 sequence ID conflict durable;merge commit input、protected/detached branch 拒绝
Bisect bisect_start / good / bad / skip / run / reset exact good/bad/current commit、sequence ID、closed recipe bounded step/time;closed stdin;tree reap required;reset 恢复 original ref
Worktree worktree_create / lock / unlock / remove / prune safe name/branch/commit 或 durable worktree ID Go-derived managed path;不复用、不 force remove、不 adoption external worktree

协议级固定上限包括 200 hunks、200 paths、128 commits、64 KiB spec JSON 和 1 MiB preview patch;SHA-1/SHA-256 object repository 均使用 exact lowercase object identity。

Preview、Approval、Checkpoint 与 exactly-once fence

每项 mutation 采用同一 durable flow:

  1. discovery/preview 只读捕获 repository/common-dir identity、HEAD/branch、raw index、worktree/status、stash、sequencer、upstream、object format、impact graph 和 capability generation;
  2. Application 重读 active Run/Mission/Session/Workspace、Code/Deliver + Local + network-disabled profile、permission snapshot/revision、active Workspace lease/generation,并把这些 private authority facts 加入 approval fingerprint;
  3. review 创建 immutable operation 和 pending one-time git.advanced Approval;preview 本身不授权执行;
  4. execute 重新生成 preview、重验 repo/authority/sequence/worktree,并建立 schema v117 Workspace Checkpoint boundary;
  5. 只有取得 proposed -> running CAS 且赢得 exact common-dir 单一 running fence 的 caller 可以调用 Git;
  6. terminal transition 原子保存 typed receipt、sequence/worktree generation 和 append-only Run events;相同 operation-key/相同意图 replay 返回同一结果,不同意图冲突;
  7. startup reconciliation 对 running 记录只观察、不重放。无法证明命令是否已完成时记录 interrupted/failed,绝不猜测成功。

每次操作都建立 Checkpoint。preview 和 receipt 会明确披露不完整恢复:Workspace snapshot 能恢复有界文件与 raw index(包括 conflict stage 1/2/3),但不能保证复活已删除的 stash/ref、受管根中的外部 worktree 内容、进程、服务、网络或 Workspace 外文件。

Hunk 与 stash 的内容安全

  • discovery 使用 bounded textual、no-rename、full-index diff;所有 caller path 使用 literal pathspec。
  • hunk ID 覆盖 operation/path/base/index/worktree/context/patch,不按旧行号盲目应用。
  • preview 的 before_sha256 来自真实 source bytes,after_sha256 来自仅应用所选 hunks 的内存结果;执行前再次投影并逐项比较。
  • 文件消失、no-final-newline 状态变化、未选择 hunk 漂移、repository-wide binding 漂移都会要求重新 review。
  • stash list/show 不暴露 selector,只返回 exact stash/base/index/untracked parent 与 bounded role/hash evidence。
  • keep_index 与 restore_index 为显式字段;include-ignored、任意 stash pathspec 和 selector 不可表达。
  • apply/pop 同时检查 preview 时和命令前的 ignored collision;active rebase/cherry/bisect 在可能切换 commit 前再次检查,防止 Git 静默覆盖 status 隐藏的 ignored content。

Rebase、cherry-pick 与 bounded bisect

Rebase start 只允许 reviewed upstream 为 HEAD ancestor 的 clean attached local branch;存在 configured upstream 时按 shared history 处理并拒绝改写。Cherry-pick 只接受有序 exact single-parent commits。两者保存 original HEAD/branch、targets、current HEAD、sequencer SHA-256、conflict objects、generation 和 originating operation。

continue/skip/abort 只接受 durable sequence ID,并要求 live HEAD/sequencer 与 SQLite 行一致;外部执行 git rebase --continue 或 git cherry-pick --continue 后不能用旧 preview 被静默接纳。冲突 receipt 投影 base/ours/theirs 与可用 recovery action。

自动 bisect 只有两种固定 recipe:

  • go_test:go test -count=1 ./...;
  • npm_test:仓库固定的 offline npm validation launcher。

调用者只能选择 1–128 steps 与 1–900 秒 per-step timeout,不能提供 argv/Shell/executable/environment/network。每步绑定 exact commit、关闭 stdin、使用 stripped offline environment 和 whole-process-tree runner;缺少 tree_reaped、timeout、cancel 或 budget exhaustion 均产生 typed failure。这里的 offline 环境不是 OS 网络沙箱,repository test code 仍是显式审批后的 host execution。

Managed worktree 生命周期

目标路径固定为 <managed-root>/<common-dir-fingerprint-prefix>/<safe-name>,调用者不提交 destination。registry 永久保存 path digest、repository/common-dir、branch、commit、Run、Workspace、generation 和 creating/last operation;name 即使 remove 后也不复用。

managed root、common-dir 子目录、目标和父路径在 preview 与 mutation 前都检查 POSIX symlink 和 Windows junction/reparse traversal。remove 不带 --force,同时复核 registry/live HEAD、branch、common-dir、tracked、untracked、ignored 和 lock state;外部 commit drift 即使 worktree clean 也拒绝删除。prune 只处理 product registry 中已 missing 且 path hash 精确匹配的项。

create 成功但 registry persistence 前崩溃时,reconciliation 只可登记 path/common-dir/branch/commit 全匹配、clean、unlocked、attached 的 exact target;原 operation 仍保持 failed/interrupted,不会伪造成功 receipt。

Git 进程与安全边界

Git 使用替换环境并忽略 system/global config。实现显式关闭或拒绝:

  • hooks、credential helpers、prompt、pager、interactive sequence editor、external diff、fsmonitor、system attributes 和 LFS smudge;
  • repository-local executable filter/diff/merge drivers;
  • commit signing/signing agent、recursive submodule checkout;
  • rebase autoStash/updateRefs、rerere auto-resolution;
  • force push、reset-hard、clean-force、remote deletion、arbitrary refspec、raw argv 和 external worktree path。

固定 no-op ordinary editor 仅允许 rebase --continue 使用 sequencer 已有 message,不启动用户编辑器。Windows case alias、.git path component、unsafe/quoted path、symlink/junction、submodule、detached HEAD、protected/shared branch、fork/upstream/base drift、literal pathspec metacharacter、cancellation、process-tree failure 与真实 conflict 都有回归覆盖。

CLI、HTTP、Desktop 与文档

CLI:

cyberagent git-advanced status|discover-hunks|preview|run [operation]
  --run <run-id> --enable-git-advanced --enable-permission-control [...typed flags]

preview/不带 --confirm 的 run 不创建 mutation;run --confirm 才创建并批准 exact proposal 后执行。process capability 默认关闭,SQLite 中的旧记录不能在重启后重新启用它。

HTTP/OpenAPI:

GET  /api/v1/runs/{run_id}/git-advanced
POST /api/v1/runs/{run_id}/git-advanced/discover-hunks
POST /api/v1/runs/{run_id}/git-advanced/review
POST /api/v1/runs/{run_id}/git-advanced/execute

projection/discovery 使用 read bearer;review/execute 使用独立 control bearer。所有 body 为 128 KiB 内 closed JSON,unknown/duplicate field、GET body、重复 query、URL/body Run mismatch 和 stale generation 均拒绝。

Desktop 仅在 bootstrap capability 开启时显示“高级 Git”,并呈现 authority generation、repo/branch/upstream、hunk patch、stash role、base/ours/theirs conflict、sequence action、bisect progress、worktree state、Checkpoint limitation、Approval 与 immutable receipt;renderer 不接收 private lease ID 或 host path。

同步更新 README 中英文、usage、HTTP API、architecture、Desktop test matrix、Task/Status/Progress/Memory、独立 docs/git-advanced.md 与 ADR 0122。

主线兼容性与生成契约

最终 head f9cedc5 基于 origin/main@715591a(PR #119 / Issue #116 LSP Runtime)。rebase 解决 13 个冲突,保留:

  • code-intel-lsp.v1 的 CLI/OpenAPI/Desktop/model-tool 路径与 runtime capability;
  • Advanced Git 的新 CLI/OpenAPI/Desktop 路径与独立 process capability;
  • 合并后的 focused-checks@1.1.0(SHA-256 f5a6de08275e074efae00749bc2404a925fbc6a88ec25f37fcd1e9d8c69df28c);
  • 合并后的 review@1.4.0(SHA-256 9248f38a13048894382b0b79a9188ac1eb14d05f908f22b5f63a46a1c2feb07a);
  • schema v122 → v123 连续迁移与完整历史 migration chain。

OpenAPI/TypeScript 连续生成字节一致:

  • 144 paths / 160 operations / 419 schemas;
  • OpenAPI SHA-256:116952142fb55bae2cfbe9b13f7e5742f16d14760989d0618acd0e6a43e240f8;
  • TypeScript binding SHA-256:2cb61016a393b5160bf6c37a2751f5d80bff5b5184aaddbd35290af860b284a4。

验收条件对应

  • hunk stage/unstage/revert 使用内容指纹、expected source/result hash 与 execution-time revalidation;HEAD/index/worktree/status/stash/sequencer/upstream 漂移拒绝旧 preview。
  • stash tracked/untracked/index role、exact OID、keep/restore index、conflict-retained pop、ignored collision 和 lossy drop recovery limitation 已实现并测试。
  • rebase/cherry-pick start/continue/skip/abort 在 conflict、cancel、crash/restart 和 external sequencer drift 下具有 durable generation state machine,不重复应用命令。
  • bisect start/mark/run/status/reset 使用 exact commit、closed recipe、step/time bound、whole-tree ownership;reset 恢复原引用。
  • worktree create/lock/unlock/remove/prune 不越出 managed root、不复用 name/path、不 adoption 外部 worktree、不删除 unknown/dirty/drifted content。
  • 每项 mutation 都有 exact preview、Approval、Workspace Checkpoint、operation-key/CAS、typed receipt 和 append-only audit event。
  • force/shared rewrite、credential helper、hooks、signing、custom driver、recursive submodule、raw argv 和任意 test command 默认不可用并有明确诊断。
  • Windows/Linux case/path/link、junction/symlink、submodule、detached/protected/shared branch、fork/upstream/base drift 与真实 conflict fixture 已纳入跨平台测试;本机完成 Windows 真实 Git,Linux test binaries 全量交叉编译,Linux runtime 由 CI 执行。
  • review / focused-checks 可消费完整 merge-base diff、stable hunk、conflict、worktree、Checkpoint 与 recovery evidence,并保留 LSP source evidence。
  • unit、integration、race、fault injection、real Git、OpenAPI、Desktop/React 和双语文档完成。

本地验证

最终重放主线后的完整发布门:

  • go test -p 2 -count=1 -timeout 30m ./...:全仓通过;Store 748.018s、Application 499.105s、HTTP 133.862s、repository 101.197s、CLI App 98.970s。
  • Advanced Git + LSP 定向 -race:repository 83.453s、Application 74.034s、Store 18.235s、HTTP 12.104s、CLI App 11.568s、codeintel 1.478s。
  • 小包完整 -race:gitadvanced 1.327s、workspacecheckpoint 13.279s、Desktop 35.400s。
  • go test -tags "desktop,wv2runtime.error" -count=1 ./cmd/cyberagent-desktop ./internal/desktop ./internal/webui:0.772s / 20.282s / 0.425s。
  • ordinary + Desktop-tag go vet、new-code scoped staticcheck、go mod verify、go mod tidy -diff、git diff --check 通过。
  • GOOS=linux GOARCH=amd64 CGO_ENABLED=0 编译全部 58 个 Go test binary 通过。
  • npm run check:api、strict TypeScript、完整 Web tests(65 files / 288 tests)、production build 通过;现有 React act/jsdom canvas/query warning 与 Monaco chunk warning 未升级为失败。
  • npm audit --audit-level=high:0 vulnerabilities。
  • Rust fmt、locked tests(7 + 2)、Clippy 通过;重放前在线 RustSec audit 通过,最终 cargo audit --no-fetch --no-yanked 使用 1217 条缓存 advisory 扫描 41 个 locked dependency 通过;Cargo.lock 未变化。
  • OpenAPI/TypeScript 连续生成一致;计数和 SHA-256 如上。
  • 39 个变更 Go 文件均通过 gofmt drift check;74 个变更文件不含 .env、SQLite/WAL、node_modules、Rust target、Desktop build 或其他本机运行时产物。

已知主线/本机验证说明

无过滤 staticcheck -checks='SA*,S1*,QF*' ./... 返回 8 项既有告警:

  • internal/application/command_runtime.go:145 SA4006;
  • internal/codeintel/real_lsp_test.go:181 S1016;
  • internal/fileedit/fileedit.go:215 SA9003;
  • internal/plugins/package.go:281 SA1019;
  • internal/projectconfig/projectconfig.go:183 SA4005;
  • internal/sandbox/docker_container_io_export.go:291/294 的 SA1019 / SA4011 / S1023。

以上 6 个文件相对 origin/main...HEAD 均无 diff,本 PR 不把扩大扫描误写为 zero-warning;新增代码的 scoped scan 通过。

第一次默认并发全仓运行在 main 原样的 TestCommandRuntimeForegroundCancellationReapsProcessTree 遇到一次 Windows 负载敏感 cleanup deadline;隔离普通 20 次和 race 5 次均通过。随后完整 Application 复验在 main 原样、整个流程只有 500ms deadline 的 TestUIEvidenceDeadlineReapsBuildJobBeforeApplicationLaunch 中提前耗尽 source revalidation;隔离普通 20 次通过,race instrumentation 5 次中有 2 次复现 deadline 阶段漂移。最终项目惯用的 -p 2 全仓门完整通过,因此没有把两个未修改的主线测试或产品实现夹带进 #117。

本机 Go 1.26.5 的 govulncheck ./... 如实报告 5 项可达标准库 advisory:GO-2026-6218、GO-2026-6090、GO-2026-6089、GO-2026-5972、GO-2026-5026,均标记由 Go 1.26.6 修复。本 PR 未新增 Go module 依赖,不把该结果写成 zero finding。最终在线 RustSec refresh 曾遇到网络错误,因此当前 head 只声明使用最新本机 1217-advisory 缓存的 audit;不会把网络失败包装成在线通过。

安全审计

  • 逐层复核 closed union、literal pathspec、exact OID/hunk、repo/common-dir/authority binding 和 execution-time revalidation;raw argv 与跨 operation 字段不可达。
  • 复核 ignored collision、selected-hunk projected hash、no-final-newline、root redirect、case alias、.git path、symlink/junction、submodule 和 managed remove/prune deletion fence,并补充负向回归。
  • 复核 Git process environment,明确关闭 signing、helpers、hooks、external diff、custom drivers、recursive submodule、autostash/updateRefs/rerere 与用户 editor。
  • 复核 Approval/Checkpoint/CAS/common-dir fence、immutable terminal facts、crash-window reconciliation 和 public DTO redaction;running command 不 replay,unprovable success 不升级。
  • 复核 browser closed parser 与 Desktop retained approval review;renderer 不能以 capability display 或 stale preview 自行授权 mutation。
  • No credentials, tokens, local paths, raw prompts/tool output, databases or runtime artifacts are included.

非目标与残余边界

  • 不提供 force push、reset-hard、clean-force、远端 ref 删除、共享历史改写、任意 Git/Shell、任意 bisect command 或自动 ours/theirs 选择。
  • 不实现 GitHub review thread、CI log、remote comment write-back;这些属于 [Epic] LSP 代码智能、高级 Git 与 GitHub 审阅协作 #107 后续 provider/review workflow。
  • Checkpoint 不保证恢复 deleted refs/stash object、外部 worktree 内容、Workspace 外文件、进程、服务或网络副作用;限制在 preview/receipt 中显式披露。
  • Go/npm bisect recipe 会在宿主执行仓库代码;stripped/offline environment、Approval 和 process ownership 是降险与审计边界,不是 OS network/filesystem sandbox。
  • 本地没有进行 signed Desktop release、人工 Windows 10/11 GUI 矩阵或远端 destructive Git smoke;跨平台与发布结论以本 Draft PR 的 CI/维护者验收为准。

Audit

  • No credentials or local runtime data are included.
  • Policy, Workspace Scope, Approval, Checkpoint, process, repository, managed-path, recovery and persistence boundaries were reviewed.
  • README 中英文、usage/HTTP/architecture/Desktop guide、ADR、Project Status、Progress/Memory/Task Book 和 generated OpenAPI/TypeScript binding 已同步。

CI 状态

最终 head f9cedc5 的 GitHub Actions 全部通过:

  • CI run 32396488102:Go control plane 20m43s、TypeScript 1m10s、Rust 55s、真实 LSP(Ubuntu 1m50s / macOS 1m12s / Windows 2m19s)、macOS Desktop 2m52s、Windows Desktop 9m32s、真实 Edge UI evidence 1m53s,全部成功。
  • Desktop release run 32396488158:dependency/license boundary 1m00s,可复现并验证的 Portable ZIP 8m01s,全部成功;GitHub Release 发布在 pull request 事件上按设计 skipped。

@Qiyuanqiii
Qiyuanqiii marked this pull request as ready for review August 20, 2026 18:56
@Qiyuanqiii
Qiyuanqiii merged commit 015c858 into main Aug 20, 2026
12 checks passed
@Qiyuanqiii
Qiyuanqiii deleted the codex/issue-117-git-advanced branch August 20, 2026 18:57
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.

feat(git): hunk 级操作、高级恢复与 Worktree

1 participant