fix(board): discover dot-prefixed repos (.profile) without dotglob's scope creep

board.sh's discovery loops (for entry in "$root"/*, and the polyrepo
container's child loop) never see dot-prefixed directories - measured with
a known-positive control: two repos in one root, one dot-prefixed, board
found only the other. This makes any dot-repo (e.g. .profile, the
Forgejo/GitHub org-profile convention) permanently invisible: not listed,
and --dispatch --repo .profile refuses outright.

A blanket `shopt -s dotglob` is not the fix: it would also route a
dot-prefixed non-repo dir (e.g. .claude) into the container-scan branch,
silently expanding what counts as a polyrepo container. Instead, add_dot_repos()
picks up only dot-entries that are themselves git repos, at both discovery
depths, leaving non-repo dot-dirs untouched. `.*` as a literal glob pattern
already matches dot-entries without dotglob, so no shopt toggle is needed.

Closes ordre 20260818T124828Z-136209036-from-.claude.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qMr8vZZFwa4dBrheNgAhj
This commit is contained in:
Kjell Tore Guttormsen 2026-08-18 15:01:00 +02:00
commit 3e5add0aee
2 changed files with 94 additions and 0 deletions

View file

@ -1973,6 +1973,71 @@ grep -v '^[[:space:]]*#' "$NRFNR_FIXTURE" | grep -q 'NR==FNR'
check "the same filter+grep DOES find a live NR==FNR in a known-positive fixture" $?
/bin/rm -f "$NRFNR_FIXTURE" 2>/dev/null
# --- 22. Dot-prefixed repo discovery (board.sh:265/271 dotglob gap) --------
# Ordre 20260818T124828Z-136209036-from-.claude, measured: `for entry in
# "$root"/*` has no dotglob, so a dot-prefixed repo directory (the Forgejo/
# GitHub `.profile` org-profile convention) is never seen by board at all -
# not listed, not dispatchable ("no repo named '.profile' in the scanned
# roots"). Known-positive control per the order: two repos in one isolated
# root, one dot-prefixed, one not - board must find BOTH, not just the dot
# one (a test that only checked the dot-repo would pass even if the fix
# broke the ordinary case).
DOT_ROOT="$(mktemp -d)"
mkrepo "$DOT_ROOT/.dotrepo"
{
echo "# STATE - .dotrepo"
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
echo "<!-- board: status=planned; blocked-on=-; next-cost=Sonnet 5/high -->"
echo "Dot-prefixed repo, e.g. the .profile org-profile convention."
} > "$DOT_ROOT/.dotrepo/STATE.md"
mkrepo "$DOT_ROOT/regularrepo"
{
echo "# STATE - regularrepo"
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
echo "<!-- board: status=planned; blocked-on=-; next-cost=Sonnet 5/high -->"
echo "Ordinary repo, no leading dot."
} > "$DOT_ROOT/regularrepo/STATE.md"
DOT_OUT="$("$BOARD" --roots "$DOT_ROOT" --plain 2>/dev/null)"
printf '%s' "$DOT_OUT" | grep -q '\.dotrepo'
check "board finds a dot-prefixed repo" $?
printf '%s' "$DOT_OUT" | grep -q 'regularrepo'
check "board still finds the ordinary repo alongside it (known-positive)" $?
printf '%s' "$DOT_OUT" | grep -q '(2 repo'
check "board reports both repos, not just one" $?
# A dot-prefixed directory that is NOT itself a repo must never become a
# polyrepo container: a naive `shopt -s dotglob` on the existing else-branch
# (board.sh:270-275) would route a dir like .claude there, silently
# expanding what counts as a container - unmeasured scope creep the order
# explicitly flagged. Its child repo must stay invisible.
mkdir -p "$DOT_ROOT/.nonrepo-dotdir"
mkrepo "$DOT_ROOT/.nonrepo-dotdir/child-repo"
DOT_OUT2="$("$BOARD" --roots "$DOT_ROOT" --plain 2>/dev/null)"
printf '%s' "$DOT_OUT2" | grep -q 'child-repo'
[ $? -ne 0 ]
check "a dot-prefixed NON-repo dir is not turned into a polyrepo container" $?
printf '%s' "$DOT_OUT2" | grep -q '(2 repo'
check "the non-repo dot-dir does not change the repo count" $?
# Same glob, second place (board.sh:271): a dot-prefixed repo nested under a
# polyrepo container (depth 2) must also be found, for the identical reason
# - the order flags this as the same defect class, unmeasured but present in
# the code.
mkdir -p "$DOT_ROOT/polyrepo-dir"
mkrepo "$DOT_ROOT/polyrepo-dir/.dotchild"
{
echo "# STATE - .dotchild"
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
echo "<!-- board: status=planned; blocked-on=-; next-cost=Sonnet 5/high -->"
echo "Dot-prefixed repo nested under a polyrepo container."
} > "$DOT_ROOT/polyrepo-dir/.dotchild/STATE.md"
DOT_OUT3="$("$BOARD" --roots "$DOT_ROOT" --plain 2>/dev/null)"
printf '%s' "$DOT_OUT3" | grep -q '\.dotchild'
check "board finds a dot-prefixed repo nested under a polyrepo container (depth 2)" $?
/bin/rm -rf "$DOT_ROOT" 2>/dev/null
echo ""
echo "board-selftest: $PASS passed, $FAIL failed"
[ "$FAIL" -eq 0 ] || exit 1