fix(gates): close the review findings in the gates and their docs
Two reproduced bugs in check-skill-version-bump: - The origin/main-tip check fired even when the pushed skill was byte-identical to main's tip, so a cherry-pick or backport failed a push that ships nothing. The merge-base intersectionea119d8added covers that only when some base carries the content, which a criss-cross history gives and a linear one does not. A new same_subtree compares tree object ids, so the exemption holds whatever route the history took. - The failure line reported "baseline: none" when the skill was absent at every merge-base but present at the tip, and the Fix: line then named no version. The author writes the natural 1.0.0 and gets a second blocked push. It now falls back to the tip's version. ADR-0022 is not amended: the documented behaviour does not change, andea119d8set the precedent by fixing the same failure class script-only.1614bceverified that executables.allow grants are version-blind and corrected ADR-0019, gates.md and apm.yml, but missed the gate script's own header and its operator-facing FAIL message, which still told the reader deployment was silently broken, and gates.md's hook summary, which still called it a silent-failure guard. All three now match. Also: README's offline guarantee carries the populated-apm_modules condition gates.md and AGENTS.md already state; the scripts/ layout row drops "sync" for the three deleted sync scripts; the check-rtk-prefix README rationale names the 12 subdirectory READMEs that survive rather than the skill-root ones this branch deleted; gates.md re-cites its three head -1 sites by enclosing function per its own :238 rule; and deploy-manifest drops a pointer to a provider-manifest.sh that has never existed on main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwD8Egs5r4ndqeFLmhusX2
This commit is contained in:
@@ -633,6 +633,77 @@ write_skill "$F" demo alpha 'version: "1.0.1"' "later body"; commit "$F" F3
|
||||
expect_fail "an unbumped edit on a criss-cross branch still fails, naming the baseline sha" \
|
||||
"alpha: 1\.0\.1 -> 1\.0\.1 \(not above merge-base [0-9a-f]{40}\)" "$F"
|
||||
|
||||
echo ""
|
||||
echo "--- 41. a cherry-picked fix identical to main's tip passes ---"
|
||||
# Case 40 pins the same property — content identical to main's tip ships
|
||||
# nothing — for a criss-cross history, where the merge-base intersection alone
|
||||
# already exempts the skill because one base carries that content. This is the
|
||||
# LINEAR shape, where no base does: the branch was cut before the fix landed on
|
||||
# main and then cherry-picked it, so the single merge-base predates the fix and
|
||||
# the skill reaches the tip comparison carrying exactly the tip's version. The
|
||||
# only escapes would be a spurious 1.0.2 — leaving main with two versions of
|
||||
# identical content — or a rebase the push does not otherwise need.
|
||||
#
|
||||
# C0 alpha 1.0.0
|
||||
# +-- main: FIX bumps alpha to 1.0.1 (origin/main)
|
||||
# +-- feature: cherry-picks FIX
|
||||
F="$(make_fixture)"
|
||||
(cd "$F" && git checkout -q main)
|
||||
write_skill "$F" demo alpha 'version: "1.0.1"' "fixed body"; commit "$F" "fix alpha"
|
||||
FIX_SHA="$(cd "$F" && git rev-parse HEAD)"
|
||||
# -x: without it the picked commit can come out byte-identical to FIX — same
|
||||
# tree, same parent, same author and committer second — and git reuses the sha,
|
||||
# so the branch silently fast-forwards onto main and the case under test is
|
||||
# gone. The trailer -x adds guarantees a distinct commit.
|
||||
(cd "$F" && git update-ref refs/remotes/origin/main main && git checkout -q feature \
|
||||
&& git cherry-pick -x "$FIX_SHA" > /dev/null)
|
||||
if [[ "$(cd "$F" && git rev-parse HEAD)" != "$FIX_SHA" ]]; then
|
||||
pass "fixture check: the cherry-pick made a distinct commit, not a fast-forward onto main"
|
||||
else
|
||||
fail "fixture check: the branch fast-forwarded onto main, so the tip is the merge-base"
|
||||
fi
|
||||
if [[ "$(cd "$F" && git merge-base --all origin/main HEAD | wc -l)" -eq 1 ]]; then
|
||||
pass "fixture check: the linear history has exactly one merge-base"
|
||||
else
|
||||
fail "fixture check: expected one merge-base, got $(cd "$F" && git merge-base --all origin/main HEAD)"
|
||||
fi
|
||||
if [[ -z "$(cd "$F" && git diff origin/main HEAD -- plugins)" ]]; then
|
||||
pass "fixture check: nothing under plugins/ differs between origin/main and the branch"
|
||||
else
|
||||
fail "fixture check: plugins/ differs, so this is not the case under test"
|
||||
fi
|
||||
expect_pass "a cherry-picked skill identical to main's tip passes without a further bump" "$F"
|
||||
# The ratchet still holds on the same shape: a further edit is no longer
|
||||
# identical to the tip, so the tip rule applies again.
|
||||
write_skill "$F" demo alpha 'version: "1.0.1"' "later body"; commit "$F"
|
||||
expect_fail "an unbumped edit on top of the cherry-pick still fails against the tip" \
|
||||
"alpha: 1\.0\.1 -> 1\.0\.1 \(not above origin/main tip\)" "$F"
|
||||
|
||||
echo ""
|
||||
echo "--- 42. the named baseline is the tip when no merge-base carries the skill ---"
|
||||
# A skill added on main after the branch was cut is absent at every merge-base,
|
||||
# so only the tip names a version — and the tip's is the version the push is
|
||||
# held to. Reporting "none" sends the author to the natural 1.0.0 and costs a
|
||||
# second blocked push on the same mistake.
|
||||
F="$(make_fixture)"
|
||||
(cd "$F" && git checkout -q main)
|
||||
write_skill "$F" demo delta 'version: "3.2.1"' "main's delta"; commit "$F" "add delta on main"
|
||||
(cd "$F" && git update-ref refs/remotes/origin/main main && git checkout -q feature)
|
||||
write_skill "$F" demo delta "" "branch delta"; commit "$F" "add delta on branch"
|
||||
expect_fail "a missing version names the tip's version, not 'none'" \
|
||||
"delta: metadata\.version missing or not MAJOR\.MINOR\.PATCH at HEAD \(baseline: 3\.2\.1\)" "$F"
|
||||
expect_fail "the baseline is never reported as none while the tip carries one" \
|
||||
"delta: metadata\.version missing or not MAJOR\.MINOR\.PATCH at HEAD \(baseline: [0-9]" "$F"
|
||||
# The same message shape for the SKILL.md-missing branch of the report.
|
||||
F="$(make_fixture)"
|
||||
(cd "$F" && git checkout -q main)
|
||||
write_skill "$F" demo delta 'version: "3.2.1"' "main's delta"; commit "$F" "add delta on main"
|
||||
(cd "$F" && git update-ref refs/remotes/origin/main main && git checkout -q feature)
|
||||
mkdir -p "$F/plugins/demo/.apm/skills/delta/references"
|
||||
echo "ref" > "$F/plugins/demo/.apm/skills/delta/references/x.md"; commit "$F" "delta without SKILL.md"
|
||||
expect_fail "a missing SKILL.md names the tip's version too" \
|
||||
"delta: SKILL\.md missing at HEAD \(baseline: 3\.2\.1\)" "$F"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
|
||||
Reference in New Issue
Block a user