Log a warning for each AI provider registered without an API key so that misconfiguration is surfaced at boot time (not silently on the first API call). Each message names the environment variable to set: ANTHROPIC_API_KEY – Claude GOOGLE_AI_API_KEY – Gemini OPENAI_API_KEY – OpenAI Providers without a key remain registered but are marked unavailable via isAvailable(), preserving backward compatibility. - Add Log::warning() calls in registerProviders() for empty keys - Extend AgenticManagerTest with a dedicated 'API key validation warnings' describe block (7 new test cases) - Update DX-002 in TODO.md as resolved Closes #29 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13 KiB
TODO.md - core-agentic
Production-quality task list for the AI agent orchestration package.
Last updated: 2026-01-29
P1 - Critical / Security
Security Hardening
-
SEC-001: API key hashing uses SHA-256 without salt (FIXED 2026-01-29)
- Location:
Models/AgentApiKey.php::generate() - Risk: Weak credential storage vulnerable to rainbow table attacks
- Fix: Switched to
password_hash()with Argon2id - Note:
findByKey()now iterates active keys since Argon2id uses unique salts - Added
verifyKey()method for single-key verification
- Location:
-
SEC-002: SQL injection risk in TaskCommand orderByRaw (FIXED 2026-01-29)
- Location:
Console/Commands/TaskCommand.php - Risk:
orderByRaw("FIELD(priority, ...)")pattern vulnerable if extended - Fix: Replaced with parameterised
orderByPriority()andorderByStatus()scopes - Also fixed
PlanCommand.phpwith same pattern
- Location:
-
SEC-003: StateSet tool lacks workspace scoping (FIXED 2026-01-29)
- Location:
Mcp/Tools/Agent/State/StateSet.php - Risk: Plan lookup by slug without workspace constraint - cross-tenant data access
- Fix: Added workspace_id context check and forWorkspace() scoping to:
StateSet.php,StateGet.php,StateList.phpPlanGet.php,PlanList.php
- Added ToolDependency for workspace_id requirement
- Location:
-
SEC-004: Missing rate limiting on MCP tool execution
- Location:
Services/AgentToolRegistry.php::execute() - Risk: API key rate limits apply to auth, not individual tool calls
- Fix: Add per-tool rate limiting in execute() method
- Acceptance: Tool execution respects rate limits per workspace
- Location:
Input Validation
- VAL-001: Template variable injection vulnerability
- Location:
Services/PlanTemplateService.php::substituteVariables() - Risk: Special characters in variables could corrupt JSON structure
- Status: Partially fixed with escapeForJson, but needs additional input sanitisation
- Fix: Validate variable values against allowed character sets
- Acceptance: Malicious variable values rejected with clear error
- Location:
P2 - High Priority
Test Coverage (Critical Gap)
-
TEST-001: Add AgentApiKey model tests (FIXED 2026-01-29)
- Created
tests/Feature/AgentApiKeyTest.phpusing Pest functional syntax - Created
tests/Pest.phpfor Pest configuration with helper functions - Covers: key generation with Argon2id, validation, permissions, rate limiting, IP restrictions
- Additional coverage: key rotation, security edge cases
- 70+ test cases for comprehensive model coverage
- Created
-
TEST-002: Add AgentApiKeyService tests (FIXED 2026-01-29)
- Created
tests/Feature/AgentApiKeyServiceTest.phpusing Pest functional syntax - Covers: authenticate(), IP validation, rate limit tracking, key management
- 58 test cases including full authentication flow and edge cases
- Created
-
TEST-003: Add IpRestrictionService tests (FIXED 2026-01-29)
- Created
tests/Feature/IpRestrictionServiceTest.phpusing Pest functional syntax - Covers: IPv4/IPv6 validation, CIDR matching (all prefix lengths), edge cases
- 78 test cases for security-critical IP whitelisting
- Created
-
TEST-004: Add PlanTemplateService tests (FIXED 2026-01-29)
- Created
tests/Feature/PlanTemplateServiceTest.phpusing Pest functional syntax - Covers: template listing, retrieval, preview, variable substitution, plan creation, validation, categories, context generation
- 47 test cases organised into 9 describe blocks with proper beforeEach/afterEach setup
- Created
-
TEST-005: Add AI provider service tests (FIXED 2026-01-29)
- Created
tests/Unit/ClaudeServiceTest.php- Anthropic Claude API tests (Pest functional syntax) - Created
tests/Unit/GeminiServiceTest.php- Google Gemini API tests (Pest functional syntax) - Created
tests/Unit/OpenAIServiceTest.php- OpenAI API tests (Pest functional syntax) - Created
tests/Unit/AgenticManagerTest.php- Provider coordinator tests (Pest functional syntax) - All use mocked HTTP responses with describe/it blocks
- Covers: provider configuration, API key management, request handling, response parsing
- Includes: error handling, retry logic (429/500), edge cases, streaming
- AgenticManager tests: provider registration, retrieval, availability, default provider handling
- Created
Missing Database Infrastructure
-
DB-001: Missing agent_plans table migration (FIXED 2026-01-29)
- Created
Migrations/0001_01_01_000003_create_agent_plans_tables.php - Creates:
agent_plans,agent_phases,agent_workspace_statestables - Adds
agent_plan_idFK and related columns toagent_sessions - Includes proper indexes for slug, workspace, and status queries
- Created
-
DB-002: Missing indexes on frequently queried columns (FIXED 2026-02-23)
agent_sessions.session_id- unique() constraint creates implicit index; sufficient for lookupsagent_plans.slug- redundant plain index dropped; compound (workspace_id, slug) index addedworkspace_states.key- already indexed via ->index('key') in migration 000003
Error Handling
-
ERR-001: ClaudeService stream() lacks error handling
- Location:
Services/ClaudeService.php::stream() - Issue: No try/catch around streaming, could fail silently
- Fix: Wrap in exception handling, yield error events
- Location:
-
ERR-002: ContentService has no batch failure recovery
- Location:
Services/ContentService.php::generateBatch() - Issue: Failed articles stop processing, no resume capability
- Fix: Add progress tracking, allow resuming from failed point
- Location:
P3 - Medium Priority
Developer Experience
-
DX-001: Missing workspace context error messages unclear
- Location: Multiple MCP tools
- Issue: "workspace_id is required" doesn't explain how to fix
- Fix: Include context about authentication/session setup
-
DX-002: AgenticManager doesn't validate API keys on init (FIXED 2026-02-23)
- Location:
Services/AgenticManager.php::registerProviders() - Issue: Empty API key creates provider that fails on first use
- Fix:
Log::warning()emitted for each provider registered without an API key; message names the env var to set
- Location:
-
DX-003: Plan template variable errors not actionable
- Location:
Services/PlanTemplateService.php::validateVariables() - Fix: Include expected format, examples in error messages
- Location:
Code Quality
-
CQ-001: Duplicate state models (WorkspaceState vs AgentWorkspaceState)
- Files:
Models/WorkspaceState.php,Models/AgentWorkspaceState.php - Issue: Two similar models for same purpose
- Fix: Consolidate into single model, or clarify distinct purposes
- Files:
-
CQ-002: ApiKeyManager uses Core\Api\ApiKey, not AgentApiKey (FIXED 2026-02-23)
- Location:
View/Modal/Admin/ApiKeyManager.php - Issue: Livewire component uses different API key model than services
- Fix: Switched to
AgentApiKeymodel andAgentApiKeyServicethroughout - Updated blade template to use
permissions,getMaskedKey(),togglePermission() - Added integration tests in
tests/Feature/ApiKeyManagerTest.php
- Location:
-
CQ-003: ForAgentsController cache key not namespaced (FIXED 2026-02-23)
- Location:
Controllers/ForAgentsController.php - Issue:
Cache::remember('agentic.for-agents.json', ...)could collide - Fix: Cache key and TTL now driven by
mcp.cache.for_agents_key/mcp.cache.for_agents_ttlconfig - Added
cacheKey()public method and config entries inconfig.php - Tests added in
tests/Feature/ForAgentsControllerTest.php
- Location:
Performance
-
PERF-001: AgentPhase::checkDependencies does N queries
- Location:
Models/AgentPhase.php::checkDependencies() - Issue: Loops through dependencies with individual
find()calls - Fix: Eager load or use whereIn for batch lookup
- Location:
-
PERF-002: AgentToolRegistry::forApiKey iterates all tools
- Location:
Services/AgentToolRegistry.php::forApiKey() - Issue: O(n) filter on every request
- Fix: Cache permitted tools per API key
- Location:
P4 - Low Priority
Documentation Gaps
-
DOC-001: Add PHPDoc to AgentDetection patterns
- Location:
Services/AgentDetection.php - Issue: User-Agent patterns undocumented
- Fix: Document each pattern with agent examples
- Location:
-
DOC-002: Document MCP tool dependency system
- Location:
Mcp/Tools/Agent/directory - Fix: Add README explaining ToolDependency, context requirements
- Location:
Feature Completion
-
FEAT-001: Session cleanup for stale sessions
- Issue: No mechanism to clean up abandoned sessions
- Fix: Add scheduled command to mark stale sessions as failed
- Criteria: Sessions inactive >24h marked as abandoned
-
FEAT-002: Plan archival with data retention policy
- Issue: Archived plans kept forever
- Fix: Add configurable retention period, cleanup job
-
FEAT-003: Template version management
- Location:
Services/PlanTemplateService.php - Issue: Template changes affect existing plan references
- Fix: Add version tracking to templates
- Location:
Consistency
-
CON-001: Mixed UK/US spelling in code comments
- Issue: Some comments use "organize" instead of "organise"
- Fix: Audit and fix to UK English per CLAUDE.md
-
CON-002: Inconsistent error response format
- Issue: Some tools return
['error' => ...], others['success' => false, ...] - Fix: Standardise on single error response format
- Issue: Some tools return
P5 - Nice to Have
Observability
-
OBS-001: Add structured logging to AI provider calls
- Issue: No visibility into API call timing, token usage
- Fix: Add Log::info with provider, model, tokens, latency
-
OBS-002: Add Prometheus metrics for tool execution
- Fix: Emit tool_execution_seconds, tool_errors_total
Admin UI Improvements
-
UI-001: Add bulk operations to plan list
- Fix: Multi-select archive, activate actions
-
UI-002: Add session timeline visualisation
- Fix: Visual work_log display with timestamps
-
UI-003: Add template preview before creation
- Fix: Show resolved variables, phase list
P6 - Future / Backlog
Architecture Evolution
-
ARCH-001: Consider event sourcing for session work_log
- Benefit: Full replay capability, audit trail
- Consideration: Adds complexity
-
ARCH-002: Extract AI provider abstraction to separate package
- Benefit: Reusable across other modules
- Consideration: Increases package count
Integration
-
INT-001: Add webhook notifications for plan status changes
- Use: External integrations can react to agent progress
-
INT-002: Add Slack/Discord integration for session alerts
- Use: Team visibility into agent operations
Completed Items
Security (Fixed)
- Missing
agent_api_keystable migration - Migration added - Rate limiting bypass - getRecentCallCount now reads from cache
- Admin routes lack middleware - RequireHades applied
- ForAgentsController missing rate limiting - Added
- SEC-001: API key hashing SHA-256 to Argon2id - Switched to password_hash() (2026-01-29)
- SEC-002: SQL injection in orderByRaw - Replaced with parameterised scopes (2026-01-29)
- SEC-003: StateSet/StateGet/StateList/PlanGet/PlanList workspace scoping - Added forWorkspace() checks (2026-01-29)
Code Quality (Fixed)
- Add retry logic to AI provider services - HasRetry trait added
- Stream parsing fragile - HasStreamParsing trait added
- ContentService hardcoded paths - Now configurable
- Rate limit TTL race condition - Uses Cache::add()
- JSON escaping in template substitution - Added
DX (Fixed)
- MCP tool handlers commented out - Documented properly
- MCP token lookup not implemented - Database lookup added
Test Coverage (Fixed)
- TEST-001: AgentApiKey model tests - 70+ tests in AgentApiKeyTest.php (2026-01-29)
- TEST-002: AgentApiKeyService tests - 58 tests in AgentApiKeyServiceTest.php (2026-01-29)
- TEST-003: IpRestrictionService tests - 78 tests in IpRestrictionServiceTest.php (2026-01-29)
- TEST-004: PlanTemplateService tests - 35+ tests in PlanTemplateServiceTest.php (2026-01-29)
- TEST-005: AI provider tests - ClaudeServiceTest, GeminiServiceTest, OpenAIServiceTest, AgenticManagerTest (2026-01-29)
Database (Fixed)
- DB-001: Missing agent_plans migration - Created 0001_01_01_000003_create_agent_plans_tables.php (2026-01-29)
- DB-002: Performance indexes - Dropped redundant slug index, added compound (workspace_id, slug) index (2026-02-23)
Notes
Test Coverage Estimate: ~65% (improved from ~35%)
- Models: Well tested (AgentPlan, AgentPhase, AgentSession, AgentApiKey)
- Services: AgentApiKeyService, IpRestrictionService, PlanTemplateService now tested
- AI Providers: ClaudeService, GeminiService, OpenAIService, AgenticManager unit tested
- Commands: Untested (3 commands)
- Livewire: Untested
Priority Guide:
- P1: Security/data integrity - fix before production
- P2: High impact on reliability - fix in next sprint
- P3: Developer friction - address during regular work
- P4: Nice to have - backlog candidates
- P5: Polish - when time permits
- P6: Future considerations - parking lot