Skip to content

chore: add lefthook git hooks and polyglot static analysis toolchain - #480

Open
BillyOutlast wants to merge 1 commit into
Drop-OSS:developfrom
Heretek-AI:pr/toolchain
Open

chore: add lefthook git hooks and polyglot static analysis toolchain#480
BillyOutlast wants to merge 1 commit into
Drop-OSS:developfrom
Heretek-AI:pr/toolchain

Conversation

@BillyOutlast

Copy link
Copy Markdown

Summary

Adds a two-layer quality-gate setup for the polyglot monorepo: fast local hooks at commit/push, authoritative scans in CI. Nothing in CI depends on a hook having run — hooks are early feedback, CI is the authority.

Layer When What
lefthook pre-commit commit prettier + eslint --fix on staged files, ast-grep scan, gitleaks (<10s)
lefthook pre-push push server typecheck, per-crate clippy, golangci-lint, knip report
GitHub Actions PR/push gitleaks history scan, cargo-audit ×7 crates, golangci-lint (Go backend)
GitHub Actions weekly semgrep deep scan → SARIF → Code Scanning

What's included

  • lefthook as a root devDependency wired via "prepare": "lefthook install" — hooks self-install on pnpm install, no brew prerequisite. Glob-filtered so irrelevant commands skip entirely (a markdown-only commit pays ~nothing)
  • security.yml — gitleaks full-history scan via direct CLI (gitleaks-action requires a paid license for organization repos), cargo-audit matrix across all 7 Rust crates with on-the-fly lockfile generation for vendored crates that gitignore theirs, golangci-lint job for the previously-unlinted Go backend
  • semgrep-scheduled.yml — weekly deep scan uploaded to Code Scanning; deliberately not in push/PR CI where its runtime would hurt
  • knip report-only step in Server CI (non-blocking during rollout), with workspace-aware knip.json
  • ast-grep starter rules (sgconfig.yml + rules/): no-console-log (server TS/Vue), no-fmt-println (Go)
  • backend/.golangci.yml (v2 syntax) with gosec + core linters
  • Shared root .prettierrc.json (copied from server/)
  • CLAUDE.md documenting what runs when, escape hatches, native binary install paths, and machine-readable output commands for AI agents

Rollout philosophy

Deliberately non-disruptive — each gate starts in warn/report mode with a recorded baseline in CLAUDE.md:

  • knip: report-only (baseline: 117 unused files / 31 unused exports / 4 unused deps)
  • golangci-lint: --new-from-rev=origin/develop new-issues-only
  • ast-grep rules: severity: warning

Each has a documented flip-to-strict path once triaged. The clippy pre-push hook skips desktop/src-tauri locally (needs Tauri system libs) but CI covers it.

Verification

$ pnpm exec lefthook validate
All good
$ pnpm exec lefthook run pre-commit --all-files   # ~5s wall
✔️ gitleaks ✔️ ast-grep ✔️ eslint ✔️ prettier
$ cd server && pnpm run typecheck && pnpm run build   # clean

Negative-tested: a staged fake API key fails pre-commit via gitleaks.

Two enforcement layers: fast local hooks at commit/push, authoritative
scans in CI. Nothing in CI depends on a hook having run.

- lefthook (root devDep, wired via prepare script): pre-commit formats
  staged files (prettier + eslint --fix), runs ast-grep structural scan
  and gitleaks secret scan (<10s); pre-push runs server typecheck,
  per-crate clippy on changed crates, golangci-lint, knip report
- security.yml: gitleaks full-history scan (direct CLI — gitleaks-action
  requires a paid license for orgs), cargo-audit matrix across all 7 Rust
  crates with lockfile generation for vendored crates that gitignore it,
  golangci-lint job for the Go backend (--new-from-rev rollout mode)
- semgrep-scheduled.yml: weekly deep scan -> SARIF -> Code Scanning,
  deliberately not wired into push/PR CI
- knip report-only job in server-ci (non-blocking during rollout)
- configs: knip.json (workspace-aware), sgconfig.yml + starter rules
  (no-console-log TS/Vue, no-fmt-println Go), backend/.golangci.yml v2
  with gosec, shared root .prettierrc.json, clippy-changed.sh helper
- CLAUDE.md documenting what runs when, escape hatches, native binary
  install paths, and rollout baselines

Rollout is deliberately non-disruptive: knip report-only, golangci-lint
new-issues-only, ast-grep rules as warnings — each documented in
CLAUDE.md with its baseline count for flipping to strict later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant