framework: make tool discoverability, workspace placement and model tiering mechanical #1174

Merged
Mos merged 24 commits from feat/workspace-hygiene-tool-enforcement into main 2026-08-13 14:21:23 +00:00
2 changed files with 64 additions and 8 deletions
Showing only changes of commit 20d86e392b - Show all commits
@@ -40,8 +40,41 @@ FIXTURES="$TMP/fixtures.tsv"
printf '2\t{"tool_input":{"command":"git clone x \\"$HOME\\"/wt"}}\ta closing quote between HOME and slash does not hide the path\n'
printf '2\t{"tool_input":{"command":"git clone x ${HOME}/wt"}}\tthe braced HOME spelling is the same home path\n'
printf '2\t{"tool_input":{"command":"git clone x \\"${HOME}\\"/wt"}}\tbraced HOME may also end a quoted span before the slash\n'
# The target may be HOME itself. End-of-command and whitespace terminate the
# token just as a slash does; punctuation that can extend a path does not.
printf '2\t{"tool_input":{"command":"git clone x $HOME"}}\tthe unbraced variable may name HOME exactly\n'
printf '2\t{"tool_input":{"command":"git clone x \\"$HOME\\""}}\tquotes do not change the exact HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x ${HOME}"}}\tthe braced variable may name HOME exactly\n'
printf '2\t{"tool_input":{"command":"git clone x ~"}}\ttilde may name HOME exactly\n'
printf '2\t{"tool_input":{"command":"git worktree add $HOME topic"}}\twhitespace terminates an exact HOME target before another argument\n'
# Unquoted POSIX metacharacters terminate the target word even without spaces.
printf '2\t{"tool_input":{"command":"git clone x $HOME;echo x"}}\tsemicolon terminates an exact HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x \\"$HOME\\"&& echo x"}}\tand-if terminates a quoted exact HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x ${HOME}| cat"}}\ta pipe terminates a braced exact HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x ~&"}}\tbackground operator terminates a tilde HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x $HOME</dev/null"}}\tinput redirection terminates the target word\n'
printf '2\t{"tool_input":{"command":"git clone x $HOME>out"}}\toutput redirection terminates the target word\n'
printf '2\t{"tool_input":{"command":"( git clone x $HOME)"}}\ta subshell close terminates the exact HOME target\n'
printf '2\t{"tool_input":{"command":"git clone x $HOME\\necho x"}}\ta literal newline terminates the target word\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME_BACKUP/wt"}}\ta longer HOME-prefixed variable is a different path\n'
printf '0\t{"tool_input":{"command":"git clone x $HOMEBREW/wt"}}\tHOMEBREW is not HOME either\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME.bak/wt"}}\ta dot continues the path token into a sibling name\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME+bak/wt"}}\tplus is ordinary sibling filename content\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME@bak/wt"}}\tat-sign is ordinary sibling filename content\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME,bak/wt"}}\tcomma is ordinary sibling filename content\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME:bak/wt"}}\tcolon is ordinary sibling filename content\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME=bak/wt"}}\tequals is ordinary sibling filename content\n'
printf '0\t{"tool_input":{"command":"git clone x ${HOME}+bak/wt"}}\tbraced HOME plus suffix is still a sibling\n'
printf '0\t{"tool_input":{"command":"git clone x /home/tester+bak/wt"}}\ta literal plus-suffixed home path is a sibling\n'
printf '0\t{"tool_input":{"command":"git clone x /home/tester@bak/wt"}}\ta literal at-suffixed home path is a sibling\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME+bak/wt;echo x"}}\ta later terminator does not turn a sibling into HOME\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME@bak/wt&& echo x"}}\tand-if after a sibling preserves the allow\n'
printf '0\t{"tool_input":{"command":"git clone x \\"$HOME;bak/wt\\""}}\ta quoted semicolon is filename content, not a boundary\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME\\\\;bak/wt"}}\tan escaped semicolon is filename content, not a boundary\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME\\u001b/wt"}}\ta raw internal-marker byte is encoded as filename content\n'
printf '0\t{"tool_input":{"command":"git clone x /home/tester.bak/wt"}}\ta literal sibling path is not beneath HOME\n'
printf '0\t{"tool_input":{"command":"git clone x /home/testerx/wt"}}\ta longer literal basename is not HOME\n'
printf '0\t{"tool_input":{"command":"git clone x ~root/wt"}}\tanother account tilde is not this account HOME\n'
printf '0\t{"tool_input":{"command":"git clone x $HOME}/wt"}}\ta closing brace without an opening brace is a literal suffix\n'
printf '0\t{"tool_input":{"command":"git clone x ${HOME/wt"}}\tan opening brace without a close is not a HOME expansion\n'
# Quote removal must not create an expansion the shell never performs.
@@ -485,6 +518,10 @@ home_case 'a usable HOME still allows a checkout onto a work filesystem' \
0 '/home/tester' 'git clone https://example.invalid/x /src/wt'
home_case 'a usable HOME still catches the literal path' \
2 '/home/tester' 'git clone https://example.invalid/x /home/tester/wt' 'checks a repository out under'
home_case 'a usable HOME catches the exact literal path without a trailing slash' \
2 '/home/tester' 'git clone https://example.invalid/x /home/tester' 'checks a repository out under'
home_case 'quotes around the exact literal HOME path do not change the target' \
2 '/home/tester' 'git clone https://example.invalid/x "/home/tester"' 'checks a repository out under'
home_case 'a quoted literal HOME segment remains contiguous with the suffix' \
2 '/home/tester' 'git clone https://example.invalid/x "/home/tester"/wt' 'checks a repository out under'
home_case 'and the unexpanded $HOME spelling, which needs no resolution at all' \
@@ -100,13 +100,23 @@ normalize_command_words() {
-v protect_path_literals="$protect_path_literals" '
BEGIN {
state = "outside"; out = ""; word_start = 1
word_boundary = sprintf("%c", 27)
literal_dollar = sprintf("%c", 28)
literal_tilde = sprintf("%c", 29)
}
{
if (NR > 1) { out = out "\n"; word_start = 1 }
if (NR > 1) {
if (protect_path_literals) out = out word_boundary
else out = out "\n"
word_start = 1
}
for (i = 1; i <= length($0); i++) {
c = substr($0, i, 1)
# A raw marker byte is ordinary word content. Encode it visibly so only
# this machine can manufacture an internal boundary marker.
if (protect_path_literals && c == word_boundary) {
out = out "\\x1b"; word_start = 0; continue
}
if (state == "single") {
if (c == "\047") {
state = "outside"
@@ -144,7 +154,10 @@ normalize_command_words() {
}
continue
}
if (c == "\\") {
if (protect_path_literals && c ~ /[[:space:]|&;()<>]/) {
out = out word_boundary
word_start = 1
} else if (c == "\\") {
if (i == length($0)) {
out = out c
} else {
@@ -173,12 +186,14 @@ normalize_command_words() {
CMD_NAMES="$(printf '%s' "$CMD" | normalize_command_words 1 0)"
# Paths need the same quote and escape handling, but not name-mode substitution
# flattening: an expansion-capable `$HOME` spelling must remain visible to the
# checkout check. Shell-literal dollar/tilde characters (single-quoted, escaped,
# or a quoted tilde) become internal nonmatching markers; otherwise quote removal
# would create a HOME spelling the shell never expands. A path assembled from a
# different variable or command substitution is absent from the literal text and
# checkout check. Unquoted POSIX shell metacharacters become an internal word-
# boundary marker; quoted/escaped metacharacters remain content. Shell-literal
# dollar/tilde characters become separate nonmatching markers; otherwise quote
# removal would create a HOME spelling the shell never expands. A path assembled
# from a different variable or command substitution is absent from the literal text and
# remains outside a text guard's visibility.
CMD_PATHS="$(printf '%s' "$CMD" | normalize_command_words 0 1)"
PATH_WORD_BOUNDARY=$'\033'
# The one place the shape of a program NAME is written down. Every name consumer
# below uses it, so the next fix to this class lands in a single location instead of
@@ -307,8 +322,12 @@ derives the path and never consults \$HOME at all:
EOF
exit 2
fi
# Any argument that resolves under $HOME and is not under a work filesystem.
if printf '%s' "$CMD_PATHS" | grep -Eq "(^|[[:space:]=])($home_re)/"; then
# Any argument that resolves to $HOME itself or beneath it. The path-mode
# normalizer marks every unquoted POSIX shell word boundary, so the home token
# must be preceded by a boundary/start/assignment and followed by a boundary,
# slash (a descendant), or end. Arbitrary filename bytes remain content; this
# avoids over-blocking sibling names such as $HOME+bak or $HOME.bak.
if printf '%s' "$CMD_PATHS" | grep -Eq "(^|=|$PATH_WORD_BOUNDARY)($home_re)($PATH_WORD_BOUNDARY|/|$)"; then
cat <<EOF
BLOCKED: this checks a repository out under \$HOME.