--- phase: 01-foundation plan: 01 type: execute wave: 0 depends_on: [] files_modified: - go.mod - go.sum - main.go - testdata/samples/openai_key.txt - testdata/samples/anthropic_key.txt - testdata/samples/no_keys.txt - pkg/providers/registry_test.go - pkg/storage/db_test.go - pkg/engine/scanner_test.go autonomous: true requirements: [CORE-01, CORE-02, CORE-03, CORE-04, CORE-05, CORE-06, CORE-07, STOR-01, STOR-02, STOR-03, CLI-01] must_haves: truths: - "go.mod exists with all Phase 1 dependencies at pinned versions" - "go build ./... succeeds with zero errors on a fresh checkout" - "go test ./... -short runs without compilation errors (tests may fail — stubs are fine)" - "testdata/ contains files with known key patterns for scanner integration tests" artifacts: - path: "go.mod" provides: "Module declaration with all Phase 1 dependencies" contains: "module github.com/salvacybersec/keyhunter" - path: "main.go" provides: "Binary entry point under 30 lines" contains: "func main()" - path: "testdata/samples/openai_key.txt" provides: "Sample file with synthetic OpenAI key for scanner tests" - path: "pkg/providers/registry_test.go" provides: "Test stubs for provider loading and registry" - path: "pkg/storage/db_test.go" provides: "Test stubs for SQLite + encryption roundtrip" - path: "pkg/engine/scanner_test.go" provides: "Test stubs for pipeline stages" key_links: - from: "go.mod" to: "petar-dambovaliev/aho-corasick" via: "require directive" pattern: "petar-dambovaliev/aho-corasick" - from: "go.mod" to: "modernc.org/sqlite" via: "require directive" pattern: "modernc.org/sqlite" --- Initialize the Go module, install all Phase 1 dependencies at pinned versions, create the minimal main.go entry point, and lay down test scaffolding with testdata fixtures that every subsequent plan's tests depend on. Purpose: All subsequent plans require a compiling module and test infrastructure to exist before they can add production code and make tests green. Wave 0 satisfies this bootstrap requirement. Output: go.mod, go.sum, main.go, pkg/*/test stubs, testdata/ fixtures. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/01-foundation/01-RESEARCH.md @.planning/phases/01-foundation/01-VALIDATION.md Module: github.com/salvacybersec/keyhunter Dependencies to install: github.com/spf13/cobra@v1.10.2 github.com/spf13/viper@v1.21.0 modernc.org/sqlite@latest gopkg.in/yaml.v3@v3.0.1 github.com/petar-dambovaliev/aho-corasick@latest github.com/panjf2000/ants/v2@v2.12.0 golang.org/x/crypto@latest golang.org/x/time@latest github.com/charmbracelet/lipgloss@latest github.com/stretchr/testify@latest go 1.22 keyhunter/ main.go cmd/ root.go (created in Plan 05) scan.go (created in Plan 05) providers.go (created in Plan 05) config.go (created in Plan 05) pkg/ providers/ (created in Plan 02) engine/ (created in Plan 04) storage/ (created in Plan 03) config/ (created in Plan 05) output/ (created in Plan 05) providers/ (created in Plan 02) testdata/ samples/ Task 1: Initialize Go module and install Phase 1 dependencies go.mod, go.sum - /home/salva/Documents/apikey/.planning/phases/01-foundation/01-RESEARCH.md (Standard Stack section — exact library versions) - /home/salva/Documents/apikey/CLAUDE.md (Technology Stack table — version constraints) Run the following commands in the project root (/home/salva/Documents/apikey): ```bash go mod init github.com/salvacybersec/keyhunter go get github.com/spf13/cobra@v1.10.2 go get github.com/spf13/viper@v1.21.0 go get modernc.org/sqlite@latest go get gopkg.in/yaml.v3@v3.0.1 go get github.com/petar-dambovaliev/aho-corasick@latest go get github.com/panjf2000/ants/v2@v2.12.0 go get golang.org/x/crypto@latest go get golang.org/x/time@latest go get github.com/charmbracelet/lipgloss@latest go get github.com/stretchr/testify@latest go mod tidy ``` Verify the resulting go.mod contains: - `module github.com/salvacybersec/keyhunter` - `go 1.22` (or 1.22.x) - `github.com/spf13/cobra v1.10.2` - `github.com/spf13/viper v1.21.0` - `github.com/petar-dambovaliev/aho-corasick` (any version) - `github.com/panjf2000/ants/v2 v2.12.0` - `modernc.org/sqlite` (any v1.35.x) - `github.com/charmbracelet/lipgloss` (any version) Do NOT add: chi, templ, telego, gocron — these are Phase 17-18 only. Do NOT use CGO_ENABLED=1 or mattn/go-sqlite3. cd /home/salva/Documents/apikey && grep -q 'module github.com/salvacybersec/keyhunter' go.mod && grep -q 'cobra v1.10.2' go.mod && grep -q 'modernc.org/sqlite' go.mod && echo "go.mod OK" - go.mod contains `module github.com/salvacybersec/keyhunter` - go.mod contains `github.com/spf13/cobra v1.10.2` (exact) - go.mod contains `github.com/spf13/viper v1.21.0` (exact) - go.mod contains `github.com/panjf2000/ants/v2 v2.12.0` (exact) - go.mod contains `modernc.org/sqlite` (v1.35.x) - go.mod contains `github.com/petar-dambovaliev/aho-corasick` - go.mod contains `golang.org/x/crypto` - go.mod contains `github.com/charmbracelet/lipgloss` - go.sum exists and is non-empty - `go mod verify` exits 0 go.mod and go.sum committed with all Phase 1 dependencies at correct versions Task 2: Create main.go entry point and test scaffolding main.go, testdata/samples/openai_key.txt, testdata/samples/anthropic_key.txt, testdata/samples/multiple_keys.txt, testdata/samples/no_keys.txt, pkg/providers/registry_test.go, pkg/storage/db_test.go, pkg/engine/scanner_test.go - /home/salva/Documents/apikey/.planning/phases/01-foundation/01-VALIDATION.md (Wave 0 Requirements and Per-Task Verification Map) - /home/salva/Documents/apikey/.planning/phases/01-foundation/01-RESEARCH.md (Architecture Patterns, project structure diagram) Create the following files: **main.go** (must be under 30 lines): ```go package main import "github.com/salvacybersec/keyhunter/cmd" func main() { cmd.Execute() } ``` **testdata/samples/openai_key.txt** — file containing a synthetic (non-real) OpenAI-style key for scanner integration tests: ``` # Test file: synthetic OpenAI key pattern OPENAI_API_KEY=sk-proj-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr1234 ``` **testdata/samples/anthropic_key.txt** — file containing a synthetic Anthropic-style key: ``` # Test file: synthetic Anthropic key pattern export ANTHROPIC_API_KEY="sk-ant-api03-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy01234567890-ABCDE" ``` **testdata/samples/multiple_keys.txt** — file with both key types: ``` # Multiple providers in one file OPENAI_API_KEY=sk-proj-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr5678 ANTHROPIC_API_KEY=sk-ant-api03-XYZabcdefghijklmnopqrstuvwxyz01234567890ABCDEFGH-XYZAB ``` **testdata/samples/no_keys.txt** — file with no keys (negative test case): ``` # This file contains no API keys # Used to verify false-positive rate is zero for clean files Hello world ``` **pkg/providers/registry_test.go** — test stubs (will be filled by Plan 02): ```go package providers_test import ( "testing" ) // TestRegistryLoad verifies that provider YAML files are loaded from embed.FS. // Stub: will be implemented when registry.go exists (Plan 02). func TestRegistryLoad(t *testing.T) { t.Skip("stub — implement after registry.go exists") } // TestProviderSchemaValidation verifies format_version and last_verified are required. // Stub: will be implemented when schema.go validation exists (Plan 02). func TestProviderSchemaValidation(t *testing.T) { t.Skip("stub — implement after schema.go validation exists") } // TestAhoCorasickBuild verifies Aho-Corasick automaton builds from provider keywords. // Stub: will be implemented when registry builds automaton (Plan 02). func TestAhoCorasickBuild(t *testing.T) { t.Skip("stub — implement after registry AC build exists") } ``` **pkg/storage/db_test.go** — test stubs (will be filled by Plan 03): ```go package storage_test import ( "testing" ) // TestDBOpen verifies SQLite database opens and creates schema. // Stub: will be implemented when db.go exists (Plan 03). func TestDBOpen(t *testing.T) { t.Skip("stub — implement after db.go exists") } // TestEncryptDecryptRoundtrip verifies AES-256-GCM encrypt/decrypt roundtrip. // Stub: will be implemented when encrypt.go exists (Plan 03). func TestEncryptDecryptRoundtrip(t *testing.T) { t.Skip("stub — implement after encrypt.go exists") } // TestArgon2KeyDerivation verifies Argon2id produces 32-byte key deterministically. // Stub: will be implemented when crypto.go exists (Plan 03). func TestArgon2KeyDerivation(t *testing.T) { t.Skip("stub — implement after crypto.go exists") } ``` **pkg/engine/scanner_test.go** — test stubs (will be filled by Plan 04): ```go package engine_test import ( "testing" ) // TestShannonEntropy verifies the entropy function returns expected values. // Stub: will be implemented when entropy.go exists (Plan 04). func TestShannonEntropy(t *testing.T) { t.Skip("stub — implement after entropy.go exists") } // TestKeywordPreFilter verifies Aho-Corasick pre-filter rejects files without keywords. // Stub: will be implemented when filter.go exists (Plan 04). func TestKeywordPreFilter(t *testing.T) { t.Skip("stub — implement after filter.go exists") } // TestScannerPipeline verifies end-to-end scan of testdata returns expected findings. // Stub: will be implemented when engine.go exists (Plan 04). func TestScannerPipeline(t *testing.T) { t.Skip("stub — implement after engine.go exists") } ``` Create the `cmd/` package directory with a minimal stub so main.go compiles: **cmd/root.go** (minimal stub — will be replaced by Plan 05): ```go package cmd import "os" // Execute is a stub. The real command tree is built in Plan 05. func Execute() { _ = os.Args } ``` After creating all files, run `go build ./...` to confirm the module compiles. cd /home/salva/Documents/apikey && go build ./... && go test ./... -short 2>&1 | grep -v "^--- SKIP" | grep -v "^SKIP" | grep -v "^ok" || true && echo "BUILD OK" - `go build ./...` exits 0 with no errors - `go test ./... -short` exits 0 (all stubs skip, no failures) - main.go is under 30 lines - testdata/samples/openai_key.txt contains `sk-proj-` prefix - testdata/samples/anthropic_key.txt contains `sk-ant-api03-` prefix - testdata/samples/no_keys.txt contains no key patterns - pkg/providers/registry_test.go, pkg/storage/db_test.go, pkg/engine/scanner_test.go each exist with skip-based stubs - cmd/root.go exists so `go build ./...` compiles Module compiles, test stubs exist, testdata fixtures created. Subsequent plans can now add production code and make tests green. After both tasks: - `cd /home/salva/Documents/apikey && go build ./...` exits 0 - `go test ./... -short` exits 0 - `grep -r 'sk-proj-' testdata/` finds the OpenAI test fixture - `grep -r 'sk-ant-api03-' testdata/` finds the Anthropic test fixture - go.mod has all required dependencies at specified versions - go.mod initialized with module path `github.com/salvacybersec/keyhunter` and Go 1.22 - All 10 Phase 1 dependencies installed at correct versions - main.go under 30 lines, compiles successfully - 3 test stub files exist (providers, storage, engine) - 4 testdata fixture files exist (openai key, anthropic key, multiple keys, no keys) - `go build ./...` and `go test ./... -short` both exit 0 After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md` following the summary template.