From 01240ce787f06e01aafbc2956b500078b6310905 Mon Sep 17 00:00:00 2001 From: Pierre Brisorgueil Date: Wed, 3 Jun 2026 16:58:33 +0200 Subject: [PATCH] fix(skills/update-stack): switch drift gate scan to git diff (catches missing-locally case) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace `git ls-files` iteration (locally-present files only) with `git diff --name-only devkit-vue/master HEAD` (bidirectional). Adds a second BLOCK arm for files present upstream but absent locally — the previous scan silently skipped deleted stack files. Closes #4233 --- .claude/skills/update-stack/SKILL.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.claude/skills/update-stack/SKILL.md b/.claude/skills/update-stack/SKILL.md index 3071ab00c..2c93882e0 100644 --- a/.claude/skills/update-stack/SKILL.md +++ b/.claude/skills/update-stack/SKILL.md @@ -101,17 +101,21 @@ git fetch devkit-vue master --quiet drift_found=0 while IFS= read -r f; do - upstream_blob=$(git ls-tree devkit-vue/master -- "$f" 2>/dev/null | awk '{print $3}') - [ -z "$upstream_blob" ] && continue # downstream-only file — skip - local_blob=$(git rev-parse "HEAD:$f" 2>/dev/null) - if [ "$upstream_blob" != "$local_blob" ]; then - echo "BLOCK: drift on shared stack file: $f" + # Both sides exist + differ → drift + if git cat-file -e "devkit-vue/master:$f" 2>/dev/null && git cat-file -e "HEAD:$f" 2>/dev/null; then + echo "BLOCK: drift on shared file: $f" echo " Fix A — revert to upstream: git checkout devkit-vue/master -- $f" echo " Fix B — promote upstream: open a devkit PR with the change, merge, /update-stack here" echo " Fix C — relocate: move logic to a downstream-only module or src/config/defaults/.config.js" drift_found=1 + # Upstream has it, local doesn't → missing-locally + elif git cat-file -e "devkit-vue/master:$f" 2>/dev/null; then + echo "BLOCK: missing locally (was on upstream): $f" + echo " Fix — restore: git checkout devkit-vue/master -- $f" + drift_found=1 fi -done < <(git ls-files src/modules src/lib src/config 2>/dev/null \ + # Downstream-only file (not in upstream) → skip silently +done < <(git diff --name-only devkit-vue/master HEAD -- src/modules src/lib src/config 2>/dev/null \ | grep -vE "/(tests|__tests__)/" | grep -vE "\.(test|spec)\.(js|jsx|ts|tsx|vue)$") [ "$drift_found" -eq 1 ] && exit 1 @@ -120,7 +124,7 @@ echo "3ter: no drift — OK" **Rules:** - Block on ANY shared-file divergence. No "declare and skip" path — the `DOWNSTREAM_PATCHES.md` ledger model was abandoned 2026-06-02 (memory `feedback_no_dev_in_shared_modules`). -- Scan covers the full stack tree (`src/modules`, `src/lib`, `src/config`) — auto-discovers every shared module. Per-file `git ls-tree` on upstream filters downstream-only files. +- Scan source is `git diff --name-only devkit-vue/master HEAD` (bidirectional) — catches both files that differ AND files present upstream but missing locally (deleted downstream). The previous `git ls-files` approach only saw locally-present files. - Test files (paths containing `/tests/` or `/__tests__/`, or filenames ending `.test.{js,jsx,ts,tsx,vue}` / `.spec.{js,jsx,ts,tsx,vue}`) are excluded — downstream test adaptations are acceptable. - E2E helpers under `src/lib/helpers/e2e/` ARE scanned — they are stack-managed. Downstream modification triggers BLOCK; use Fix B (promote upstream) if a downstream needs e2e helper changes. - `src/modules/app/app.router.js` historically diverged on every downstream (downstream routes). Under no-ledger this must be refactored: `app.router.js` does NOT currently expose an extension hook — the refactor needs to add one (e.g. a `registerDownstreamRoutes()` call sourced from a downstream-only module like `src/modules/{project}/{project}.router.js`), then keep `app.router.js` stack-iso. Until that refactor lands, this gate will BLOCK on every Vue downstream `/update-stack`.