Claude (review-harness setup) f3ee4722a8 Phase A + B (MVP) — local review harness
Implements the MVP cutline from the planning artifact:
- Phase A: skeleton + CLI dispatch + provider interface + stub model doctor
- Phase B: scanner + git probe + 12 static analyzers + reporters + pipeline
- Phase B fixtures: clean-repo, insecure-repo, degraded-repo

12 static analyzers per PROMPT.md "Suggested Static Checks For MVP":
hardcoded_paths, shell_execution, raw_sql_interpolation, broad_cors,
secret_patterns, large_files, todo_comments, missing_tests,
env_file_committed, unsafe_file_io, exposed_mutation_endpoint,
hardcoded_local_ip.

Acceptance gates passing:
- B1 (intake produces accurate counts) ✓
- B2 (insecure fixture fires ≥8 distinct check_ids — actually 11/12) ✓
- B3 (clean fixture produces 0 confirmed findings — no false positives) ✓
- B4 (scrum mode produces all 6 required markdown + JSON reports) ✓
- B5 (receipts.json marks degraded phases honestly) ✓
- F  (self-review on this repo runs without crashing) ✓ — exit 66 (degraded
  because Phase C LLM review is hardcoded skipped)

Phases C (LLM review), D (validation cross-check), E (memory + diff +
rules subcommands) deferred per the cutline. The MVP delivers the
evidence-first path; LLM is purely additive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 00:56:02 -05:00

59 lines
2.0 KiB
Go

// Package analyzers defines the static-analysis surface. Each
// analyzer is a function that takes the scanner's view of the repo
// and returns []Finding. The Finding shape is locked by
// docs/REPORT_SCHEMA.md — fields here are the canonical names
// that flow into reports + memory + LLM-finding cross-checks.
package analyzers
// Severity ladder from REPORT_SCHEMA.md. Stored as a string so the
// JSON shape is exactly what operators expect to grep for.
type Severity string
const (
SeverityLow Severity = "low"
SeverityMedium Severity = "medium"
SeverityHigh Severity = "high"
SeverityCritical Severity = "critical"
)
// Status reflects the validation state. Static-analysis findings
// default to "suspected" — they're regex hits without context.
// Validation (Phase D) promotes to "confirmed" or rejects with reason.
type Status string
const (
StatusConfirmed Status = "confirmed"
StatusSuspected Status = "suspected"
StatusRejected Status = "rejected"
StatusBlocked Status = "blocked"
)
// Source tracks who produced a finding. Useful in the JSON for
// downstream consumers that want to sort/filter.
type Source string
const (
SourceStatic Source = "static"
SourceLLM Source = "llm"
SourceValidator Source = "validator"
)
// Finding is the canonical shape per docs/REPORT_SCHEMA.md.
// IDs are deterministic-from-content (file + line + check) so the
// same finding across runs produces the same ID — useful for memory
// dedup later.
type Finding struct {
ID string `json:"id"`
Title string `json:"title"`
Severity Severity `json:"severity"`
Status Status `json:"status"`
File string `json:"file"`
LineHint string `json:"line_hint,omitempty"`
Evidence string `json:"evidence"`
Reason string `json:"reason"`
SuggestedFix string `json:"suggested_fix,omitempty"`
Source Source `json:"source"`
Confidence float64 `json:"confidence"`
CheckID string `json:"check_id,omitempty"` // e.g. "static.hardcoded_paths"
}