fix(skills): fail upgrade unconditionally when canonical publish fails

A failed canonical publish only failed the upgrade when
hasDependentSkillRoot reported a non-universal link target; that helper
explicitly skipped universal agents, which are exactly the direct consumers
of ~/.agents/skills. On a universal-only machine (e.g. only Codex
installed), UpgradeSkillLocations* returned a nil error with nothing
installed, contradicting the documented "canonical publication is
mandatory and fails the upgrade loudly" contract.

Canonical publish failures now return an error unconditionally in both the
mono and multi branches, and hasDependentSkillRoot is removed. The test
that pinned the old standalone-does-not-fail-fast behavior now asserts
error propagation in both modes.
This commit is contained in:
玉澜 committed 2026-08-14 14:27:57 +08:00
1 parent f8af8dc1dc
commit 7cfaa1ca74
2 files changed
+18 -28

No files matched your search

+9 -8
View File
@@ -263,10 +263,14 @@ func TestCrossPlatformCoverageConfiguredAgentRootsMatchUpstreamAndCustomHomes(t
}
}
func TestCrossPlatformCoverageUpgradeCanonicalFailureOnlyFailsFastWithDependents(t *testing.T) {
func TestCrossPlatformCoverageUpgradeCanonicalFailureFailsFastUnconditionally(t *testing.T) {
for _, mode := range []string{"mono", "multi"} {
t.Run(mode, func(t *testing.T) {
home := withFakeHome(t)
withFakeHome(t)
// Canonical-only configuration (no non-universal dependents): a failed
// canonical publish must still fail the whole upgrade. Universal agents
// read canonical directly, so silently succeeding here would leave the
// machine without any usable Skill while reporting success.
testseam.Swap(t, &knownSkillDirs, []string{".agents/skills"})
testseam.Swap(t, &upgradeCopyDir, func(string, string) error { return errors.New("canonical denied") })
@@ -279,15 +283,12 @@ func TestCrossPlatformCoverageUpgradeCanonicalFailureOnlyFailsFastWithDependents
src = writeMultiBundle(t, src, "dingtalk-chat")
}
result, err := UpgradeSkillLocations(src)
if err != nil {
t.Fatalf("standalone canonical failure should be reported per-target, not fail fast: %v", err)
if err == nil || !strings.Contains(err.Error(), "canonical Skill 安装失败") {
t.Fatalf("canonical publish failure must propagate an error, got (%v)", err)
}
if len(result.Failed()) != 1 || len(result.Succeeded()) != 0 {
if result == nil || len(result.Failed()) != 1 || len(result.Succeeded()) != 0 {
t.Fatalf("result = %#v", result)
}
if hasDependentSkillRoot(home, filepath.Join(home, ".agents", "skills")) {
t.Fatal("canonical-only configuration unexpectedly has a dependent root")
}
})
}
}