feat(security): receipt admin scripts + user git-ops (zero exceptions)

Wire the remaining shell egress through gstack-egress-lib.sh:

- gstack-gbrain-mcp-verify: both JSON-RPC probe POSTs (initialize +
  tools/list) receipted fail-closed via payload files (hash == wire
  bytes). A refused receipt lands in the NETWORK class — no send.
- gstack-security-dashboard / gstack-community-dashboard: the
  community-pulse GETs receipted fail-open (read-only stats must not
  break over an audit hiccup).
- gstack-gbrain-supabase-provision: api_call receipted fail-closed.
  Each retry attempt hands the helper a fresh copy of the body file
  (the helper consumes its payload). The receipt hashes the request
  body only — the PAT never reaches the ledger or any log. Refusal
  exits 8 without retrying.
- git-class sha256:null receipts, fail-open: gstack-artifacts-init
  (ls-remote, initial push, fetch/pull recovery, retry push),
  gstack-brain-restore (staging clone, existing-repo fetch),
  gstack-session-update (self-update pull).

gstack-team-init needs no wiring: every git clone in it is inside an
echoed instruction string, not an executed command.

The lib now self-locates with shell builtins only (no dirname), so
sourcing works under the whitelist-PATH test harnesses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit b8c5e2055b21ab72878b3e46f8047782ee65a11c)
This commit is contained in:
Garry Tan
2026-08-12 15:31:48 -07:00
parent 52288947ec
commit 97ace4a452
10 changed files with 111 additions and 24 deletions
+20 -4
View File
@@ -40,6 +40,16 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
URL_BIN="$SCRIPT_DIR/gstack-artifacts-url"
REMOTE_FILE="$HOME/.gstack-artifacts-remote.txt"
# Egress receipt helpers (_receipted_git): fail-open for user-directed
# git ops against the user's own artifacts remote.
. "$SCRIPT_DIR/gstack-egress-lib.sh"
# remote host for receipt records (github.com etc). Set once PUSH_URL exists.
_artifacts_host() {
local h="${PUSH_URL#*://}"; h="${h#*@}"; h="${h%%[/:]*}"
echo "${h:-unknown}"
}
REMOTE_URL=""
HOST_PREF=""
URL_FORM_SUPPORTED="false"
@@ -185,7 +195,8 @@ PUSH_URL=$("$URL_BIN" --to ssh "$CANONICAL_HTTPS" 2>/dev/null || echo "$CANONICA
# ---- verify push URL is reachable ----
echo "Verifying remote connectivity: $PUSH_URL"
if ! git ls-remote "$PUSH_URL" >/dev/null 2>&1; then
if ! _receipted_git open artifacts-init "$(_artifacts_host)" artifacts-remote-ls-remote "user ran gstack-artifacts-init" \
bash -c 'git ls-remote "$1" >/dev/null 2>&1' _ "$PUSH_URL"; then
cat >&2 <<EOF
Remote not reachable via SSH: $PUSH_URL
This could mean:
@@ -346,10 +357,15 @@ else
fi
# ---- initial push ----
if ! git push -q -u origin main 2>/dev/null; then
if ! _receipted_git open artifacts-init "$(_artifacts_host)" artifacts-initial-push "user ran gstack-artifacts-init" \
bash -c 'git push -q -u origin main 2>/dev/null'; then
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if git fetch origin 2>/dev/null && git pull --ff-only origin "$CURRENT_BRANCH" 2>/dev/null; then
git push -q -u origin "$CURRENT_BRANCH" || {
if _receipted_git open artifacts-init "$(_artifacts_host)" artifacts-fetch "user ran gstack-artifacts-init" \
bash -c 'git fetch origin 2>/dev/null' \
&& _receipted_git open artifacts-init "$(_artifacts_host)" artifacts-pull "user ran gstack-artifacts-init" \
bash -c 'git pull --ff-only origin "$1" 2>/dev/null' _ "$CURRENT_BRANCH"; then
_receipted_git open artifacts-init "$(_artifacts_host)" artifacts-initial-push "user ran gstack-artifacts-init" \
git push -q -u origin "$CURRENT_BRANCH" || {
echo "Push to $PUSH_URL failed. The remote may have divergent content." >&2
echo "Try: cd ~/.gstack && git pull --rebase origin $CURRENT_BRANCH && git push origin $CURRENT_BRANCH" >&2
exit 1