fix(claude): stop stale .mcp.json residue outranking a project switch, and gate stale builds #106

Merged
michal merged 3 commits from worktree-fix-statusline-project into main 2026-08-10 15:52:51 +00:00
4 changed files with 31 additions and 4 deletions
Showing only changes of commit 96e27c8716 - Show all commits

View File

@@ -890,8 +890,14 @@ ships a binary missing whatever landed on main meanwhile, and `rpm -U --force`
overwrites the good one with it. That happened on 2026-08-10: a build from a overwrites the good one with it. That happened on 2026-08-10: a build from a
stale checkout replaced `/usr/bin/mcpctl` with one that had no `statusline` stale checkout replaced `/usr/bin/mcpctl` with one that had no `statusline`
command, months after the status line landed. `scripts/check-main-sync.sh` command, months after the status line landed. `scripts/check-main-sync.sh`
(sourced by `build-rpm.sh` and `build-deb.sh`) fetches `main`, compares, and fetches `main`, compares, and fails before any work happens, listing the commits
fails before any work happens, listing the commits you are missing. you are missing. It gates every path that produces something others consume:
`build-rpm.sh`, `build-deb.sh`, `build-mcpd.sh` (each is also run standalone, so
none can rely on another having checked) and `deploy-k8s.sh` — where a stale
branch would pin its sha in Pulumi and make it the cluster's source of truth.
`deploy-k8s.sh --dry-run` skips the check: it builds and cuts over nothing, and
blocking a read-only inspection only teaches people to export the escape hatch
permanently, disabling the gate for real deploys too.
```bash ```bash
git merge main # the fix git merge main # the fix

View File

@@ -16,6 +16,11 @@ if [ -f .env ]; then
set -a; source .env; set +a set -a; source .env; set +a
fi fi
# This pushes an image to the registry, so the same staleness gate as the package
# builds applies. Run standalone as well as from deploy-k8s.sh, hence its own copy.
source "$SCRIPT_DIR/check-main-sync.sh"
check_main_sync
# Push directly to internal address (external proxy has body size limit) # Push directly to internal address (external proxy has body size limit)
REGISTRY="10.0.0.194:3012" REGISTRY="10.0.0.194:3012"
IMAGE="mcpd" IMAGE="mcpd"

View File

@@ -84,8 +84,10 @@ check_main_sync() {
echo "" >&2 echo "" >&2
echo "ERROR: '$branch' is $behind commit(s) behind $base — refusing to build." >&2 echo "ERROR: '$branch' is $behind commit(s) behind $base — refusing to build." >&2
echo "" >&2 echo "" >&2
echo " Building now would package a binary without these, and installing it" >&2 # Deliberately artifact-agnostic: the same helper gates RPM/DEB packages, the
echo " would overwrite a good one with a version missing them:" >&2 # mcpd image, and the k8s deploy.
echo " Building now would produce an artifact without these, and shipping it" >&2
echo " would replace a good one with a version missing them:" >&2
echo "" >&2 echo "" >&2
git log --oneline --no-decorate "HEAD..$ref" | head -15 | sed 's/^/ /' >&2 git log --oneline --no-decorate "HEAD..$ref" | head -15 | sed 's/^/ /' >&2
if [ "$behind" -gt 15 ]; then if [ "$behind" -gt 15 ]; then

View File

@@ -80,6 +80,20 @@ cat <<EOF
EOF EOF
[ -f "$PULUMI_YAML" ] || die "Pulumi config not found: $PULUMI_YAML" [ -f "$PULUMI_YAML" ] || die "Pulumi config not found: $PULUMI_YAML"
# ── 0. Staleness gate ──
# Same hazard as the RPM build, with the cluster on the receiving end: a branch
# behind main deploys images missing whatever landed there, and the sha pinned in
# Pulumi makes that the new source of truth. Skipped for --dry-run, which builds
# and cuts over nothing — blocking a read-only inspection only teaches people to
# export MCPCTL_ALLOW_BEHIND_MAIN=1 permanently, which would disable the gate for
# the real deploys too.
if [ "$DRY_RUN" = true ]; then
warn "dry-run: skip the main-sync check"
else
source "$SCRIPT_DIR/check-main-sync.sh"
check_main_sync || die "branch is behind main — merge it before deploying"
fi
# ── 1. Test gate ── # ── 1. Test gate ──
if [ "$SKIP_TESTS" = true ]; then warn "skipping unit tests (--skip-tests)"; else if [ "$SKIP_TESTS" = true ]; then warn "skipping unit tests (--skip-tests)"; else
say "1/7 Unit tests (pnpm test:run)" say "1/7 Unit tests (pnpm test:run)"