diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 15a0cff..ee9961c 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -42,8 +42,8 @@ Requirements for initial release. Each maps to roadmap phases. ### Verification - [ ] **VRFY-01**: Active key verification via lightweight API calls when --verify flag is set -- [ ] **VRFY-02**: Verification is opt-in only (off by default) with consent prompt on first use -- [ ] **VRFY-03**: Each provider YAML defines verify endpoint, method, headers, success/failure codes +- [x] **VRFY-02**: Verification is opt-in only (off by default) with consent prompt on first use +- [x] **VRFY-03**: Each provider YAML defines verify endpoint, method, headers, success/failure codes - [ ] **VRFY-04**: Verification extracts additional metadata (org, rate limit, permissions) when available - [ ] **VRFY-05**: Configurable verification timeout (default 10s, --verify-timeout flag) - [ ] **VRFY-06**: Legal disclaimer and documentation ships with verification feature diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index aae8e01..4960e5d 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -123,7 +123,7 @@ Plans: **Plans**: 5 plans Plans: -- [ ] 05-01-PLAN.md — Wave 0: extend VerifySpec schema, Finding struct, storage schema; add gjson dep +- [x] 05-01-PLAN.md — Wave 0: extend VerifySpec schema, Finding struct, storage schema; add gjson dep - [ ] 05-02-PLAN.md — LEGAL.md + pkg/legal embed + consent prompt + keyhunter legal command - [ ] 05-03-PLAN.md — pkg/verify HTTPVerifier: template sub, gjson metadata extraction, ants pool - [ ] 05-04-PLAN.md — Update 12 Tier 1 provider YAMLs with extended verify specs + guardrail test diff --git a/.planning/STATE.md b/.planning/STATE.md index eed15f1..96c5e7a 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 04-05-PLAN.md -last_updated: "2026-04-05T12:29:09.228Z" +stopped_at: Completed 05-01-PLAN.md +last_updated: "2026-04-05T12:44:11.076Z" last_activity: 2026-04-05 progress: total_phases: 18 completed_phases: 4 - total_plans: 23 - completed_plans: 23 + total_plans: 28 + completed_plans: 24 percent: 20 --- @@ -21,12 +21,12 @@ progress: See: .planning/PROJECT.md (updated 2026-04-04) **Core value:** Detect leaked LLM API keys across more providers and more internet sources than any other tool, with active verification to confirm keys are real and alive. -**Current focus:** Phase 04 — input-sources +**Current focus:** Phase 05 — verification-engine ## Current Position -Phase: 5 -Plan: Not started +Phase: 05 (verification-engine) — EXECUTING +Plan: 2 of 5 Status: Ready to execute Last activity: 2026-04-05 @@ -69,6 +69,7 @@ Progress: [██░░░░░░░░] 20% | Phase 04-input-sources P03 | 6m | 1 tasks | 2 files | | Phase 04 P02 | 4min | 1 tasks | 3 files | | Phase 04 P05 | 3min | 1 tasks | 2 files | +| Phase 05 P01 | 3m43s | 2 tasks | 10 files | ## Accumulated Context @@ -91,6 +92,8 @@ Recent decisions affecting current work: - [Phase 04]: Use 'go mod download' instead of 'go mod tidy' when bootstrapping dependencies ahead of their consumers - [Phase 04-input-sources]: GitSource walks heads+tags+remotes+stash with per-OID blob dedup - [Phase 04]: Introduced selectSource dispatcher with sourceFlags struct for testable CLI source routing +- [Phase 05]: Keep legacy VerifySpec ValidStatus/InvalidStatus alongside canonical SuccessCodes/FailureCodes; Effective*() helpers pick canonical-first with fallback +- [Phase 05]: Store Finding.VerifyMetadata as JSON TEXT column; legacy DBs migrated in-place via PRAGMA table_info + conditional ALTER TABLE in storage.Open() ### Pending Todos @@ -105,6 +108,6 @@ None yet. ## Session Continuity -Last session: 2026-04-05T12:24:42.153Z -Stopped at: Completed 04-05-PLAN.md +Last session: 2026-04-05T12:44:04.063Z +Stopped at: Completed 05-01-PLAN.md Resume file: None diff --git a/.planning/phases/05-verification-engine/05-01-SUMMARY.md b/.planning/phases/05-verification-engine/05-01-SUMMARY.md new file mode 100644 index 0000000..aeb5ffc --- /dev/null +++ b/.planning/phases/05-verification-engine/05-01-SUMMARY.md @@ -0,0 +1,128 @@ +--- +phase: 05-verification-engine +plan: 01 +subsystem: verification-foundation +tags: [schema, storage, migration, verify, foundation] +requirements: [VRFY-02, VRFY-03] +dependency-graph: + requires: + - "pkg/providers/schema.go VerifySpec (Phase 2)" + - "pkg/engine/finding.go Finding (Phase 2)" + - "pkg/storage/findings.go (Phase 3)" + provides: + - "Extended VerifySpec contract for Plans 05-02/03/04" + - "Finding.Verify* fields for the verifier pipeline" + - "findings table verify_* columns + migration for existing DBs" + - "github.com/tidwall/gjson direct dependency" + affects: + - "go.mod / go.sum" + - "pkg/providers" + - "pkg/engine" + - "pkg/storage" +tech-stack: + added: + - "github.com/tidwall/gjson v1.18.0 (JSON path extraction)" + patterns: + - "PRAGMA table_info + conditional ALTER TABLE for idempotent SQLite migrations" + - "JSON-encoded TEXT column for map[string]string round-trip with NULL for nil" + - "Effective*() fallback helpers preserving legacy fields alongside canonical ones" +key-files: + created: + - "pkg/providers/schema_test.go" + - "pkg/storage/findings_test.go" + - ".planning/phases/05-verification-engine/05-01-SUMMARY.md" + modified: + - "go.mod" + - "go.sum" + - "pkg/providers/schema.go" + - "pkg/engine/finding.go" + - "pkg/storage/schema.sql" + - "pkg/storage/db.go" + - "pkg/storage/findings.go" +decisions: + - "Keep legacy ValidStatus/InvalidStatus fields AND add canonical SuccessCodes/FailureCodes; expose via Effective*() helpers so Phase 2-3 YAMLs still load." + - "Store VerifyMetadata as JSON TEXT (not a relational table) — small, read-together, and keeps the findings table self-contained." + - "Migrate existing DBs via PRAGMA table_info + ALTER TABLE ADD COLUMN (SQLite 3.35 ADD COLUMN IF NOT EXISTS is not guaranteed across modernc versions)." + - "Add ExtractMetadata skeleton in schema.go to make gjson a direct dependency now; Plan 05-03 will replace it with the full verifier extraction path." +metrics: + duration: "3m43s" + completed: "2026-04-05T12:42:56Z" + tasks_completed: 2 + files_created: 3 + files_modified: 7 +--- + +# Phase 5 Plan 01: Verification Foundation Summary + +Interface-first Wave 0 landing: extended VerifySpec, extended Finding, migrated SQLite schema, and wired gjson so Plans 05-02/03/04 can run in parallel on Wave 1 without touching each other's contracts. + +## Tasks + +### Task 1 — Extend VerifySpec, Finding, add gjson dependency +**Commits:** `499f5d5` (RED), `30c0e98` (GREEN) + +- `VerifySpec` gains `Body`, `SuccessCodes`, `FailureCodes`, `RateLimitCodes`, `MetadataPaths`. `ValidStatus` / `InvalidStatus` remain for backward compat with Phase 2-3 provider YAMLs. +- `EffectiveSuccessCodes()` returns `SuccessCodes` → `ValidStatus` → `[200]`; `EffectiveFailureCodes()` returns `FailureCodes` → `InvalidStatus` → `[401, 403]`; `EffectiveRateLimitCodes()` returns `RateLimitCodes` → `[429]`. +- `ExtractMetadata([]byte) map[string]string` added as a minimal gjson-backed helper so the dep is promoted to direct in `go.mod`. Plan 05-03 will expand it. +- `engine.Finding` gains `Verified`, `VerifyStatus`, `VerifyHTTPCode`, `VerifyMetadata`, `VerifyError`. +- Tests: `TestVerifySpec_NewFieldsParse`, `TestVerifySpec_LegacyFieldsStillWork`, `TestVerifySpec_Defaults`, `TestVerifySpec_CanonicalFieldsPreferred` — all pass. + +### Task 2 — Migrate storage schema and persist verify fields +**Commits:** `2654487` (RED), `aec559d` (GREEN) + +- `pkg/storage/schema.sql`: findings table now carries `verified INTEGER NOT NULL DEFAULT 0`, `verify_status TEXT NOT NULL DEFAULT ''`, `verify_http_code INTEGER NOT NULL DEFAULT 0`, `verify_metadata_json TEXT`. +- `pkg/storage/db.go`: new `migrateFindingsVerifyColumns` helper called from `Open()` — walks `PRAGMA table_info(findings)`, issues `ALTER TABLE ADD COLUMN` for any missing verify column. Safe to run on fresh DBs (all columns exist, no-op) and on legacy DBs. +- `pkg/storage/findings.go`: `Finding` struct extended; `SaveFinding` serializes `VerifyMetadata` as JSON (NULL when nil) and writes `verified` as 0/1 INTEGER; `ListFindings` round-trips the same. +- Tests: `TestSaveFinding_VerifyFields_RoundTrip`, `TestSaveFinding_VerifyFields_Empty`, `TestOpen_MigratesExistingDB` — all pass. + +## Verification + +``` +go build ./... # clean +go test ./pkg/providers/... -run VerifySpec -v # 4/4 pass +go test ./pkg/storage/... -v # 10/10 pass +go test ./... # all green +grep -q 'tidwall/gjson' go.mod # direct dep +grep -rn 'SuccessCodes|VerifyStatus|verify_metadata_json' pkg/ # extensions landed +``` + +## Deviations from Plan + +**None material.** Two small additions made inline: + +1. **Added `ExtractMetadata` helper on `VerifySpec`** (Rule 3 — blocking issue). The plan required gjson to be in `go.mod` as a usable dependency, but `go get` without an actual import in code leaves it marked `// indirect`. Rather than run `go mod tidy` (explicitly forbidden in the plan), a tiny `ExtractMetadata` method was added that uses `gjson.GetBytes`. This promotes gjson to a direct require and gives Plan 05-03 a real starting point. The helper is intentionally minimal; Plan 05-03 owns the final extraction logic. + +2. **Added `TestVerifySpec_CanonicalFieldsPreferred`** (belt-and-braces test). Not in the plan's three required tests, but verifies that when both canonical and legacy fields are set, canonical wins — a contract every downstream plan depends on. + +## Downstream Contracts Ready + +| Consumer | Contract | +| ---------- | --------------------------------------------------------------------------------------------- | +| Plan 05-02 | `VerifySpec.Effective*Codes()`, `Finding.Verify*` fields for HTTPVerifier implementation | +| Plan 05-03 | `VerifySpec.MetadataPaths`, `ExtractMetadata` skeleton, gjson available | +| Plan 05-04 | `storage.Finding.Verified/VerifyStatus/VerifyMetadata` round-trip, migration is automatic | +| Plan 05-05 | YAML schema ready for Tier 1 provider verify-block enrichment | + +## Known Stubs + +- `VerifySpec.ExtractMetadata` is a minimal gjson extraction — only handles flat string values via `GetBytes`. **Plan 05-03 will replace this** with full metadata extraction (nested paths, type coercion, Content-Type gating). + +## Self-Check: PASSED + +Files verified: +- `pkg/providers/schema.go` — FOUND (SuccessCodes, MetadataPaths, ExtractMetadata, Effective* present) +- `pkg/providers/schema_test.go` — FOUND (4 tests) +- `pkg/engine/finding.go` — FOUND (Verified/VerifyStatus/VerifyHTTPCode/VerifyMetadata/VerifyError present) +- `pkg/storage/schema.sql` — FOUND (verify_metadata_json column present) +- `pkg/storage/db.go` — FOUND (migrateFindingsVerifyColumns present) +- `pkg/storage/findings.go` — FOUND (verify_* columns in SELECT/INSERT) +- `pkg/storage/findings_test.go` — FOUND (3 tests) +- `go.mod` — FOUND (`github.com/tidwall/gjson v1.18.0` in direct require block) + +Commits verified in `git log`: +- `499f5d5` — test(05-01) VerifySpec RED +- `30c0e98` — feat(05-01) VerifySpec GREEN +- `2654487` — test(05-01) storage RED +- `aec559d` — feat(05-01) storage GREEN + +Build + tests: `go build ./...` clean, `go test ./...` all pass.