export declare const VERSION_DRIFT_GUARD_SH = "# --- webpieces version-drift guard (pure sh \u2014 runs even when the installed guard bin is stale) -----\n# The committed shim is version-agnostic, so it keeps working right after a git pull, BEFORE the\n# matching pnpm install. That is exactly when node_modules can be STALE: an OLDER @webpieces than\n# package.json now pins, whose outdated validator rejects the NEWER webpieces.config.json with baffling\n# \"unknown rule\" errors. Detect that drift HERE (before exec'ing the possibly-stale bin): compare every\n# EXACT-pinned @webpieces/* version in the root package.json against the version actually installed in\n# node_modules; the first mismatch wins. Range specs (^ ~ workspace:*) are skipped, so they never\n# false-positive; best-effort \u2014 a version we cannot read is skipped. On drift we fall through to the\n# SAME fail-closed path as a missing bin (allow only pnpm install, deny the rest).\n#\n# pnpm CATALOGS: a dep pinned via \"catalog:\" / \"catalog:\" carries NO digit-version in package.json,\n# so the old scraper matched nothing and the guard was BLIND to it \u2014 DRIFT_PKG stayed empty and the\n# stale bin ran (the 2026-07 \"0.3.369 vs 0.4.405\" incident). Resolve those specs through the top-level\n# `catalogs:` block of pnpm-lock.yaml (catalog -> pkg -> resolved version) before comparing.\n#\n# THE SAME PASS ANSWERS FAULT U (2026-08-05). Scraping root package.json is also the only way to learn\n# whether @webpieces/ai-hook-rules is DECLARED at all, and that is the difference between \"not installed\n# yet\" (X, cured by pnpm install) and \"nothing asks for it\" (U, where pnpm install is a guaranteed\n# no-op). WP_PIN carries the first EXACT @webpieces pin found, so U's deny can prescribe the version the\n# rest of the repo is already on rather than an unpinned add. Both are set BEFORE the range/catalog\n# `continue`s, so a repo pinning the package by range still counts as having declared it.\nDRIFT_PKG=\"\"\nDRIFT_DECLARED=\"\"\nDRIFT_INSTALLED=\"\"\nWP_HOOK_PKG_DECLARED=\"\"\nWP_PIN=\"\"\nif [ -f \"$ROOT/package.json\" ]; then\n # Only when a @webpieces dep actually uses a \"catalog:\" spec do we scan the (possibly huge) lockfile \u2014\n # a cheap grep keeps the common, catalog-free repo from paying that cost on every tool call. One awk\n # pass over pnpm-lock.yaml emits \" <@webpieces/pkg> \" lines for the sh lookup below;\n # \\047 is a single quote (so this awk program carries none and stays safely single-quotable in sh).\n WP_CATALOGS=\"\"\n WP_WS_CATALOGS=\"\"\n # THE PIN LIVES IN pnpm-workspace.yaml, and the LOCK is only the fallback (2026-08-20).\n #\n # L0 used to learn the pin from pnpm-lock.yaml's `catalogs:` alone, while L1's WebpiecesVersions.readPin\n # reads pnpm-workspace.yaml. Two notions of \"the pin\", and the gap is exactly where the cure lands: an\n # agent told to raise this tree's pin edits pnpm-workspace.yaml, re-runs, and L0 still reports the OLD\n # number \u2014 because only `pnpm install` rewrites the lock \u2014 so it concludes the edit did nothing and\n # reaches for something worse. Reading the workspace manifest FIRST makes the edit visible immediately.\n #\n # It resolves the same two YAML shapes readPin does, and that is not optional: a repo pinning the whole\n # @webpieces family in lockstep writes the version ONCE as `&wp 0.4.669` and aliases the rest as `*wp`,\n # so an anchor-blind read silently nulls the leg on precisely the repos that pin most carefully. Both\n # `catalog:` (the default catalog) and `catalogs:` (named ones) are walked. A value that is not a plain\n # digit-version (a range) is NOT emitted, so a loose pinner falls through to the lock rather than being\n # compared against an incomparable spec.\n if grep -Eq '\"@webpieces/[^\"]*\"[[:space:]]*:[[:space:]]*\"catalog:' \"$ROOT/package.json\" 2>/dev/null && [ -f \"$ROOT/pnpm-workspace.yaml\" ]; then\n WP_WS_CATALOGS=\"$(awk '\n { n=0; while (substr($0,n+1,1)==\" \") n++; c=substr($0,n+1) }\n c==\"\" || substr(c,1,1)==\"#\" { next }\n {\n ai=index(c,\":\")\n if (ai>0) {\n av=substr(c,ai+1); sub(/^[ \\t]+/,\"\",av)\n if (substr(av,1,1)==\"&\") {\n an=substr(av,2); sub(/[ \\t].*/,\"\",an)\n sub(/^&[^ \\t]+[ \\t]*/,\"\",av)\n sub(/[ \\t]+#.*/,\"\",av); gsub(/[\"\\047]/,\"\",av); sub(/[ \\t].*/,\"\",av)\n if (an!=\"\" && av!=\"\") anch[an]=av\n }\n }\n }\n n==0 { mode=(c ~ /^catalog: *$/)?1:((c ~ /^catalogs: *$/)?2:0); cat=(mode==1)?\"default\":\"\"; next }\n mode==0 { next }\n mode==2 && c ~ /^[^:]+: *$/ { cat=c; sub(/: *$/,\"\",cat); gsub(/[\"\\047 ]/,\"\",cat); next }\n {\n ki=index(c,\":\")\n if (ki<=0) next\n k=substr(c,1,ki-1); gsub(/[\"\\047 ]/,\"\",k)\n if (substr(k,1,11)!=\"@webpieces/\") next\n v=substr(c,ki+1); sub(/^[ \\t]+/,\"\",v); sub(/^&[^ \\t]+[ \\t]*/,\"\",v)\n sub(/[ \\t]+#.*/,\"\",v); gsub(/[\"\\047]/,\"\",v); sub(/[ \\t].*/,\"\",v)\n if (v==\"\") next\n nn++; key[nn]=cat \" \" k; ali[nn]=(substr(v,1,1)==\"*\")?substr(v,2):\"\"; val[nn]=v\n }\n END { for (i=1;i<=nn;i++) { vv=(ali[i]==\"\")?val[i]:anch[ali[i]]; if (vv ~ /^[0-9]/) print key[i] \" \" vv } }\n ' \"$ROOT/pnpm-workspace.yaml\" 2>/dev/null)\"\n fi\n if grep -Eq '\"@webpieces/[^\"]*\"[[:space:]]*:[[:space:]]*\"catalog:' \"$ROOT/package.json\" 2>/dev/null && [ -f \"$ROOT/pnpm-lock.yaml\" ]; then\n WP_CATALOGS=\"$(awk '\n { n=0; while (substr($0,n+1,1)==\" \") n++; c=substr($0,n+1) }\n c==\"\" { next }\n n==0 { incat=(c ~ /^catalogs: *$/)?1:0; cat=\"\"; pkg=\"\"; next }\n incat==0 { next }\n n==2 { cat=c; sub(/:.*/,\"\",cat); pkg=\"\"; next }\n n==4 { pkg=c; sub(/: *$/,\"\",pkg); gsub(/[\"\\047]/,\"\",pkg); next }\n n==6 && substr(pkg,1,11)==\"@webpieces/\" && c ~ /^version:/ {\n v=c; sub(/^version: */,\"\",v); gsub(/[\"\\047 ]/,\"\",v);\n if (cat!=\"\" && v!=\"\") print cat \" \" pkg \" \" v\n }\n ' \"$ROOT/pnpm-lock.yaml\" 2>/dev/null)\"\n fi\n while IFS=' ' read -r WP_NAME WP_DECL; do\n [ -n \"$WP_NAME\" ] || continue\n # Fault U's input: the package is DECLARED (in any spec shape, in any dependency block of the root\n # manifest). Recorded before every `continue` below, so a range or catalog spec still counts.\n [ \"$WP_NAME\" = \"ai-hook-rules\" ] && WP_HOOK_PKG_DECLARED=1\n # Resolve the declared spec to an EXACT version, or skip it: ranges (^ ~ workspace:*) never drift,\n # and a catalog spec we cannot resolve is best-effort skipped rather than guessed.\n case \"$WP_DECL\" in\n catalog:*)\n WP_CAT=\"${WP_DECL#catalog:}\"; [ -n \"$WP_CAT\" ] || WP_CAT=\"default\"\n WP_DECL=\"$(printf '%s\\n' \"$WP_WS_CATALOGS\" | awk -v c=\"$WP_CAT\" -v p=\"@webpieces/$WP_NAME\" '$1==c && $2==p {print $3; exit}')\"\n [ -n \"$WP_DECL\" ] || WP_DECL=\"$(printf '%s\\n' \"$WP_CATALOGS\" | awk -v c=\"$WP_CAT\" -v p=\"@webpieces/$WP_NAME\" '$1==c && $2==p {print $3; exit}')\"\n [ -n \"$WP_DECL\" ] || continue ;;\n [0-9]*) : ;;\n *) continue ;;\n esac\n # The release the rest of this repo is on \u2014 what fault U's cure should pin to.\n [ -n \"$WP_PIN\" ] || WP_PIN=\"$WP_DECL\"\n WP_MANIFEST=\"$BIN_ROOT/node_modules/@webpieces/$WP_NAME/package.json\"\n [ -f \"$WP_MANIFEST\" ] || continue\n WP_INST=\"$(sed -n 's/.*\"version\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p' \"$WP_MANIFEST\" | head -n1)\"\n [ -n \"$WP_INST\" ] || continue\n if [ \"$WP_DECL\" != \"$WP_INST\" ]; then\n DRIFT_PKG=\"@webpieces/$WP_NAME\"\n DRIFT_DECLARED=\"$WP_DECL\"\n DRIFT_INSTALLED=\"$WP_INST\"\n break\n fi\n done <