ci: guard against private paths, usernames, and machine names

Adds scripts/check-no-private-paths.sh and wires it into the existing
guard workflow (runs on every push + PR). It fails if a real local
filesystem path, personal username, or host name lands in the public
repo — the class of leak just removed (e.g. /home/<user>/ worktree
paths and a dev machine name).

- Blocks exact private tokens and real-username home paths
  (/home/<x>/, /Users/<x>/, C:\Users\<x>\).
- Allowlists the placeholder paths the docs legitimately use
  (/Users/you/..., ~/, etc.), so no false positives on the tree.
- Verified: passes clean on the current tree; fails on a planted
  leak (token + real home path); placeholder paths pass.
- CLAUDE.md hygiene section now points to both guards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3RxH4JxAQYsuA9kFVnR5v
This commit is contained in:
Claude 2026-07-01 15:14:07 +00:00
parent e89a922cf8
commit 02e0241aa2
No known key found for this signature in database
3 changed files with 99 additions and 3 deletions

View file

@ -1,8 +1,11 @@
name: Guard — No Private Cloud Code
# Fails if private Vestige Cloud *service* code (billing, sync-key/namespace
# mapping, Lemon Squeezy webhooks, transactional email) ever lands in this
# public repo. The public cloud *client* is allowed and does not trip this.
# Fails if private content ever lands in this public repo:
# 1. Private Vestige Cloud *service* code (billing, sync-key/namespace
# mapping, Lemon Squeezy webhooks, transactional email). The public cloud
# *client* is allowed and does not trip this.
# 2. Private local paths, usernames, or machine names (e.g. a real
# /home/<user>/ worktree). Placeholder paths like /Users/you/ are allowed.
on:
push:
branches: [main, feat/cloud-sync-mvp]
@ -23,3 +26,6 @@ jobs:
- name: Scan for private cloud service markers
run: ./scripts/check-no-private-cloud.sh
- name: Scan for private paths, usernames, and machine names
run: ./scripts/check-no-private-paths.sh

View file

@ -87,3 +87,9 @@ Do not commit private absolute paths, local agent memory paths, unpublished
planning files, real credentials, personal operating notes, or private repo
locations. Example environment variables in docs must be empty placeholders or
obviously fake examples.
Two CI guards enforce this on every push and PR (see
`.github/workflows/guard-no-private-cloud.yml`):
`scripts/check-no-private-cloud.sh` blocks private cloud-service code, and
`scripts/check-no-private-paths.sh` blocks real local paths, usernames, and
machine names (placeholder paths like `/Users/you/...` or `~/` are fine).

View file

@ -0,0 +1,84 @@
#!/usr/bin/env bash
# check-no-private-paths.sh — Fail if a private local filesystem path, personal
# username, or machine name leaks into this public repo.
#
# Background: some planning docs once carried real absolute paths such as
# /home/<realuser>/prppl/vestige-phase2/...
# plus a developer machine name. Those are metadata leaks (username, folder
# layout, host) — not credentials, but exactly the kind of thing the public-repo
# hygiene rules say to keep out. They were removed; this guard stops them (and
# anything like them) from creeping back in.
#
# It scans only tracked files (git grep) for two classes of leak:
# 1. Known private tokens — exact handles / private worktree names.
# 2. Absolute home paths that reveal a REAL username, while allowlisting the
# obvious placeholders the docs legitimately use (e.g. /Users/you/...).
#
# If a match is a genuine false positive, add the placeholder to ALLOW_USERS or
# refine the pattern below — do not weaken it to a no-op.
set -u
cd "$(git rev-parse --show-toplevel)" || {
echo "check-no-private-paths: not inside a git repository" >&2
exit 2
}
# 1) Exact private tokens that must never appear anywhere in the repo.
BLOCK_TOKENS=(
'delandtj'
'prppl'
)
# 2) Placeholder usernames the docs legitimately use in example home paths.
# A /home/<name>/ or /Users/<name>/ whose <name> is NOT one of these trips.
ALLOW_USERS='you|user|username|name|me|example|runner|youruser|YOU|USER|USERNAME|YOURNAME'
# This guard and its workflow name the tokens/patterns, so exclude them.
EXCLUDES=(
':(exclude)scripts/check-no-private-paths.sh'
':(exclude).github/workflows/guard-no-private-cloud.yml'
)
violations=0
report=""
# --- 1. exact private tokens ---------------------------------------------------
for tok in "${BLOCK_TOKENS[@]}"; do
if hits=$(git grep -Ini -F -e "$tok" -- "${EXCLUDES[@]}" 2>/dev/null); then
if [ -n "$hits" ]; then
violations=$((violations + 1))
report+=$'\n'" ✗ private token: \"$tok\""$'\n'
report+="$(printf '%s\n' "$hits" | sed 's/^/ /')"$'\n'
fi
fi
done
# --- 2. absolute home paths that reveal a real username ------------------------
# Candidate lines contain /home/<x>/ or /Users/<x>/ or C:\Users\<x>\; then drop
# the lines whose username segment is an allowlisted placeholder.
if cand=$(git grep -nIE '(/home/|/Users/|[Cc]:\\Users\\)[A-Za-z0-9_.-]+[/\\]' \
-- "${EXCLUDES[@]}" 2>/dev/null); then
leaks=$(printf '%s\n' "$cand" \
| grep -vE "(/home/|/Users/|[Cc]:\\\\Users\\\\)(${ALLOW_USERS})[/\\]" || true)
if [ -n "$leaks" ]; then
violations=$((violations + 1))
report+=$'\n'" ✗ private home path (real username?):"$'\n'
report+="$(printf '%s\n' "$leaks" | sed 's/^/ /')"$'\n'
fi
fi
if [ "$violations" -ne 0 ]; then
echo "════════════════════════════════════════════════════════════════════"
echo " PRIVATE PATH / USERNAME / MACHINE NAME DETECTED IN PUBLIC REPO"
echo "════════════════════════════════════════════════════════════════════"
echo "$report"
echo "════════════════════════════════════════════════════════════════════"
echo " Real local paths, usernames, and host names must not be committed."
echo " Use a placeholder (e.g. /Users/you/... or ~/) instead. If a match is"
echo " a false positive, extend ALLOW_USERS in scripts/check-no-private-paths.sh."
echo "════════════════════════════════════════════════════════════════════"
exit 1
fi
echo "check-no-private-paths: OK — no private paths, usernames, or host names in public repo"
exit 0