Improve managed Git updates with remote preflight and safe staged refresh - #13
Open
Lowerce wants to merge 5 commits into
Open
Improve managed Git updates with remote preflight and safe staged refresh#13Lowerce wants to merge 5 commits into
Lowerce wants to merge 5 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR improves the managed Git source update path by:
The implementation follows the existing source authority, partial-update, staged replacement, and bridge execution models.
Motivation
Previously, a managed Git update prepared a new checkout before determining whether the remote commit had changed. This caused unnecessary Git and filesystem work for sources that were already current.
Long-running updates could also cross two existing limits:
The update path also relied on
lock.localPathduring checkout replacement. Managed checkout ownership therefore needed to be verified before any remote preflight, local reuse, rename, or replacement operation.Core changes
Remote commit preflight
For managed Git sources with a locked commit, the update path now:
originBranchis available;This makes the confirmed-unchanged path inexpensive while preserving the existing recovery behavior for uncertain or damaged states.
Branch-preserving staged refresh
When the remote commit has changed, the update path:
FETCH_HEADin detached mode.If local preparation fails, the update continues through the established clean clone, HTTPS fallback, and archive fallback sequence.
When
lock.originBranchis present, the same branch is used consistently by remote preflight, staged fetch, clean clone, and archive fallback. The clean-fetch path explicitly fetchesrefs/heads/<originBranch>before accepting the result, ensuring that the final checkout resolves to the requested branch rather than a same-named tag.Locks without
originBranchretain the established default-branch behavior.Managed checkout ownership validation
Before any update-side checkout operation, the service verifies that:
lock.localPathexactly matches<stateRoot>/source/<sourceKind>/<sourceId>;An invalid path returns
SOURCE_CHECKOUT_PATH_INVALIDbefore the referenced checkout is read or modified. External sources continue to leave the managed update path before managed checkout validation.PID-aware mutation locking
Mutation lock recovery now considers the owner process:
This keeps long-running updates serialized without leaving dead locks permanently behind.
Bounded desktop update execution
Desktop update commands use a dedicated timeout budget:
Selected source IDs are deduplicated before calculating the timeout. Overflow is handled explicitly, and the result is always capped at 15 minutes.
Update flow
Per-source fetch failures continue through the existing partial-update result model. Authority failures such as an invalid managed checkout path stop before checkout preparation.
Verification
npm run build@skill-flow/integration:fs-utils.test.ts— 6 passed@skill-flow/core-engine:source-checkout-service.test.tsandsource-authority-service.test.ts— 22 passed@skill-flow/query:source-lifecycle.test.ts— 50 passed中文概要
本 PR 对托管 Git 来源更新链路进行了以下改进:
实现继续沿用现有的 source authority、partial update、暂存替换和 bridge 执行模型。
背景
修改前,托管 Git 来源在确认远端 commit 是否变化之前,就会准备新的 checkout。因此,即使来源已经是最新状态,也会发生不必要的 Git 和文件系统操作。
长时间更新还可能跨越两个既有限制:
更新流程还会在替换 checkout 时使用
lock.localPath,因此必须在远端预检、本地复用、rename 和 replacement 之前验证托管路径所有权。核心改进
远端 commit 预检
对于已经记录 commit 的托管 Git 来源,更新流程现在会规范化 Git locator,在存在
originBranch时查询该精确分支,并比较远端 commit 与 lock commit。Commit 相同且本地 checkout 完整时会直接跳过 checkout 准备;无法确认远端 commit 时则进入既有的完整更新流程。这使已经确认未变化的来源能够快速完成,同时保留不确定状态和损坏状态下的恢复行为。
保持分支身份的暂存刷新
当远端 commit 已发生变化时,更新流程会:
FETCH_HEAD。如果本地准备失败,则继续使用既有的 clean clone、HTTPS fallback 和 archive fallback 流程。
当
lock.originBranch存在时,远端预检、暂存 fetch、干净 clone 和 archive fallback 统一使用同一分支。干净下载完成后还会明确 fetchrefs/heads/<originBranch>,确保最终 checkout 对应请求的分支,而不是同名 tag。没有记录
originBranch的 lock 继续使用既有的默认分支行为。托管 checkout 所有权校验
在任何更新侧 checkout 操作之前,服务会验证:
lock.localPath与<stateRoot>/source/<sourceKind>/<sourceId>完全一致;路径不合法时返回
SOURCE_CHECKOUT_PATH_INVALID,并在读取或修改目标 checkout 之前终止。External source 会在托管 checkout 校验之前退出该更新路径。感知 PID 的 mutation lock
Mutation lock 回收现在会判断持有进程的状态:
这可以保证长时间更新仍然保持串行,同时避免已经失去 owner 的锁永久残留。
有上限的桌面更新
桌面 update 命令使用独立的执行时间预算:
计算时间前会对 source ID 去重,同时显式处理整数溢出,最终结果始终不超过 15 分钟。
更新流程
普通来源 fetch 失败继续遵循既有的 partial-update 结果模型。托管路径不合法等 authority failure 会在 checkout 准备前终止。
验证
npm run build@skill-flow/integration:fs-utils.test.ts— 6 项通过@skill-flow/core-engine:source-checkout-service.test.ts与source-authority-service.test.ts— 共 22 项通过@skill-flow/query:source-lifecycle.test.ts— 50 项通过