- Add Layered() method to Go SDK for per-source-class consensus queries - Add LayeredQueryParams, LayeredResult, TierResolution types to Go SDK - Create conflict example demonstrating Skeptic and Layered endpoints - Update quickstart.md with sections 6 (conflict detection) and 7 (authority tiers) - Remove tracked Go binary and add data/ to .gitignore The new quickstart sections demonstrate Episteme's differentiating features: - Skeptic endpoint shows "Trust but Verify" conflict analysis - Layered endpoint shows per-tier resolution (Clinical vs Anecdotal) Note: Pre-existing large files flagged by pre-commit hook (technical debt from prior sessions) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
180 lines
4.3 KiB
Markdown
180 lines
4.3 KiB
Markdown
# Quality Checks & Pre-commit Hooks
|
|
|
|
**When to use:** Setting up your dev environment, understanding CI/local parity, or debugging pre-commit failures.
|
|
|
|
## Prerequisites
|
|
|
|
- Rust toolchain installed (`rustup`)
|
|
- `jscpd` for duplication checks: `npm install -g jscpd`
|
|
- Go toolchain (for SDK work)
|
|
- `goimports`: `go install golang.org/x/tools/cmd/goimports@latest`
|
|
- `golangci-lint` (optional): `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest`
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Run all quality checks (same as CI)
|
|
make quality
|
|
|
|
# Auto-fix formatting (Rust)
|
|
make fmt
|
|
|
|
# Auto-fix formatting (Go)
|
|
make go-fmt
|
|
|
|
# See clippy errors
|
|
make lint
|
|
|
|
# Lint Go SDK
|
|
make go-lint
|
|
```
|
|
|
|
## Pre-commit Hook (v2)
|
|
|
|
The pre-commit hook at `.git/hooks/pre-commit` uses a **two-phase approach**:
|
|
|
|
### Phase 1: Auto-fix
|
|
- Runs formatters (`cargo fmt`, `gofmt`, `goimports`)
|
|
- Re-stages formatted files automatically
|
|
- Transparent to the developer
|
|
|
|
### Phase 2: Verify
|
|
- Checks formatting (should pass after phase 1)
|
|
- Runs linters (`cargo clippy`, `go vet`, `golangci-lint`)
|
|
- Checks file length (max 500 lines)
|
|
- Blocks commit if any check fails
|
|
|
|
### Languages Supported
|
|
|
|
| Language | Format | Lint | File Length |
|
|
|----------|--------|------|-------------|
|
|
| Rust | `cargo fmt` | `cargo clippy` | ✅ |
|
|
| Go | `gofmt` + `goimports` | `go vet` + `golangci-lint` | ✅ |
|
|
|
|
### Smart Detection
|
|
|
|
- Only checks staged files (fast feedback)
|
|
- Auto-detects Go modules (walks up to find `go.mod`)
|
|
- Skips checks if no Rust/Go files are staged
|
|
- Re-stages files after formatting
|
|
|
|
### Installing the Hook
|
|
|
|
The hook should already exist. If not:
|
|
|
|
```bash
|
|
chmod +x .git/hooks/pre-commit
|
|
```
|
|
|
|
### Bypassing (Emergency Only)
|
|
|
|
```bash
|
|
# Skip pre-commit hook (logged, use sparingly)
|
|
git commit --no-verify -m "emergency fix"
|
|
```
|
|
|
|
## What Gets Checked
|
|
|
|
### Rust
|
|
|
|
| Check | Command | What it catches |
|
|
|-------|---------|-----------------|
|
|
| Format | `cargo fmt --check` | Inconsistent formatting |
|
|
| Lint | `cargo clippy -- -D warnings` | Code smells, potential bugs |
|
|
| Duplication | `jscpd` (CI only) | Copy-pasted code blocks |
|
|
| Tests | `cargo test` (CI only) | Broken functionality |
|
|
|
|
### Go (SDK)
|
|
|
|
| Check | Command | What it catches |
|
|
|-------|---------|-----------------|
|
|
| Format | `gofmt -l` | Inconsistent formatting |
|
|
| Imports | `goimports` | Unorganized imports |
|
|
| Vet | `go vet ./...` | Suspicious constructs |
|
|
| Lint | `golangci-lint run` | Code quality issues |
|
|
|
|
### Universal
|
|
|
|
| Check | Threshold | What it catches |
|
|
|-------|-----------|-----------------|
|
|
| File length | 500 lines max | Files too large to reason about |
|
|
|
|
## Enforced Lints
|
|
|
|
These are set to `deny` in `Cargo.toml` (CI will fail):
|
|
|
|
| Lint | Why |
|
|
|------|-----|
|
|
| `clippy::unwrap_used` | Panics are forbidden in production code |
|
|
| `clippy::expect_used` | Panics are forbidden in production code |
|
|
| `clippy::panic` | Explicit panics are forbidden in production code |
|
|
|
|
**Tests are exempt** via `clippy.toml`:
|
|
- `allow-unwrap-in-tests = true`
|
|
- `allow-expect-in-tests = true`
|
|
- `allow-panic-in-tests = true`
|
|
|
|
To add a new enforced lint, update `[workspace.lints.clippy]` in root `Cargo.toml`.
|
|
|
|
## Troubleshooting
|
|
|
|
### "Format check failed"
|
|
|
|
```bash
|
|
make fmt # Auto-fix Rust
|
|
make go-fmt # Auto-fix Go
|
|
git add -u # Re-stage (hook does this automatically)
|
|
```
|
|
|
|
### "Clippy warnings treated as errors"
|
|
|
|
Fix the warnings. Common ones:
|
|
|
|
```rust
|
|
// Bad: unused variable
|
|
let x = 5;
|
|
|
|
// Good: prefix with underscore
|
|
let _x = 5;
|
|
```
|
|
|
|
### "go vet failed"
|
|
|
|
Check for suspicious constructs:
|
|
|
|
```bash
|
|
cd sdk/go/steme && go vet ./...
|
|
```
|
|
|
|
### "File too long"
|
|
|
|
Split into smaller modules. Keep files under 500 lines for maintainability.
|
|
|
|
### "Duplication detected"
|
|
|
|
Refactor the duplicated code into a shared function or module.
|
|
|
|
## CI/Local Parity
|
|
|
|
The pre-commit hook runs a subset of what CI runs (format, lint, file length). Full CI also runs:
|
|
- Tests (`cargo test`, `go test`)
|
|
- Duplication detection (`jscpd`)
|
|
- Security audit (`cargo audit`)
|
|
|
|
## Performance
|
|
|
|
Target: **<10 seconds** on staged files
|
|
|
|
| Scenario | Time |
|
|
|----------|------|
|
|
| No Rust/Go files staged | <0.2s |
|
|
| Go files only (warm) | <2s |
|
|
| Rust files only (warm) | <3s |
|
|
| Both (warm) | <5s |
|
|
| Cold compile | ~11s |
|
|
|
|
## Related
|
|
|
|
- [Testing Guide](./testing.md) - Running tests
|
|
- [Rust Guidelines](../backend/rust-guidelines.md) - Code standards
|