fix(kyberforge): give branch-aware advice for the refreshed apm lock
Why: the docs said to discard a refreshed apm.lock.yaml on a feature branch because the refresh records main's commit, but the branch's own lock records a (older) main commit too, and the SessionStart notice gave the same "commit or discard" advice on every branch. Implementation Notes: - check-apm-current.sh picks fixed advice by branch: commit or discard deliberately on the default branch (origin/HEAD, else main), discard and reinstall on a feature branch; the branch name is never interpolated. - README, AGENTS.md and ADR-0019 give the real reasons (no lock churn in the branch diff, deployed tree matches the committed lock), the cost (the session runs the older main) and that the next session start refreshes again. - ADR-0019's check-clean and stale-server claims restated to match apm's source. ADR: 0019 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,11 @@ command -v python3 > /dev/null 2>&1 || { echo "python3 required"; exit 77; }
|
||||
FAKE_BIN="$(mktemp -d)"
|
||||
WORK="$(mktemp -d)"
|
||||
trap 'rm -rf "$FAKE_BIN" "$WORK"' EXIT
|
||||
# The hook asks git which branch it is on. Stop git's discovery at the temp
|
||||
# root so a $TMPDIR that happens to sit inside a checkout cannot leak a branch
|
||||
# into the fixtures that are meant to be outside one.
|
||||
export GIT_CEILING_DIRECTORIES
|
||||
GIT_CEILING_DIRECTORIES="$(dirname "$WORK")"
|
||||
|
||||
# Mock `apm`. $1 chooses what `apm outdated` reports; $2 the exit code of
|
||||
# `apm update`. Sentinel files record whether update was actually invoked and
|
||||
@@ -124,6 +129,55 @@ else
|
||||
fail "emits valid JSON"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- lock advice follows the branch ---"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# ADR-0019: on the default branch the rewritten lock is a real update to commit or
|
||||
# discard; on a feature branch it is unrelated churn to discard. Outside a git
|
||||
# checkout (the fixture above) the neutral advice stands.
|
||||
advice_of() { json_field additionalContext <<< "$1"; }
|
||||
grep -q "commit it or discard it deliberately" <<< "$(advice_of "$out")" \
|
||||
&& pass "gives neutral lock advice outside a git checkout" \
|
||||
|| fail "outside a git checkout the advice should stay neutral"
|
||||
|
||||
if command -v git > /dev/null 2>&1; then
|
||||
REPO="$WORK/repo"
|
||||
mkdir -p "$REPO"
|
||||
git -C "$REPO" init -q -b main
|
||||
git -C "$REPO" -c user.email=probe@example.invalid -c user.name=probe \
|
||||
commit -q --allow-empty -m init
|
||||
touch "$REPO/apm.lock.yaml"
|
||||
|
||||
out="$(run_hook_in "$REPO" "$REPO")"
|
||||
grep -q "default branch, so commit it or discard it deliberately" <<< "$(advice_of "$out")" \
|
||||
&& pass "on main, says to commit or discard the lock deliberately" \
|
||||
|| fail "on main the advice should be commit-or-discard: $(advice_of "$out")"
|
||||
|
||||
git -C "$REPO" checkout -q -b feature/x
|
||||
out="$(run_hook_in "$REPO" "$REPO")"
|
||||
advice="$(advice_of "$out")"
|
||||
grep -qF "feature branch, so discard it: git checkout -- apm.lock.yaml && apm install" <<< "$advice" \
|
||||
&& pass "on a feature branch, says to discard the lock and reinstall" \
|
||||
|| fail "on a feature branch the advice should be discard-and-install: $advice"
|
||||
grep -q "commit it" <<< "$advice" \
|
||||
&& fail "on a feature branch the advice must not suggest committing the lock" \
|
||||
|| pass "on a feature branch, does not suggest committing the lock"
|
||||
echo "$out" | python3 -m json.tool > /dev/null 2>&1 \
|
||||
&& pass "feature-branch notice is valid JSON" || fail "feature-branch notice broke the JSON"
|
||||
|
||||
# A remote whose default branch is not `main` is honoured via origin/HEAD.
|
||||
git -C "$REPO" update-ref refs/remotes/origin/feature/x HEAD
|
||||
git -C "$REPO" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/feature/x
|
||||
out="$(run_hook_in "$REPO" "$REPO")"
|
||||
grep -q "default branch, so commit it" <<< "$(advice_of "$out")" \
|
||||
&& pass "reads the default branch from origin/HEAD when it is set" \
|
||||
|| fail "should treat origin/HEAD's branch as the default: $(advice_of "$out")"
|
||||
else
|
||||
echo " (git not on PATH — branch-specific advice cases not run)"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- stale, refresh fails ---"
|
||||
|
||||
Reference in New Issue
Block a user