Data Model: Auto-protect Agent Directories
Feature: Auto-protect Agent Directories Branch: 003-auto-protect-agent Date: 2025-11-10
Overview
This document defines the data structures and relationships for the gitignore management system that protects AI agent directories.
Core Entities
1. GitignoreManager
Purpose: Central manager for all gitignore operations
Attributes:
project_path: Path - Root directory of the projectgitignore_path: Path - Full path to .gitignore fileagent_registry: Set[str] - Static registry of all known agent directoriesmarker: str - Comment marker for auto-managed sections
Methods:
__init__(project_path: Path)- Initialize with project rootprotect_all_agents()- Add all agent directories to gitignoreprotect_selected_agents(agents: List[str])- Add specific agent directoriesensure_entries(entries: List[str])- Core method to add entriescheck_entry_exists(entry: str)- Check if entry already existsget_existing_entries()- Read current gitignore contents
Relationships:
- Manages � GitignoreFile (1:1)
- References � AgentDirectory (1:N)
2. AgentDirectory
Purpose: Represents a single agent's directory that needs protection
Attributes:
name: str - Agent name (e.g., "claude", "codex")directory: str - Directory path with trailing slash (e.g., ".claude/")is_special: bool - Indicates special handling needed (e.g., .github/)description: str - Human-readable description for documentation
Static Registry:
AGENT_DIRECTORIES = [
AgentDirectory("claude", ".claude/", False, "Claude Code CLI"),
AgentDirectory("codex", ".codex/", False, "Codex (contains auth.json)"),
AgentDirectory("opencode", ".opencode/", False, "opencode CLI"),
AgentDirectory("windsurf", ".windsurf/", False, "Windsurf"),
AgentDirectory("gemini", ".gemini/", False, "Google Gemini"),
AgentDirectory("cursor", ".cursor/", False, "Cursor"),
AgentDirectory("qwen", ".qwen/", False, "Qwen"),
AgentDirectory("kilocode", ".kilocode/", False, "Kilocode"),
AgentDirectory("auggie", ".augment/", False, "Auggie"),
AgentDirectory("github", ".github/", True, "GitHub Copilot (shared with Actions)"),
AgentDirectory("roo", ".roo/", False, "Roo Coder"),
AgentDirectory("amazonq", ".amazonq/", False, "Amazon Q"),
]
Relationships:
- Managed by � GitignoreManager (N:1)
3. GitignoreFile
Purpose: Represents the actual .gitignore file
Attributes:
path: Path - Full file pathcontent: List[str] - Lines in the fileline_ending: str - Detected line ending style ("\n" or "\r\n")exists: bool - Whether file exists on disk
Methods:
read()- Read file contents from diskwrite(content: List[str])- Write content to diskdetect_line_ending()- Detect and preserve line ending stylehas_entry(entry: str)- Check if specific entry exists
Relationships:
- Managed by � GitignoreManager (1:1)
4. GitignoreEntry
Purpose: Represents a single line/pattern in gitignore
Attributes:
pattern: str - The gitignore pattern (e.g., ".claude/")comment: Optional[str] - Associated comment if anyis_auto_managed: bool - Whether added by spec-kittyline_number: Optional[int] - Position in file
Validation Rules:
- Pattern must not be empty
- Pattern should not contain invalid characters
- Directories should end with trailing slash
5. ProtectionResult
Purpose: Result of gitignore protection operation
Attributes:
success: bool - Whether operation succeededmodified: bool - Whether gitignore was modifiedentries_added: List[str] - New entries addedentries_skipped: List[str] - Entries already presenterrors: List[str] - Any errors encounteredwarnings: List[str] - Any warnings generated
Methods:
to_console_output()- Format for user displaylog_details()- Detailed logging output
State Transitions
GitignoreFile States
NONEXISTENT � CREATED � POPULATED � MODIFIED
� � �
4
1. NONEXISTENT: No .gitignore file exists 2. CREATED: Empty .gitignore file created 3. POPULATED: Initial entries added 4. MODIFIED: Subsequent modifications
Protection Operation Flow
START � CHECK_FILE � READ_CONTENTS � DETECT_DUPLICATES � ADD_ENTRIES � WRITE_FILE � END
� � �
CREATE_FILE SKIP_ENTRY HANDLE_ERROR
� � �
4 � END
Data Validation Rules
GitignoreManager
project_pathmust be valid directoryproject_pathmust be writable- Agent registry must not be empty
AgentDirectory
- Directory name must start with dot
- Directory name must end with slash
- No duplicate directories in registry
GitignoreFile
- Line endings must be consistent throughout file
- Marker comment must be unique
- No duplicate entries allowed
GitignoreEntry
- Pattern must follow gitignore syntax
- Comments must start with #
- No leading/trailing whitespace in patterns
Performance Considerations
Memory Usage
- Entire .gitignore file loaded into memory
- Agent registry is static (compile-time constant)
- Typical memory footprint: < 100KB
Time Complexity
- Entry lookup: O(n) where n = lines in gitignore
- Duplicate detection: O(n) using set operations
- File write: O(n) single pass
I/O Operations
- Maximum 1 read operation per init
- Maximum 1 write operation per init
- No recursive directory scanning
Error Handling
Recoverable Errors
- File permission issues � Warning + instructions
- Invalid patterns � Skip with warning
- Duplicate entries � Skip silently
Non-Recoverable Errors
- Project path not found � Exit with error
- Out of disk space � Exit with error
- Corrupted file system � Exit with error
Migration Path
From Existing System
Since handle_codex_security is an internal function:
1. Direct Replacement:
- Remove
handle_codex_security()function - Replace with GitignoreManager calls
- Update all tests to use new implementation
2. No Breaking Changes:
- This is an internal refactoring
- No public API changes
- Users won't notice any difference
Future Extensions
Potential Enhancements
1. Pattern Templates: Support for complex gitignore patterns 2. Exclusion Lists: Allow users to exclude certain agents 3. Custom Directories: User-defined directories to protect 4. Conditional Rules: Platform-specific or context-aware rules 5. Audit Trail: Log of all gitignore modifications
Integration Points
- Configuration file support
- Environment variable overrides
- CLI flags for fine-grained control
- API for external tools