diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 3588c00..4367f80 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -88,7 +88,7 @@ Requirements for initial release. Each maps to roadmap phases. ### CI/CD Integration -- [ ] **CICD-01**: keyhunter hook install/uninstall for git pre-commit hooks +- [x] **CICD-01**: keyhunter hook install/uninstall for git pre-commit hooks - [x] **CICD-02**: SARIF output uploadable to GitHub Security tab ### OSINT/Recon — IoT & Internet Scanners diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index d9ffc04..47344de 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -165,8 +165,8 @@ Plans: - [x] 07-02-PLAN.md — Gitleaks JSON + CSV parsers (IMP-02) - [x] 07-03-PLAN.md — Dedup helper + SARIF GitHub Code Scanning validation test (IMP-03, CICD-02) - [ ] 07-04-PLAN.md — cmd/import.go wiring format dispatch, dedup, DB persistence (IMP-01/02/03) -- [ ] 07-05-PLAN.md — cmd/hook.go install/uninstall with embedded pre-commit script (CICD-01) -- [ ] 07-06-PLAN.md — docs/CI-CD.md + README CI/CD section with GitHub Actions workflow (CICD-01, CICD-02) +- [x] 07-05-PLAN.md — cmd/hook.go install/uninstall with embedded pre-commit script (CICD-01) +- [x] 07-06-PLAN.md — docs/CI-CD.md + README CI/CD section with GitHub Actions workflow (CICD-01, CICD-02) ### Phase 8: Dork Engine **Goal**: Users can run, manage, and extend a library of 150+ built-in YAML dorks across GitHub, Google, Shodan, Censys, ZoomEye, FOFA, GitLab, and Bing — using the same extensibility pattern as provider definitions diff --git a/.planning/STATE.md b/.planning/STATE.md index 1aa7015..e051cdb 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,13 +4,13 @@ milestone: v1.0 milestone_name: milestone status: executing stopped_at: Completed 06-06-PLAN.md -last_updated: "2026-04-05T20:56:37.008Z" -last_activity: 2026-04-05 -- Phase 07 execution started +last_updated: "2026-04-05T20:59:28.295Z" +last_activity: 2026-04-05 progress: total_phases: 18 completed_phases: 6 total_plans: 40 - completed_plans: 37 + completed_plans: 39 percent: 20 --- @@ -26,9 +26,9 @@ See: .planning/PROJECT.md (updated 2026-04-04) ## Current Position Phase: 07 (import-cicd) — EXECUTING -Plan: 1 of 6 -Status: Executing Phase 07 -Last activity: 2026-04-05 -- Phase 07 execution started +Plan: 2 of 6 +Status: Ready to execute +Last activity: 2026-04-05 Progress: [██░░░░░░░░] 20% diff --git a/.planning/phases/07-import-cicd/07-05-SUMMARY.md b/.planning/phases/07-import-cicd/07-05-SUMMARY.md new file mode 100644 index 0000000..27cf635 --- /dev/null +++ b/.planning/phases/07-import-cicd/07-05-SUMMARY.md @@ -0,0 +1,93 @@ +--- +phase: 07-import-cicd +plan: 05 +subsystem: cmd/hook +tags: [cicd, git, pre-commit, hook, embed] +requires: [cmd/root.go hookCmd registration] +provides: [keyhunter hook install, keyhunter hook uninstall, embedded pre-commit script] +affects: [cmd/stubs.go] +tech-stack: + added: [embed (stdlib)] + patterns: [go:embed compile-time script bundling, marker-based ownership detection] +key-files: + created: + - cmd/hook.go + - cmd/hook_script.sh + - cmd/hook_test.go + modified: + - cmd/stubs.go +decisions: + - "Use KEYHUNTER-HOOK v1 marker string to detect KeyHunter-owned hooks before overwrite/delete" + - "Backup non-owned hooks on --force install instead of silent destruction (pre-commit.bak.)" + - "Reuse same --force flag variable for install/uninstall since commands are mutually exclusive" + - "Embed script via go:embed rather than string literal to preserve shell formatting and allow standalone editing" +metrics: + duration: ~5m + completed: 2026-04-05 +requirements: [CICD-01] +--- + +# Phase 7 Plan 5: cmd/hook Install/Uninstall Summary + +Git pre-commit hook lifecycle via `keyhunter hook install`/`uninstall`, with the pre-commit script bundled at compile time through `go:embed`. + +## What Was Built + +- **cmd/hook.go** — `hookCmd` parent with `install` and `uninstall` subcommands, shared `--force` flag, `.git/` validation via `hookPath()`, marker-aware overwrite/delete logic. +- **cmd/hook_script.sh** — Embedded bash script carrying the `KEYHUNTER-HOOK v1` marker. Reads staged files via `git diff --cached --name-only --diff-filter=ACMR`, pipes through `xargs -r keyhunter scan --exit-code`, propagates exit code to block commits on findings. Trailing newline preserved. +- **cmd/hook_test.go** — 10 tests: + - `TestHookInstall_FreshRepo` — mode 0o755, marker present + - `TestHookInstall_NotAGitRepo` — error when no `.git/` + - `TestHookInstall_ExistingNonKeyhunterRefuses` — refuses without `--force` + - `TestHookInstall_ForceBackupsExisting` — `.bak.` backup created + - `TestHookInstall_ExistingKeyhunterOverwrites` — updates stale marker hook silently + - `TestHookUninstall_RemovesKeyhunter` — install then remove lifecycle + - `TestHookUninstall_RefusesForeign` — refuses non-marker file + - `TestHookUninstall_Force` — removes foreign with `--force` + - `TestHookUninstall_Missing` — no-op friendly message + - `TestHookScript_ContainsRequired` — embedded script sanity check +- **cmd/stubs.go** — Removed `hookCmd` stub block; kept every other stub. + +## Verification + +``` +go build ./... # succeeds +go test ./cmd/... -run Hook -v + 10 tests, all PASS +``` + +Commit: aa8daf8 + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Transient importCmd build error** +- **Found during:** Task 1 verification (`go build`) +- **Issue:** Initial `go build` failed with `undefined: importCmd` because the stubs.go linter-driven update removed `importCmd` while `cmd/import.go` wasn't visible in the workspace yet. +- **Fix:** Re-scanned workspace; `cmd/import.go` was present (plan 07-04's output), no action needed beyond ensuring `stubs.go` does not redeclare `importCmd`. Final `go build` succeeds. +- **Files modified:** none beyond plan scope +- **Commit:** aa8daf8 (same task commit) + +## Key Decisions + +- **Marker string as ownership signal.** `KEYHUNTER-HOOK v1` in the script header lets uninstall/overwrite distinguish our hooks from user-authored ones without an external manifest file. The `v1` suffix reserves space for future script format bumps. +- **Backup-on-force rather than destroy.** `--force` install renames the existing hook to `pre-commit.bak.` instead of deleting, giving users a recovery path if they aimed the flag carelessly. +- **No global `viper`/config wiring.** The hook commands are filesystem-only; introducing config loading would add surface area for zero benefit at this layer. + +## Files Created/Modified + +- Created: cmd/hook.go (~105 lines) +- Created: cmd/hook_script.sh (20 lines) +- Created: cmd/hook_test.go (~180 lines) +- Modified: cmd/stubs.go (removed 6-line stub block) + +## Self-Check: PASSED + +- cmd/hook.go: FOUND +- cmd/hook_script.sh: FOUND +- cmd/hook_test.go: FOUND +- Commit aa8daf8: FOUND +- `go build ./...`: PASS +- `go test ./cmd/... -run Hook`: 10/10 PASS +- Stub removed from cmd/stubs.go: CONFIRMED