diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..9e4544f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,26 @@ +# CODEOWNERS - Require human approval for critical files +# +# These patterns require explicit human review before merging. +# AI agents (Claude, etc.) cannot approve changes to these files. + +# Project identity and module path - NEVER change without owner approval +go.mod @CodeMonkeyCybersecurity/owners +go.sum @CodeMonkeyCybersecurity/owners + +# Repository configuration +.github/ @CodeMonkeyCybersecurity/owners +.gitignore @CodeMonkeyCybersecurity/owners + +# Build and deployment +Makefile @CodeMonkeyCybersecurity/owners +Dockerfile* @CodeMonkeyCybersecurity/owners +docker-compose*.yml @CodeMonkeyCybersecurity/owners + +# Documentation that defines project identity +README.md @CodeMonkeyCybersecurity/owners +CLAUDE.md @CodeMonkeyCybersecurity/owners +LICENSE* @CodeMonkeyCybersecurity/owners + +# Configuration files +*.yaml @CodeMonkeyCybersecurity/owners +*.yml @CodeMonkeyCybersecurity/owners diff --git a/CLAUDE.md b/CLAUDE.md index b0863a0..a005697 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,6 +51,41 @@ When looking for context, Claude should: - **Actionable**: Every criticism includes a concrete fix - **Human-focused**: Remember this tool serves security researchers who need reliable results +### AI Agent Boundaries (MANDATORY) + +**NEVER do these without explicit human authorization:** + +1. **Project Identity Changes** + - NEVER rename the project, module path, or executable + - NEVER change `go.mod` module path + - NEVER rename the GitHub repository + - The project is called `shells` - this is final + +2. **Architectural Decisions** + - NEVER restructure the entire codebase + - NEVER change the primary language or framework + - NEVER migrate to different infrastructure (e.g., Kubernetes) + - ASK before making changes that affect >50 files + +3. **External Dependencies** + - NEVER add major new dependencies without asking + - NEVER remove existing dependencies that are in use + - NEVER upgrade to major versions (e.g., v1 → v2) + +4. **Configuration and Deployment** + - NEVER modify CI/CD pipelines without asking + - NEVER change deployment targets or methods + - NEVER modify security-sensitive configurations + +**ALWAYS do these:** + +1. **Ask before major changes** - If a change affects project identity, architecture, or >20 files, ask first +2. **Verify builds** - Run `go build ./...` before committing +3. **Follow existing patterns** - Match the style and structure of existing code +4. **Document decisions** - Add inline comments explaining non-obvious choices + +**Incident Reference**: PR #4 renamed the project from `shells` to `artemis` without authorization, causing divergent branches and build failures. This section exists to prevent similar incidents. + ## Common Development Commands ### Build and Test diff --git a/Makefile b/Makefile index f90dfde..abaab8f 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all deps build install test clean fmt vet +.PHONY: all deps build install test clean fmt vet install-hooks # Default target all: build @@ -37,4 +37,12 @@ check: fmt vet test # Development build with race detection dev: - go build -race -o shells . \ No newline at end of file + go build -race -o shells . + +# Install git hooks for development +install-hooks: + @echo "Installing git hooks..." + @cp scripts/git-hooks/pre-commit .git/hooks/pre-commit + @cp scripts/git-hooks/pre-push .git/hooks/pre-push + @chmod +x .git/hooks/pre-commit .git/hooks/pre-push + @echo "Git hooks installed successfully." \ No newline at end of file diff --git a/scripts/git-hooks/pre-commit b/scripts/git-hooks/pre-commit new file mode 100755 index 0000000..f3898ad --- /dev/null +++ b/scripts/git-hooks/pre-commit @@ -0,0 +1,44 @@ +#!/bin/bash +# pre-commit hook - Validates critical files before commit +# +# Install: cp scripts/git-hooks/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit +# Or run: make install-hooks + +set -e + +# Check if go.mod module path is being changed +if git diff --cached --name-only | grep -q "^go.mod$"; then + # Get the module path from staged go.mod + staged_module=$(git show :go.mod | grep "^module " | awk '{print $2}') + + # Verify it's still shells + if [[ "$staged_module" != "github.com/CodeMonkeyCybersecurity/shells" ]]; then + echo "" + echo "ERROR: Module path change detected!" + echo "" + echo " Current: $staged_module" + echo " Expected: github.com/CodeMonkeyCybersecurity/shells" + echo "" + echo "The project module path must remain 'github.com/CodeMonkeyCybersecurity/shells'." + echo "If you need to change this, get explicit owner approval first." + echo "" + exit 1 + fi +fi + +# Run gofmt on staged Go files +staged_go_files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$' || true) +if [[ -n "$staged_go_files" ]]; then + unformatted=$(gofmt -l $staged_go_files 2>/dev/null || true) + if [[ -n "$unformatted" ]]; then + echo "" + echo "WARNING: Some Go files are not formatted:" + echo "$unformatted" + echo "" + echo "Run 'gofmt -w' on these files or 'make fmt'" + echo "" + # Warning only, don't block + fi +fi + +exit 0 diff --git a/scripts/git-hooks/pre-push b/scripts/git-hooks/pre-push new file mode 100755 index 0000000..9d793f0 --- /dev/null +++ b/scripts/git-hooks/pre-push @@ -0,0 +1,56 @@ +#!/bin/bash +# pre-push hook - Prevents pushing when local and remote have diverged +# +# Install: cp scripts/git-hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push +# Or run: make install-hooks + +set -e + +remote="$1" +url="$2" + +# Only check pushes to origin +if [[ "$remote" != "origin" ]]; then + exit 0 +fi + +# Get current branch +branch=$(git rev-parse --abbrev-ref HEAD) + +# Skip for new branches (no upstream) +if ! git rev-parse --verify "origin/$branch" &>/dev/null; then + exit 0 +fi + +# Check for divergence +local_only=$(git rev-list "origin/$branch..$branch" --count 2>/dev/null || echo "0") +remote_only=$(git rev-list "$branch..origin/$branch" --count 2>/dev/null || echo "0") + +if [[ "$local_only" -gt 0 ]] && [[ "$remote_only" -gt 0 ]]; then + echo "" + echo "ERROR: Branches have diverged!" + echo "" + echo " Local has $local_only commit(s) not on remote" + echo " Remote has $remote_only commit(s) not on local" + echo "" + echo "To fix:" + echo " 1. git fetch origin" + echo " 2. git rebase origin/$branch # or git merge origin/$branch" + echo " 3. Resolve any conflicts" + echo " 4. git push" + echo "" + exit 1 +fi + +# Verify build passes before push (optional - can be slow) +if [[ -f "go.mod" ]]; then + echo "Verifying build..." + if ! go build ./... 2>/dev/null; then + echo "" + echo "ERROR: Build failed! Fix build errors before pushing." + echo "" + exit 1 + fi +fi + +exit 0