mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-13 08:29:04 +02:00
feat(ci): supply-chain hygiene — secret gate on every PR diff, dependency review, OSV, dependabot, evidence-bar PR template
The repo owned a redaction engine and had zero CI-side secret scanning. quality-gate.yml now pipes every PR diff's ADDED lines through our own bin/gstack-redact (gate-secret-scan.mjs, taken from the fork — it dogfoods the engine): HIGH findings fail the check, MEDIUM prints an advisory count only (no human in CI to confirm), planted-bug fixtures excluded by pathspec. Live-verified both directions: PEM key fails, clean diff and MEDIUM shapes pass; ShellCheck (errors) covers the setup/build shell boundary and passes today; bun audit gates critical advisories. Trigger is pull_request, never pull_request_target. dependency-review.yml adopts the hardened never-merged prior-art branch (fail-on-severity high, workflow paths watched, tight perms) — verify the dependency graph parses bun.lock with a canary bump before trusting the gate. dependabot: weekly, grouped per ecosystem, capped PR counts; and evals.yml image build/push now skips dependabot actors, whose read-only GITHUB_TOKEN made every lockfile bump a permanently red check. OSV scans weekly with a reasoned ignore file. All new workflow actions SHA-pinned. Scorecard deliberately not taken (no consumer for the score). The PR template front-loads the evidence bar (live proof, liveness screenshot, no-ETHOS/voice-changes checklist); the unenforced DCO line is dropped. bin/gstack-verify-gate ships OPT-IN (never registered by ./setup — a Stop hook running the project's verify command after every turn is the user's call), with the fork's tests adapted to pin exactly that. Ported from time-attack/gstack (GStack 2) + our own prior-art branch. Co-authored-by: Sina Matian <sina@time-attack.dev> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Sina Matian
Claude Fable 5
parent
3aba218303
commit
8c75496391
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# gstack-verify-gate — Stop hook. Blocks the turn from ending until the
|
||||
# project's declared verification command passes.
|
||||
#
|
||||
# Declare the command on one line in the project's CLAUDE.md:
|
||||
# <!-- gstack:verify: bun test -->
|
||||
#
|
||||
# Read-or-ask: gstack never invents this command. No declaration, no gate.
|
||||
# Fails open on every absence (no CLAUDE.md, no declaration, empty value).
|
||||
#
|
||||
# Exit 0 = allow the turn to end, one-line reason on stdout.
|
||||
# Exit 2 = block, Claude Code feeds stderr back to the agent.
|
||||
#
|
||||
# Remove with: gstack-settings-hook remove-source --source verify-gate
|
||||
set -uo pipefail
|
||||
|
||||
INPUT=""
|
||||
[ -t 0 ] || INPUT="$(cat)"
|
||||
|
||||
# Claude Code re-runs Stop hooks after a block. Never gate the same turn twice.
|
||||
if printf '%s' "$INPUT" | grep -q '"stop_hook_active"[[:space:]]*:[[:space:]]*true'; then
|
||||
echo "verify-gate: gate already ran this turn, allowing."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
|
||||
while [ ! -f "$ROOT/CLAUDE.md" ] && [ "$ROOT" != "/" ]; do
|
||||
ROOT="$(dirname "$ROOT")"
|
||||
done
|
||||
|
||||
if [ ! -f "$ROOT/CLAUDE.md" ]; then
|
||||
echo "verify-gate: no CLAUDE.md above $PWD, no check declared, allowing."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CMD="$(sed -n 's/^[[:space:]]*\(<!--[[:space:]]*\)\{0,1\}gstack:verify:[[:space:]]*\(.*\)$/\2/p' "$ROOT/CLAUDE.md" | head -1)"
|
||||
CMD="${CMD%%-->*}"
|
||||
CMD="$(printf '%s' "$CMD" | tr -d '`' | sed 's/[[:space:]]*$//')"
|
||||
|
||||
if [ -z "$CMD" ]; then
|
||||
echo "verify-gate: $ROOT/CLAUDE.md declares no 'gstack:verify:' command, allowing."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OUT="$(cd "$ROOT" && eval "$CMD" 2>&1)"
|
||||
STATUS=$?
|
||||
|
||||
if [ "$STATUS" -eq 0 ]; then
|
||||
echo "verify-gate: declared check passed ($CMD)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "verify-gate: declared check FAILED with exit $STATUS: $CMD" >&2
|
||||
printf '%s\n' "$OUT" | tail -20 >&2
|
||||
echo "Fix the failure, or drop the gstack:verify line from $ROOT/CLAUDE.md." >&2
|
||||
exit 2
|
||||
Reference in New Issue
Block a user