diff --git a/scripts/pm/check-governed-merges.mjs b/scripts/pm/check-governed-merges.mjs index 954068278ab..c8fc32ab754 100644 --- a/scripts/pm/check-governed-merges.mjs +++ b/scripts/pm/check-governed-merges.mjs @@ -4516,7 +4516,7 @@ async function selfTest() { battery('the nested `ui/` workspace rows, on the register (#25712)'); const UI_ROWS = GOVERNED_SURFACES.filter((s) => s.id.startsWith('ui-')); const ROOT_ROWS = Object.freeze(GOVERNED_SURFACES.filter((s) => !s.id.startsWith('ui-'))); - const UI_SPECIMENS = { 'ui-adr': 'ui/docs/adr/0001-master-detail-subform.md', 'ui-claude-tree': 'ui/.claude/hooks/guard-main-checkout.sh', 'ui-skills-catalog': 'ui/skills/objectui/SKILL.md', 'ui-agents-md': 'ui/AGENTS.md', 'ui-claude-md': 'ui/CLAUDE.md', 'ui-workflows': 'ui/.github/workflows/ci.yml' }; + const UI_SPECIMENS = { 'ui-adr': 'ui/docs/adr/0001-master-detail-subform.md', 'ui-claude-tree': 'ui/.claude/skills/verify/SKILL.md', 'ui-skills-catalog': 'ui/skills/objectui/SKILL.md', 'ui-agents-md': 'ui/AGENTS.md', 'ui-claude-md': 'ui/CLAUDE.md', 'ui-workflows': 'ui/.github/workflows/ci.yml' }; assert('the-ui-rows-are-six-well-formed-register-rows', UI_ROWS.length === 6 && UI_ROWS.every((r) => (r.prefix ? r.prefix.endsWith('/') && r.glob === `${r.prefix}**` && r.exact === undefined : r.glob === r.exact) && r.tier === GOVERNED_TIER_H && r.tierRepos === undefined && surfaceRepos(r).join() === 'objectstack') && new Set(GOVERNED_SURFACES.map((r) => r.id)).size === GOVERNED_SURFACES.length, JSON.stringify(UI_ROWS.map((r) => r.id))); assert('the-ui-rows-mirror-the-six-rows-objectui-governs-each-under-ui', UI_ROWS.map((r) => r.glob).join() === ROOT_ROWS.filter((s) => s.id !== 'north-star').map((s) => `ui/${s.glob}`).join(), UI_ROWS.map((r) => r.glob).join()); for (const row of UI_ROWS) { diff --git a/ui/.claude/hooks/guard-main-checkout-bash.selftest.sh b/ui/.claude/hooks/guard-main-checkout-bash.selftest.sh deleted file mode 100755 index faab1c69263..00000000000 --- a/ui/.claude/hooks/guard-main-checkout-bash.selftest.sh +++ /dev/null @@ -1,443 +0,0 @@ -#!/usr/bin/env bash -# copied from objectstack@338297e46018ae96256262590a308c8be735f825 -# Self-test for guard-main-checkout-bash.sh — run it after touching that hook: -# -# .claude/hooks/guard-main-checkout-bash.selftest.sh -# -# Feeds the hook the same JSON payload shape Claude Code delivers on PreToolUse and asserts -# the block/allow verdict per command. Hermetic: it builds its OWN throwaway git repo, a -# linked worktree of it, and a non-repo directory under $TMPDIR, so the matrix never depends -# on which machine or which checkout it runs from. Needs jq and git and nothing else — no -# install, no build, no network. Exit 0 = all cases hold. -# -# Mirrors .claude/hooks/guard-shared-stash.selftest.sh case-for-case in shape. - -set -uo pipefail - -here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -hook="$here/guard-main-checkout-bash.sh" -pass=0 -fail=0 - -command -v jq >/dev/null 2>&1 || { echo "selftest needs jq to build payloads" >&2; exit 1; } -command -v git >/dev/null 2>&1 || { echo "selftest needs git to build the fixture" >&2; exit 1; } - -# --- fixture: a shared primary checkout, a linked worktree of it, a plain directory ----- -tmp="$(mktemp -d)" -trap 'rm -rf "$tmp"' EXIT -MAIN="$tmp/mainrepo" -WT="$tmp/wt" -PLAIN="$tmp/plain" -# ODD: a PRIMARY checkout whose own path carries a literal `worktrees` segment. Every write -# into it must BLOCK — it is a primary checkout, and the verdict comes from the git-dir vs -# git-common-dir structure, never from the spelling of the path (#7259). $WT is its positive -# twin: a real linked worktree at a path with no such segment. -ODD="$tmp/worktrees/oddrepo" -mkdir -p "$MAIN/pkg" "$PLAIN" "$ODD/pkg" -( - cd "$MAIN" || exit 1 - git init -q . - git config user.email selftest@example.com - git config user.name selftest - : > README.md - : > pkg/x.ts - git add -A - git commit -qm init - git worktree add -q "$WT" -b selftest-wt - cd "$ODD" || exit 1 - git init -q . - git config user.email selftest@example.com - git config user.name selftest - : > README.md - : > pkg/x.ts - git add -A - git commit -qm init -) >/dev/null 2>&1 || { echo "could not build the git fixture" >&2; exit 1; } - -CWD="$MAIN" # payload cwd for the cases that follow; reassigned per section - -# verdict [env assignments…] -> prints "block" or "allow" -verdict() { - local cmd="$1"; shift - local payload out rc - payload="$(jq -nc --arg c "$cmd" --arg w "$CWD" \ - '{cwd:$w,tool_name:"Bash",tool_input:{command:$c}}')" - out="$(printf '%s' "$payload" | env "$@" "$hook" 2>/dev/null)" - rc=$? - case "$rc" in - 0) printf 'allow' ;; - 2) printf 'block' ;; - *) printf 'exit%s' "$rc" ;; - esac -} - -expect() { # expect [env…] - local want="$1" cmd="$2"; shift 2 - local got; got="$(verdict "$cmd" "$@")" - local shown="${cmd//$'\n'/ ⏎ }" - shown="${shown//$MAIN/\$MAIN}"; shown="${shown//$WT/\$WT}"; shown="${shown//$PLAIN/\$PLAIN}" - shown="${shown//$ODD/\$ODD}" - if [ "$got" = "$want" ]; then - pass=$((pass + 1)); printf ' ok %-5s %s\n' "$got" "$shown" - else - fail=$((fail + 1)); printf ' FAIL want=%s got=%s %s\n' "$want" "$got" "$shown" - fi -} - -stderr_of() { # stderr_of [env…] -> the refusal text an agent actually reads - local cmd="$1"; shift - local payload - payload="$(jq -nc --arg c "$cmd" --arg w "$CWD" \ - '{cwd:$w,tool_name:"Bash",tool_input:{command:$c}}')" - printf '%s' "$payload" | env "$@" "$hook" 2>&1 >/dev/null -} - -says() { # says