From 426db31557a44fa308d6dfeb99eaa844ebb82a63 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman Date: Fri, 6 Feb 2026 12:16:41 -0500 Subject: [PATCH] docs: Added significant details and finalized (hopefully) task assignments --- implementation_plan.md | 2887 +++++++++++++++++++++++++++++++++++----- specification.md | 427 +++++- 2 files changed, 2910 insertions(+), 404 deletions(-) diff --git a/implementation_plan.md b/implementation_plan.md index e99534b57..1ed116845 100644 --- a/implementation_plan.md +++ b/implementation_plan.md @@ -53,7 +53,7 @@ While CleverAgents leverages LangGraph and LangChain for the underlying LLM runt | Concept | Definition | |---------|------------| -| **Plan** | A tracked lifecycle for a single unit-of-work (which may spawn subplans). Phases: Action → Strategize → Execute → Apply | +| **Plan** | A tracked lifecycle for a single unit-of-work (which may spawn subplans). Phases: Action -> Strategize -> Execute -> Apply | | **Action** | A reusable plan template. Created via CLI commands (NOT YAML files). | | **Actor** | Anything conversational; may be a single agent/LLM or an entire graph. Defined via YAML configuration files. Always named `/`. | | **Project** | A collection of resources + configuration. Created via CLI commands (NOT YAML files). | @@ -115,7 +115,7 @@ The implementation concludes only when every checklist item and spawned remediat ### Plan Lifecycle Phases ``` -Action → Strategize → Execute → Apply → Applied (terminal) +Action -> Strategize -> Execute -> Apply -> Applied (terminal) ``` | Current Phase | Command Verb | Next Phase | @@ -303,6 +303,28 @@ The following work from the previous implementation has been completed and will - Added 15 Behave test scenarios in `features/action_cli.feature` - Total test scenarios: 96 (81 + 15) +**2026-02-06**: CRITICAL ARCHITECTURAL DECISION - Tool-Based Resource Modification +- **REPLACED**: OutputParser/code fence parsing approach +- **WITH**: Tool-based change tracking (modern approach used by Claude Code, Cursor, Aider) +- **Key changes**: + - LLMs call skills/tools directly (edit_file, write_file, delete_file, etc.) + - Skills operate on sandbox state directly + - ChangeSet is built from skill invocation history, NOT by parsing LLM text output + - Added built-in resource skills (C3.6): file ops, dir ops, search, git ops + - Added MCP skill adapter (C3.7): connect to external MCP servers + - Replaced C4 "Multi-File ChangeSet Generation" with "Tool-Based Change Tracking" + - Added SkillInvocationTracker and ToolCallRouter components +- **Rationale**: + - No parsing ambiguity (is this code or explanation?) + - Each operation is explicit, typed, and trackable + - Supports rollback (replay inverse of recorded changes) + - Resource-agnostic (works for files, databases, APIs, any resource type) + - Compatible with MCP standard for external tools +- See `specification.md` sections: + - "Tool-Based Resource Modification (Modern Architecture)" + - "Unified Resource Abstraction Layer" + - "MCP Integration Architecture" + --- ## Implementation Roadmap @@ -312,43 +334,87 @@ The following work from the previous implementation has been completed and will | Milestone | Target Date | Description | |-----------|-------------|-------------| | **M0: Foundation** | Day 0 (Current) | Existing LangGraph infrastructure preserved | -| **M1: Minimal Plan Lifecycle** | +3 days | Basic Action → Strategize → Execute → Apply working | -| **M2: Projects & Resources** | +5 days | Project/Resource CLI commands, local filesystem sandbox | -| **M3: Actors & Skills** | +8 days | YAML actor loading, skill execution | -| **M4: Decision Tree** | +12 days | Decision recording during Strategize, basic correction | -| **M5: Multi-Project & Subplans** | +18 days | Subplan spawning, parallel execution | -| **M6: Server Mode** | +25 days | `agents serve` with remote project support | +| **M1: Minimal Plan Lifecycle** | +7 days | Basic Action -> Strategize -> Execute -> Apply working for source code | +| **M2: Projects & Resources** | +10 days | Project/Resource CLI commands, local filesystem sandbox | +| **M3: Actors & Skills** | +14 days | YAML actor loading, skill execution, multi-file generation | +| **M4: Decision Tree** | +21 days | Decision recording during Strategize, basic correction | +| **M5: Multi-Project & Subplans** | +25 days | Subplan spawning, parallel execution | +| **M6: Server Mode** | +30 days | `agents serve` with remote project support | | **M7: Full Feature Set** | +35 days | All spec features complete | +### Critical Path to 7-Day MVP (Source Code Only) + +**WEEK 1 GOAL**: A minimally usable application that can: +1. Create an action from CLI +2. Use the action on a source code project +3. Execute with sandbox isolation +4. Generate multi-file changes +5. Apply changes after review + +``` +CRITICAL PATH (Sequential): +Day 1: A5 Plan/Action Persistence (Luis) +Day 2: B1-B2 Project Model & CLI (Hamza) +Day 3: B3 Git Worktree Sandbox (Luis + Hamza) +Day 4: C2-C3 Actor Compilation & Skill Execution (Aditya) +Day 5: C3.6-C3.7 Built-in Skills & MCP Adapter (Luis + Aditya) +Day 6: C4 Tool-Based Change Tracking (Luis) +Day 7: C5 Plan-Actor Integration (Aditya + Luis) +Day 8: End-to-end Integration & Testing (All) +``` + ### Parallel Workstreams -The following workstreams can be worked on independently: - ``` -WORKSTREAM A: Plan Lifecycle (1 developer) -├── Plan model & state machine -├── Phase transitions -├── CLI commands (plan create, use, execute, apply) -└── Plan persistence +WORKSTREAM A: Plan Lifecycle & Persistence [Luis - Lead Architect] +├── Plan/Action database persistence +├── Phase transitions with database +├── Plan state machine completion +└── CLI integration with persistence -WORKSTREAM B: Projects & Resources (1 developer) +WORKSTREAM B: Projects & Resources [Hamza - RDF Expert] ├── Project model & CLI -├── Resource model & sandbox strategies +├── Resource model ├── Git worktree sandbox -├── Filesystem sandbox -└── Project persistence +└── Filesystem sandbox -WORKSTREAM C: Actors & Skills (1 developer) -├── Actor YAML parsing (v2 format compatibility) -├── Actor registry (existing work) +WORKSTREAM C: Actors & Skills [Aditya - Domain Expert] +├── Actor YAML schema formalization +├── Hierarchical actor configurations ├── Skill execution framework -├── Built-in provider actors -└── Actor-to-LangGraph graph compilation +├── Built-in resource skills (file ops, dir ops, search, git) +├── MCP skill adapter for external servers +├── Actor-to-LangGraph compilation +└── Built-in provider actors -MERGE POINT: After M3, workstreams must coordinate on: -- Plan→Actor binding (which actor handles strategize/execute) -- Resource→Context flow (how resources feed into actors) -- Skill→Tool mapping (how skills become LangGraph tools) +WORKSTREAM D: Tool-Based Change Tracking [Luis + Rui] +├── ChangeSet model enhancement +├── Skill invocation tracking +├── Tool call routing (OpenAI/Anthropic/LangChain) +├── Validation pipeline +└── Diff review artifacts + +WORKSTREAM E: Quality & Infrastructure [Brent - Detail Oriented] +├── Code review all PRs +├── Linting enforcement +├── Type checking compliance +├── Test coverage monitoring +└── Documentation writing & review + +MERGE POINT 1: After Day 7 (M1) +- Plan->Actor binding verified +- Resource->Context flow working +- Skill->Tool mapping complete + +MERGE POINT 2: After Day 14 (M3) +- Full plan lifecycle tested +- Actor compilation working +- Multi-file generation proven + +MERGE POINT 3: After Day 30 (M6) +- Server mode operational +- Decision tree correction working +- Large project handling verified ``` --- @@ -442,9 +508,9 @@ Execute all required tests through the appropriate `nox` sessions—never call ` - [X] LangChain mock provider (FakeListLLM) - [X] Core LangGraph Workflows - - [X] PlanGenerationGraph (load_context → analyze_requirements → generate_plan → validate) + - [X] PlanGenerationGraph (load_context -> analyze_requirements -> generate_plan -> validate) - [X] ContextAnalysisAgent (5-node workflow for context analysis) - - [X] AutoDebugGraph (analyze_error → generate_fix → validate_fix → apply_fix) + - [X] AutoDebugGraph (analyze_error -> generate_fix -> validate_fix -> apply_fix) - [X] Memory service with EntityMemory - [X] CLI streaming integration @@ -463,9 +529,11 @@ Execute all required tests through the appropriate `nox` sessions—never call ` --- -### Section 3: Plan Lifecycle [WORKSTREAM A - 1 Developer] +### Section 3: Plan Lifecycle [WORKSTREAM A - Luis Lead] -**Target: Milestone M1 (+3 days)** +**Target: Milestone M1 (+7 days)** + +**WEEK 1 - CRITICAL PATH** - [X] **Stage A1: Plan Data Model** (Day 1) - COMPLETED 2026-02-05 - [X] Code: Create Plan domain model @@ -482,6 +550,20 @@ Execute all required tests through the appropriate `nox` sessions—never call ` - [X] Add argument parsing for action parameters (`--arg name:type:required|optional:description`) - [X] Location: `src/cleveragents/domain/models/core/action.py` - [X] Tests: Behave scenarios for action model validation (22 scenarios in `features/action_model.feature`) + - [ ] **A2.1** [Luis] Extend Action model with additional fields (follow-up): + - [ ] Field `estimation_actor: str | None` - optional actor for cost/risk estimation + - [ ] Field `review_actor: str | None` - optional actor for code review + - [ ] Field `safety_profile: SafetyProfile | None` - safety constraints + - [ ] **A2.2** [Luis] Define `SafetyProfile` model: + - [ ] Field `allowed_skill_categories: list[str] | None` - whitelist of skill types + - [ ] Field `require_checkpoints: bool` - require checkpointable skills + - [ ] Field `require_sandbox: bool` - require sandbox for all resources + - [ ] Field `require_human_approval: bool` - require approval at Apply + - [ ] Field `max_cost_usd: float | None` - budget cap + - [ ] Field `max_retries: int` - maximum retry attempts + - [ ] **A2.3** [Rui] Write tests for extended action model: + - [ ] Scenario: Action with estimation_actor validates correctly + - [ ] Scenario: Safety profile enforced during execution - [X] **Stage A3: Plan State Machine** (Day 1-2) - COMPLETED 2026-02-05 - [X] Code: Implement plan lifecycle state machine @@ -510,86 +592,564 @@ Execute all required tests through the appropriate `nox` sessions—never call ` - [X] Location: `src/cleveragents/cli/commands/action.py`, `src/cleveragents/cli/commands/plan.py` - [X] Tests: Behave tests for action CLI (15 scenarios in `features/action_cli.feature`) - [ ] Tests: Behave tests for plan lifecycle CLI commands (pending) + - **[Rui]** Write 20 Behave scenarios in `features/plan_lifecycle_cli.feature` covering: + - [ ] `agents plan use` with valid action and project + - [ ] `agents plan use` with missing project error + - [ ] `agents plan use` with invalid action error + - [ ] `agents plan use` with argument validation + - [ ] `agents plan execute` on strategize-complete plan + - [ ] `agents plan execute` on non-strategize plan (error case) + - [ ] `agents plan lifecycle-apply` on execute-complete plan + - [ ] `agents plan lifecycle-apply` on non-execute plan (error case) + - [ ] `agents plan status` output format verification + - [ ] `agents plan lifecycle-list` filtering by phase + - [ ] `agents plan lifecycle-list` filtering by state + - [ ] `agents plan cancel` on active plan + - [ ] `agents plan cancel` on already-applied plan (error case) - [ ] Tests: Robot integration tests for CLI commands (pending) + - **[Rui]** Write Robot test suite `robot/plan_lifecycle_cli.robot` for end-to-end CLI testing -- [ ] **Stage A5: Plan Persistence** (Day 3) +- [ ] **Stage A5: Plan Persistence** (Day 1-2) **[Jeff + Luis - Critical Path]** - [ ] Code: Plan database schema and repository - - [ ] Alembic migration for plans table - - [ ] Alembic migration for actions table - - [ ] PlanRepository with methods - - [ ] ActionRepository - - [ ] Location: `alembic/versions/`, `src/cleveragents/infrastructure/database/` + - [ ] **A5.1** [Jeff] Create Alembic migration for `lifecycle_plans` table in `alembic/versions/xxx_add_lifecycle_plans.py`: + - [ ] **A5.1a** Create migration file with `revision` and `down_revision` links + - [ ] **A5.1b** Define `lifecycle_plans` table schema: + - [ ] Column `plan_id` TEXT PRIMARY KEY (ULID format) + - [ ] Column `parent_plan_id` TEXT NULLABLE FK references lifecycle_plans(plan_id) + - [ ] Column `root_plan_id` TEXT NULLABLE FK references lifecycle_plans(plan_id) + - [ ] Column `action_id` TEXT NOT NULL FK references actions(action_id) + - [ ] Column `phase` TEXT NOT NULL CHECK(phase IN ('ACTION','STRATEGIZE','EXECUTE','APPLY','APPLIED')) + - [ ] Column `state` TEXT NOT NULL (available/draft/archived for Action phase; queued/processing/errored/complete/cancelled for others) + - [ ] Column `attempt` INTEGER NOT NULL DEFAULT 1 + - [ ] Column `automation_level` TEXT NOT NULL DEFAULT 'manual' CHECK(automation_level IN ('manual','review_before_apply','full_automation')) + - [ ] Column `project_ids` TEXT NOT NULL (JSON array of project ULIDs) + - [ ] Column `arguments` TEXT NULLABLE (JSON object of arg name->value) + - [ ] Column `strategy_context` TEXT NULLABLE (JSON blob for Strategize output) + - [ ] Column `execution_log` TEXT NULLABLE (JSON array of execution events) + - [ ] Column `changeset_id` TEXT NULLABLE FK references changesets(changeset_id) + - [ ] Column `sandbox_refs` TEXT NULLABLE (JSON object mapping resource_id->sandbox_path) + - [ ] Column `created_at` TEXT NOT NULL (ISO8601 timestamp) + - [ ] Column `updated_at` TEXT NOT NULL (ISO8601 timestamp) + - [ ] Column `completed_at` TEXT NULLABLE (ISO8601 timestamp) + - [ ] Column `created_by` TEXT NULLABLE (user identifier) + - [ ] **A5.1c** Create indices for common queries: + - [ ] Index `ix_lifecycle_plans_phase` on `phase` + - [ ] Index `ix_lifecycle_plans_state` on `state` + - [ ] Index `ix_lifecycle_plans_parent` on `parent_plan_id` + - [ ] Index `ix_lifecycle_plans_root` on `root_plan_id` + - [ ] Index `ix_lifecycle_plans_created` on `created_at` + - [ ] Index `ix_lifecycle_plans_action` on `action_id` + - [ ] **A5.1d** Define foreign key ON DELETE behaviors: + - [ ] parent_plan_id: ON DELETE SET NULL (orphan subplans) + - [ ] action_id: ON DELETE RESTRICT (can't delete action with plans) + - [ ] **A5.1e** Write `downgrade()` function to drop table + - [ ] **A5.2** [Jeff] Create Alembic migration for `actions` table in `alembic/versions/xxx_add_actions.py`: + - [ ] **A5.2a** Create migration file linked to lifecycle_plans migration + - [ ] **A5.2b** Define `actions` table schema: + - [ ] Column `action_id` TEXT PRIMARY KEY (ULID format) + - [ ] Column `name` TEXT NOT NULL (namespaced format: namespace/name) + - [ ] Column `namespace` TEXT NOT NULL (extracted from name for indexing) + - [ ] Column `description` TEXT NULLABLE + - [ ] Column `definition_of_done` TEXT NOT NULL + - [ ] Column `strategy_actor` TEXT NOT NULL (namespaced actor reference) + - [ ] Column `execution_actor` TEXT NOT NULL (namespaced actor reference) + - [ ] Column `estimation_actor` TEXT NULLABLE (optional cost estimator) + - [ ] Column `review_actor` TEXT NULLABLE (optional code reviewer) + - [ ] Column `inputs_schema` TEXT NOT NULL DEFAULT '[]' (JSON array of ActionArgument) + - [ ] Column `state` TEXT NOT NULL DEFAULT 'draft' CHECK(state IN ('available','draft','archived')) + - [ ] Column `reusable` BOOLEAN NOT NULL DEFAULT TRUE + - [ ] Column `read_only` BOOLEAN NOT NULL DEFAULT FALSE + - [ ] Column `safety_profile` TEXT NULLABLE (JSON object for SafetyProfile) + - [ ] Column `created_at` TEXT NOT NULL + - [ ] Column `updated_at` TEXT NOT NULL + - [ ] **A5.2c** Create indices: + - [ ] UNIQUE index on `name` + - [ ] Index `ix_actions_namespace` on `namespace` + - [ ] Index `ix_actions_state` on `state` + - [ ] **A5.2d** Write `downgrade()` function + - [ ] **A5.3** [Luis] Create `LifecyclePlanModel` SQLAlchemy model in `src/cleveragents/infrastructure/database/models.py`: + - [ ] **A5.3a** Define class `LifecyclePlanModel(Base)` with `__tablename__ = 'lifecycle_plans'` + - [ ] **A5.3b** Define all columns matching migration schema with proper SQLAlchemy types + - [ ] **A5.3c** Define relationships: + - [ ] `parent_plan: relationship('LifecyclePlanModel', remote_side=[plan_id])` + - [ ] `children: relationship('LifecyclePlanModel', back_populates='parent_plan')` + - [ ] `action: relationship('ActionModel')` + - [ ] **A5.3d** Implement `to_domain() -> Plan` method: + - [ ] Convert all TEXT fields to appropriate Python types + - [ ] Parse JSON fields (project_ids, arguments, strategy_context, execution_log, sandbox_refs) + - [ ] Convert timestamps to datetime objects + - [ ] Return fully hydrated Plan domain model + - [ ] **A5.3e** Implement classmethod `from_domain(plan: Plan) -> LifecyclePlanModel`: + - [ ] Serialize all fields to database-compatible formats + - [ ] Serialize JSON fields with json.dumps() + - [ ] Convert datetime to ISO8601 strings + - [ ] **A5.4** [Luis] Create `ActionModel` SQLAlchemy model in `src/cleveragents/infrastructure/database/models.py`: + - [ ] **A5.4a** Define class `ActionModel(Base)` with `__tablename__ = 'actions'` + - [ ] **A5.4b** Define all columns matching migration schema + - [ ] **A5.4c** Implement `to_domain() -> Action` method + - [ ] **A5.4d** Implement classmethod `from_domain(action: Action) -> ActionModel` + - [ ] **A5.5** [Jeff] Implement `LifecyclePlanRepository` in `src/cleveragents/infrastructure/database/repositories.py`: + - [ ] **A5.5a** Define class with `__init__(self, session_factory: SessionFactory)` + - [ ] **A5.5b** Implement `create(plan: Plan) -> Plan`: + - [ ] Convert domain model to SQLAlchemy model + - [ ] Use session.add() and session.commit() + - [ ] Handle IntegrityError for duplicate IDs + - [ ] Return created plan with database-assigned values + - [ ] **A5.5c** Implement `get_by_id(plan_id: str) -> Plan | None`: + - [ ] Query by primary key + - [ ] Return None if not found + - [ ] Convert to domain model if found + - [ ] **A5.5d** Implement `get_by_phase(phase: PlanPhase) -> list[Plan]`: + - [ ] Filter by phase column + - [ ] Order by created_at DESC + - [ ] Convert all results to domain models + - [ ] **A5.5e** Implement `get_by_state(state: ProcessingState) -> list[Plan]` + - [ ] **A5.5f** Implement `get_children(parent_plan_id: str) -> list[Plan]`: + - [ ] Filter by parent_plan_id + - [ ] Used for listing subplans + - [ ] **A5.5g** Implement `get_tree(root_plan_id: str) -> list[Plan]`: + - [ ] Recursive CTE query to get all descendants + - [ ] Or iterative approach using get_children + - [ ] Return in tree order (parent before children) + - [ ] **A5.5h** Implement `update(plan: Plan) -> Plan`: + - [ ] Fetch existing record + - [ ] Update all changed fields + - [ ] Update `updated_at` timestamp + - [ ] Commit and return updated plan + - [ ] **A5.5i** Implement `list_all(limit: int = 100, offset: int = 0) -> list[Plan]`: + - [ ] Paginated query with limit/offset + - [ ] Order by created_at DESC + - [ ] **A5.5j** Implement `count() -> int`: + - [ ] SELECT COUNT(*) query + - [ ] **A5.5k** Add `@retry_database` decorator from `src/cleveragents/core/retry_patterns.py`: + - [ ] 3 retries with exponential backoff + - [ ] Only retry on OperationalError (database locked, connection timeout) + - [ ] **A5.6** [Luis] Implement `ActionRepository` in `src/cleveragents/infrastructure/database/repositories.py`: + - [ ] **A5.6a** Define class with session factory injection + - [ ] **A5.6b** Implement `create(action: Action) -> Action` + - [ ] **A5.6c** Implement `get_by_id(action_id: str) -> Action | None` + - [ ] **A5.6d** Implement `get_by_name(name: str) -> Action | None`: + - [ ] Query by namespaced name (exact match) + - [ ] Used for `agents action show local/my-action` + - [ ] **A5.6e** Implement `get_by_namespace(namespace: str) -> list[Action]`: + - [ ] Filter by namespace column + - [ ] Used for listing actions in a namespace + - [ ] **A5.6f** Implement `get_by_state(state: ActionState) -> list[Action]` + - [ ] **A5.6g** Implement `update(action: Action) -> Action` + - [ ] **A5.6h** Implement `list_available() -> list[Action]`: + - [ ] Filter by state='available' + - [ ] Used for `agents action list` + - [ ] **A5.6i** Implement `delete(action_id: str) -> bool`: + - [ ] Check for plans using this action + - [ ] Raise error if plans exist (referential integrity) + - [ ] Delete and return True if successful + - [ ] **A5.6j** Add retry decorator + - [ ] **A5.7** [Jeff] Update `PlanLifecycleService` to use repositories: + - [ ] **A5.7a** Modify `__init__()` to accept repository dependencies: + - [ ] `plan_repository: LifecyclePlanRepository` + - [ ] `action_repository: ActionRepository` + - [ ] Remove `self._plans: dict` and `self._actions: dict` + - [ ] **A5.7b** Update `create_action()` to use ActionRepository: + - [ ] Call `action_repository.create(action)` + - [ ] Handle IntegrityError for duplicate names + - [ ] **A5.7c** Update `get_action()` to use repository + - [ ] **A5.7d** Update `list_actions()` to use repository + - [ ] **A5.7e** Update `use_action()` to use both repositories: + - [ ] Fetch action from ActionRepository + - [ ] Create plan in LifecyclePlanRepository + - [ ] Return plan with database ID + - [ ] **A5.7f** Update all plan state transition methods: + - [ ] `execute_plan()`, `apply_plan()`, `start_*()`, `complete_*()`, `fail_*()` + - [ ] Fetch plan -> modify -> update via repository + - [ ] **A5.7g** Update `cancel_plan()` to use repository + - [ ] **A5.7h** Add transaction handling for multi-step operations: + - [ ] Use UnitOfWork pattern for atomic operations + - [ ] Rollback on any failure + - [ ] **A5.8** [Luis] Update DI container in `src/cleveragents/application/container.py`: + - [ ] **A5.8a** Add `LifecyclePlanRepository` provider + - [ ] **A5.8b** Add `ActionRepository` provider + - [ ] **A5.8c** Update `PlanLifecycleService` provider to inject repositories - [ ] Tests: Integration tests for plan/action persistence + - [ ] **A5.9** [Rui] Write Behave scenarios in `features/plan_persistence.feature`: + - [ ] **A5.9a** Scenario: Create plan stores record in database + - [ ] Given an action exists in database + - [ ] When I create a plan using that action + - [ ] Then the plan exists in the lifecycle_plans table + - [ ] And the plan_id is a valid ULID + - [ ] **A5.9b** Scenario: Update plan phase persists correctly + - [ ] Given a plan exists in STRATEGIZE phase + - [ ] When I transition it to EXECUTE phase + - [ ] Then the database record shows phase='EXECUTE' + - [ ] **A5.9c** Scenario: Query plans by phase returns filtered results + - [ ] **A5.9d** Scenario: Query plans by state returns filtered results + - [ ] **A5.9e** Scenario: Get plan tree returns parent and all children + - [ ] **A5.9f** Scenario: Concurrent plan creation is thread-safe + - [ ] Given 10 threads creating plans simultaneously + - [ ] Then all 10 plans are created with unique IDs + - [ ] **A5.10** [Rui] Write Behave scenarios in `features/action_persistence.feature`: + - [ ] **A5.10a** Scenario: Create action stores record in database + - [ ] **A5.10b** Scenario: Get action by namespaced name works + - [ ] **A5.10c** Scenario: List available excludes archived actions + - [ ] **A5.10d** Scenario: Update action state persists + - [ ] **A5.10e** Scenario: Delete action with existing plans fails + - [ ] **A5.11** [Rui] Write Robot test `robot/plan_persistence_e2e.robot`: + - [ ] **A5.11a** Test: Full lifecycle persists all transitions + - [ ] Create action via CLI + - [ ] Use action on project via CLI + - [ ] Execute plan via CLI + - [ ] Apply plan via CLI + - [ ] Verify all state transitions in database + - [ ] **A5.11b** Test: Restart persistence + - [ ] Create plan + - [ ] Kill process (simulate crash) + - [ ] Restart application + - [ ] Verify plan still exists and is recoverable + - [ ] **A5.11c** Test: Concurrent CLI access + - [ ] Two CLI processes accessing same plan + - [ ] Verify no data corruption + +- [ ] **Stage A6: Automation Levels Foundation** (Day 4-5) **[Luis]** + - [ ] Code: Implement basic automation level support + - [ ] **A6.1** [Luis] Add `AutomationLevel` enum to `src/cleveragents/domain/models/core/plan.py`: + - [ ] Value `MANUAL` - user triggers each phase transition + - [ ] Value `REVIEW_BEFORE_APPLY` - auto strategize+execute, pause before apply + - [ ] Value `FULL_AUTOMATION` - all phases automatic + - [ ] **A6.2** [Luis] Add automation level configuration to `src/cleveragents/config/settings.py`: + - [ ] Add `default_automation_level: AutomationLevel` setting + - [ ] Add `CLEVERAGENTS_AUTOMATION_LEVEL` environment variable + - [ ] Implement hierarchy: plan-level > session-level > global-level + - [ ] **A6.3** [Luis] Update `PlanLifecycleService` to respect automation levels: + - [ ] Add `automation_level` parameter to `use_action()` method + - [ ] If automation allows, automatically call `execute_plan()` after strategize completes + - [ ] If full automation, automatically call `apply_plan()` after execute completes + - [ ] Add pause/resume capability for review-before-apply mode + - [ ] **A6.4** [Luis] Update CLI commands to support automation levels: + - [ ] Add `--automation-level` flag to `agents plan use` command + - [ ] Add `agents config set automation-level ` command + - [ ] Add `agents plan set-automation-level ` command: + - [ ] Can change automation level for existing plan + - [ ] Only affects future phase transitions + - [ ] Subplans created after change use new level + - [ ] Add `agents session set automation-level ` command: + - [ ] Set session-level automation (overrides global) + - [ ] Persists for current session only + - [ ] Tests: Automation level tests + - [ ] **A6.5** [Rui] Write Behave scenarios in `features/automation_levels.feature`: + - [ ] Scenario: Manual mode requires explicit execute command + - [ ] Scenario: Review-before-apply auto-executes but pauses at apply + - [ ] Scenario: Full automation runs all phases without user input + - [ ] Scenario: Plan-level automation overrides global setting + - [ ] Scenario: Change automation level mid-plan works correctly **M1 SUCCESS CRITERIA**: -- [ ] Can create an action via CLI +- [ ] Can create an action via CLI and it persists to database - [ ] Can use an action on a project to create a plan -- [ ] Plan transitions through phases (even if execution is stubbed) -- [ ] Plan state persists to database +- [ ] Plan transitions through phases with database persistence +- [ ] Automation levels work (at least manual mode fully functional) --- -### Section 4: Projects & Resources [WORKSTREAM B - 1 Developer] +### Section 4: Projects & Resources [WORKSTREAM B - Hamza Lead] -**Target: Milestone M2 (+5 days)** +**Target: Milestone M2 (+10 days)** -- [ ] **Stage B1: Project Data Model** (Day 1) +**WEEK 1-2 - PARALLEL WITH PLAN LIFECYCLE** + +- [ ] **Stage B1: Project Data Model** (Day 2-3) **[Hamza - Python Expert, RDF Background]** - [ ] Code: Create Project domain model - - [ ] Define `Project` Pydantic model (project_id ULID, name, namespace, tags, is_remote) - - [ ] Define `Resource` Pydantic model (resource_id, name, type, location, is_remote, sandbox_strategy, read_only, metadata) - - [ ] Define `ResourceType` enum (git_repository, database, filesystem, api_endpoint, etc.) - - [ ] Define `SandboxStrategy` enum (git_worktree, copy_on_write, overlay, transaction_rollback, none) - - [ ] Location: `src/cleveragents/domain/models/core/project.py`, `src/cleveragents/domain/models/core/resource.py` + - [ ] **B1.1** [Hamza] Define `Project` Pydantic model in `src/cleveragents/domain/models/core/project.py`: + - [ ] Field `project_id: str` - ULID primary identifier + - [ ] Field `name: str` - human-readable name + - [ ] Field `namespace: str` - scoping namespace (local/, user/, org/) + - [ ] Field `description: str | None` - optional description + - [ ] Field `tags: list[str]` - categorization tags + - [ ] Field `is_remote: bool` - derived from resources (True if all resources remotely accessible) + - [ ] Field `resources: list[Resource]` - associated resources + - [ ] Field `validation_config: ValidationConfig | None` - test/lint commands + - [ ] Field `context_config: ContextConfig | None` - ignore patterns, chunking policy + - [ ] Field `created_at: datetime` - creation timestamp + - [ ] Field `updated_at: datetime` - last modification timestamp + - [ ] Add `@validator` for namespace format validation + - [ ] Add `namespaced_name` property returning `namespace/name` format + - [ ] **B1.2** [Hamza] Define `Resource` Pydantic model in `src/cleveragents/domain/models/core/resource.py`: + - [ ] Field `resource_id: str` - ULID primary identifier + - [ ] Field `name: str` - human-readable resource name + - [ ] Field `type: ResourceType` - enum of resource types + - [ ] Field `location: str` - path, URL, or connection string + - [ ] Field `is_remote: bool` - whether resource is network-accessible + - [ ] Field `sandbox_strategy: SandboxStrategy` - how to sandbox this resource + - [ ] Field `read_only: bool` - whether writes are allowed (default False) + - [ ] Field `metadata: dict[str, Any]` - additional type-specific metadata + - [ ] Field `created_at: datetime` - creation timestamp + - [ ] **B1.3** [Hamza] Define `ResourceType` enum: + - [ ] Value `GIT_REPOSITORY` - git repo (local or remote) + - [ ] Value `FILESYSTEM` - local directory or files + - [ ] Value `DATABASE` - SQL/NoSQL database endpoint + - [ ] Value `API_ENDPOINT` - REST/GraphQL API + - [ ] Value `DOCUMENT_CORPUS` - collection of documents (PDFs, markdown) + - [ ] Value `CLOUD_INFRASTRUCTURE` - cloud resources (AWS, GCP, etc.) + - [ ] **B1.4** [Hamza] Define `SandboxStrategy` enum: + - [ ] Value `GIT_WORKTREE` - use git worktree for isolation + - [ ] Value `COPY_ON_WRITE` - copy files to temp directory + - [ ] Value `OVERLAY` - use overlay filesystem (Linux only) + - [ ] Value `TRANSACTION_ROLLBACK` - database transaction-based + - [ ] Value `NONE` - no sandboxing (resource cannot be sandboxed) + - [ ] **B1.5** [Hamza] Define `ValidationConfig` Pydantic model: + - [ ] Field `test_command: str | None` - command to run tests + - [ ] Field `lint_command: str | None` - command to run linter + - [ ] Field `type_check_command: str | None` - command for type checking + - [ ] Field `build_command: str | None` - command to build project + - [ ] Field `custom_commands: dict[str, str]` - additional validation commands + - [ ] **B1.6** [Hamza] Define `ContextConfig` Pydantic model: + - [ ] Field `ignore_patterns: list[str]` - gitignore-style patterns to exclude + - [ ] Field `include_patterns: list[str] | None` - patterns to explicitly include + - [ ] Field `max_file_size: int` - maximum file size to index (bytes) + - [ ] Field `indexing_strategy: str` - how to index (full-text, embeddings, etc.) + - [ ] Field `chunking_policy: str` - how to chunk large files - [ ] Tests: Behave scenarios for model validation + - [ ] **B1.7** [Rui] Write 25 Behave scenarios in `features/project_model.feature`: + - [ ] Scenario: Create valid project with all fields + - [ ] Scenario: Project namespace validation accepts valid formats + - [ ] Scenario: Project namespace validation rejects invalid formats + - [ ] Scenario: Project is_remote correctly derived from resources + - [ ] Scenario: Resource with each ResourceType value validates correctly + - [ ] Scenario: Resource with each SandboxStrategy validates correctly + - [ ] Scenario: Resource read_only flag enforced on model + - [ ] Scenario: ValidationConfig with all commands validates + - [ ] Scenario: ContextConfig ignore patterns accept glob syntax + - [ ] Scenario: Project JSON serialization round-trips correctly -- [ ] **Stage B2: Project CLI Commands** (Day 2) +- [ ] **Stage B2: Project CLI Commands** (Day 3-4) **[Hamza]** - [ ] Code: Implement project CLI - - [ ] `agents project create --name [--tag ...]` - - [ ] `agents project add-resource --project --name --type --location --sandbox-strategy [--read-only]` - - [ ] `agents project remove-resource --project --name ` - - [ ] `agents project list` - - [ ] `agents project show ` - - [ ] `agents project set-validation --project --resource --test-command [--lint-command ] [--type-check-command ]` - - [ ] Location: `src/cleveragents/cli/commands/project.py` + - [ ] **B2.1** [Hamza] Create `src/cleveragents/cli/commands/project.py` with project commands: + - [ ] Implement `agents project create --name [--description ] [--tag ...]`: + - [ ] Parse namespace from name (e.g., "local/my-project") + - [ ] Validate name format and uniqueness + - [ ] Create Project with ULID + - [ ] Persist to database (or in-memory initially) + - [ ] Output created project ID and summary + - [ ] Implement `agents project add-resource --project --name --type --location --sandbox-strategy [--read-only] [--metadata key=value ...]`: + - [ ] Validate project exists + - [ ] Validate resource type is known + - [ ] Validate sandbox strategy is compatible with resource type + - [ ] Create Resource with ULID + - [ ] Add to project's resources list + - [ ] Derive project.is_remote from all resources + - [ ] Persist changes + - [ ] Implement `agents project remove-resource --project --name `: + - [ ] Validate project and resource exist + - [ ] Remove resource from project + - [ ] Re-derive is_remote + - [ ] Persist changes + - [ ] Implement `agents project list [--namespace ] [--tag ]`: + - [ ] Query projects with optional filters + - [ ] Display table with ID, name, resource count, is_remote + - [ ] Implement `agents project show `: + - [ ] Fetch project by namespaced name + - [ ] Display full details including all resources + - [ ] Show validation config if set + - [ ] Implement `agents project set-validation --project [--resource ] --test-command [--lint-command ] [--type-check-command ] [--build-command ]`: + - [ ] If --resource specified, set per-resource validation + - [ ] Otherwise set project-level validation + - [ ] Persist configuration + - [ ] Implement `agents project delete [--force]`: + - [ ] Check for active plans using this project + - [ ] If active plans exist and --force not specified, error + - [ ] Delete project and associated resources + - [ ] **B2.2** [Hamza] Register project commands in `src/cleveragents/cli/main.py`: + - [ ] Import project command group + - [ ] Add to main CLI app - [ ] Tests: Behave + Robot for all project CLI commands + - [ ] **B2.3** [Rui] Write 20 Behave scenarios in `features/project_cli.feature`: + - [ ] Scenario: Create project with valid name succeeds + - [ ] Scenario: Create project with duplicate name fails + - [ ] Scenario: Add git repository resource to project + - [ ] Scenario: Add filesystem resource to project + - [ ] Scenario: Add database resource to project (read-only) + - [ ] Scenario: Remove resource from project succeeds + - [ ] Scenario: Remove non-existent resource fails gracefully + - [ ] Scenario: List projects shows all projects + - [ ] Scenario: List projects with namespace filter works + - [ ] Scenario: Show project displays full details + - [ ] Scenario: Set validation commands persists correctly + - [ ] Scenario: Delete project with active plans blocked without --force + - [ ] **B2.4** [Rui] Write Robot integration test `robot/project_cli_integration.robot`: + - [ ] Test full project lifecycle: create -> add resources -> show -> delete + - [ ] Test project with multiple resources of different types -- [ ] **Stage B3: Sandbox Framework** (Day 3-4) +- [ ] **Stage B3: Sandbox Framework** (Day 4-6) **[Luis + Hamza - Architectural]** - [ ] Code: Implement sandbox abstraction - - [ ] Define `Sandbox` protocol/interface - - [ ] Implement `GitWorktreeSandbox` for git repositories - - [ ] Implement `FilesystemSandbox` (copy-on-write) for local files - - [ ] Implement `NoSandbox` for non-sandboxable resources - - [ ] Add sandbox lifecycle (create, commit, rollback, cleanup) - - [ ] Implement isolation mechanisms: - - [ ] Each plan gets its own sandbox containing only resources it edits - - [ ] Parallel plans cannot see each other's intermediate states - - [ ] Lazy sandboxing - resources sandboxed only when accessed - - [ ] Implement merge strategies: - - [ ] Git-style three-way merge for code resources - - [ ] Sequential application for databases - - [ ] Smart JSON/YAML merge for config files - - [ ] Parent plan merge resolution for conflicts - - [ ] Location: `src/cleveragents/infrastructure/sandbox/` + - [ ] **B3.1** [Luis] Define `Sandbox` protocol in `src/cleveragents/infrastructure/sandbox/protocol.py`: + - [ ] Method `create() -> SandboxContext` - initialize sandbox environment + - [ ] Method `get_path(resource_path: str) -> str` - get sandboxed path for resource + - [ ] Method `commit() -> CommitResult` - finalize sandbox changes + - [ ] Method `rollback() -> None` - discard sandbox changes + - [ ] Method `cleanup() -> None` - remove sandbox artifacts + - [ ] Property `sandbox_id: str` - unique identifier + - [ ] Property `resource: Resource` - resource being sandboxed + - [ ] Property `status: SandboxStatus` - current sandbox state + - [ ] **B3.2** [Luis] Define `SandboxStatus` enum: + - [ ] Value `CREATED` - sandbox initialized + - [ ] Value `ACTIVE` - sandbox in use + - [ ] Value `COMMITTED` - changes applied + - [ ] Value `ROLLED_BACK` - changes discarded + - [ ] Value `CLEANED_UP` - sandbox removed + - [ ] **B3.3** [Hamza] Implement `GitWorktreeSandbox` in `src/cleveragents/infrastructure/sandbox/git_worktree.py`: + - [ ] Constructor: accept Resource with type=GIT_REPOSITORY + - [ ] `create()`: + - [ ] Run `git worktree add -b ` from resource location + - [ ] Store worktree path and branch name + - [ ] Return SandboxContext with worktree path + - [ ] `get_path(resource_path)`: return `/` + - [ ] `commit()`: + - [ ] Run `git add -A` in worktree + - [ ] Run `git commit -m "CleverAgents execution "` if changes exist + - [ ] Return CommitResult with commit hash + - [ ] `rollback()`: + - [ ] Run `git checkout .` to discard changes + - [ ] Run `git clean -fd` to remove untracked files + - [ ] `cleanup()`: + - [ ] Run `git worktree remove --force` + - [ ] Delete the sandbox branch if desired + - [ ] Add error handling for git command failures + - [ ] Add logging for all git operations + - [ ] **B3.4** [Hamza] Implement `FilesystemSandbox` in `src/cleveragents/infrastructure/sandbox/filesystem.py`: + - [ ] Constructor: accept Resource with type=FILESYSTEM + - [ ] `create()`: + - [ ] Create temp directory using `tempfile.mkdtemp(prefix="cleveragents_sandbox_")` + - [ ] Copy resource location contents to temp directory (use shutil.copytree) + - [ ] Store original path and sandbox path + - [ ] Return SandboxContext with sandbox path + - [ ] `get_path(resource_path)`: return `/` + - [ ] `commit()`: + - [ ] Compute diff between sandbox and original + - [ ] Apply changes from sandbox to original (rsync-style) + - [ ] Return CommitResult with changed files list + - [ ] `rollback()`: + - [ ] Simply discard sandbox (changes are not applied until commit) + - [ ] No action needed on original + - [ ] `cleanup()`: + - [ ] Remove temp directory using `shutil.rmtree` + - [ ] **B3.5** [Luis] Implement `NoSandbox` in `src/cleveragents/infrastructure/sandbox/no_sandbox.py`: + - [ ] For resources that cannot be sandboxed (APIs, some cloud resources) + - [ ] `create()`: log warning that resource is not sandboxed + - [ ] `get_path(resource_path)`: return original resource path + - [ ] `commit()`: no-op (changes already applied directly) + - [ ] `rollback()`: log error that rollback not possible + - [ ] `cleanup()`: no-op + - [ ] **B3.6** [Luis] Implement `SandboxFactory` in `src/cleveragents/infrastructure/sandbox/factory.py`: + - [ ] Method `create_sandbox(resource: Resource) -> Sandbox`: + - [ ] Match resource.sandbox_strategy to implementation + - [ ] GIT_WORKTREE -> GitWorktreeSandbox + - [ ] COPY_ON_WRITE -> FilesystemSandbox + - [ ] NONE -> NoSandbox + - [ ] Raise ValueError for unknown strategy + - [ ] **B3.7** [Luis] Implement sandbox lifecycle management: + - [ ] Create `SandboxManager` in `src/cleveragents/infrastructure/sandbox/manager.py`: + - [ ] Track active sandboxes per plan + - [ ] Implement `get_or_create_sandbox(plan_id: str, resource: Resource) -> Sandbox` - lazy creation + - [ ] Implement `commit_all(plan_id: str) -> list[CommitResult]` - commit all plan sandboxes + - [ ] Implement `rollback_all(plan_id: str) -> None` - rollback all plan sandboxes + - [ ] Implement `cleanup_all(plan_id: str) -> None` - cleanup all plan sandboxes + - [ ] Implement `cleanup_abandoned() -> int` - cleanup sandboxes from crashed processes + - [ ] **B3.8** [Luis] Implement merge strategies in `src/cleveragents/infrastructure/sandbox/merge.py`: + - [ ] Define `MergeStrategy` protocol: + - [ ] Method `merge(base: Any, ours: Any, theirs: Any) -> MergeResult` + - [ ] Implement `GitMergeStrategy`: + - [ ] Use `git merge-file` for three-way merge + - [ ] Handle merge conflicts by marking in file + - [ ] Implement `SequentialMergeStrategy`: + - [ ] For non-mergeable resources, apply changes sequentially + - [ ] Implement `JsonMergeStrategy`: + - [ ] Smart JSON object merging - [ ] Tests: Integration tests for each sandbox type + - [ ] **B3.9** [Rui] Write Behave scenarios in `features/sandbox_git_worktree.feature`: + - [ ] Scenario: Create git worktree sandbox from valid git repo + - [ ] Scenario: Modify file in sandbox does not affect original + - [ ] Scenario: Commit sandbox applies changes to branch + - [ ] Scenario: Rollback sandbox discards all changes + - [ ] Scenario: Cleanup removes worktree and branch + - [ ] Scenario: Multiple sandboxes from same repo are isolated + - [ ] **B3.10** [Rui] Write Behave scenarios in `features/sandbox_filesystem.feature`: + - [ ] Scenario: Create filesystem sandbox copies directory + - [ ] Scenario: Modify file in sandbox does not affect original + - [ ] Scenario: Commit sandbox applies changes to original + - [ ] Scenario: Rollback sandbox leaves original unchanged + - [ ] Scenario: Cleanup removes temp directory + - [ ] **B3.11** [Rui] Write Robot integration test `robot/sandbox_integration.robot`: + - [ ] Test: Full sandbox lifecycle with real git repository + - [ ] Test: Sandbox isolation between parallel plans - [ ] Tests: Parallel execution isolation tests + - [ ] **B3.12** [Rui] Write Behave scenarios in `features/sandbox_isolation.feature`: + - [ ] Scenario: Two plans with sandboxes on same resource are isolated + - [ ] Scenario: Plan A cannot see Plan B's intermediate changes - [ ] Tests: Merge conflict resolution tests + - [ ] **B3.13** [Rui] Write Behave scenarios in `features/sandbox_merge.feature`: + - [ ] Scenario: Git merge strategy handles non-conflicting changes + - [ ] Scenario: Git merge strategy marks conflicts appropriately + - [ ] Scenario: Sequential merge applies changes in order -- [ ] **Stage B4: Resource Integration** (Day 4-5) +- [ ] **Stage B4: Resource Integration** (Day 6-7) **[Hamza]** - [ ] Code: Connect resources to plan execution - - [ ] Create `ResourceService` for resource access during execution - - [ ] Implement lazy sandboxing (sandbox on access, not upfront) - - [ ] Add sandbox cleanup on plan completion/failure - - [ ] Location: `src/cleveragents/application/services/resource_service.py` + - [ ] **B4.1** [Hamza] Create `ResourceService` in `src/cleveragents/application/services/resource_service.py`: + - [ ] Inject `SandboxManager` via constructor + - [ ] Method `access_resource(plan_id: str, resource: Resource, mode: str) -> ResourceAccess`: + - [ ] If mode is "write", ensure sandbox exists via SandboxManager + - [ ] If mode is "read", may use sandbox or original depending on config + - [ ] Return ResourceAccess object with sandboxed paths + - [ ] Track accessed resources for the plan + - [ ] Method `get_accessed_resources(plan_id: str) -> list[Resource]`: + - [ ] Return list of all resources accessed by this plan + - [ ] Method `commit_plan_resources(plan_id: str) -> list[CommitResult]`: + - [ ] Call SandboxManager.commit_all() + - [ ] Return commit results + - [ ] Method `rollback_plan_resources(plan_id: str) -> None`: + - [ ] Call SandboxManager.rollback_all() + - [ ] Method `cleanup_plan_resources(plan_id: str) -> None`: + - [ ] Call SandboxManager.cleanup_all() + - [ ] **B4.2** [Hamza] Implement lazy sandboxing: + - [ ] ResourceService only creates sandbox on first write access + - [ ] Read-only access may use original resource directly + - [ ] Configuration option to force sandbox even for reads + - [ ] **B4.3** [Hamza] Add sandbox cleanup hooks: + - [ ] On plan completion (success): commit then cleanup + - [ ] On plan failure: rollback then cleanup (or preserve for debugging based on config) + - [ ] On application exit: cleanup all active sandboxes + - [ ] On application startup: cleanup abandoned sandboxes from previous crash - [ ] Tests: End-to-end tests for plan execution with sandboxed resources + - [ ] **B4.4** [Rui] Write Behave scenarios in `features/resource_service.feature`: + - [ ] Scenario: First write access creates sandbox + - [ ] Scenario: Read access without write uses original + - [ ] Scenario: Multiple writes use same sandbox + - [ ] Scenario: Plan completion commits and cleans up sandbox + - [ ] Scenario: Plan failure rolls back sandbox + - [ ] **B4.5** [Rui] Write Robot integration test `robot/resource_service_integration.robot`: + - [ ] Test: Full plan execution with sandboxed git resource -- [ ] **Stage B5: Project Persistence** (Day 5) +- [ ] **Stage B5: Project Persistence** (Day 7-8) **[Hamza]** - [ ] Code: Project/Resource database schema - - [ ] Alembic migration for projects table - - [ ] Alembic migration for resources table - - [ ] Alembic migration for project_resources junction table - - [ ] ProjectRepository, ResourceRepository - - [ ] Location: `alembic/versions/`, `src/cleveragents/infrastructure/database/` + - [ ] **B5.1** [Hamza] Create Alembic migration for `projects` table: + - [ ] Schema: `project_id` (TEXT PK), `name` (TEXT UNIQUE), `namespace` (TEXT), `description` (TEXT nullable), `tags` (JSON array), `is_remote` (BOOLEAN), `validation_config` (JSON nullable), `context_config` (JSON nullable), `created_at` (TEXT), `updated_at` (TEXT) + - [ ] Add indices on `name`, `namespace` + - [ ] **B5.2** [Hamza] Create Alembic migration for `resources` table: + - [ ] Schema: `resource_id` (TEXT PK), `project_id` (TEXT FK), `name` (TEXT), `type` (TEXT), `location` (TEXT), `is_remote` (BOOLEAN), `sandbox_strategy` (TEXT), `read_only` (BOOLEAN), `metadata` (JSON), `created_at` (TEXT) + - [ ] Add foreign key constraint to projects + - [ ] Add unique constraint on (project_id, name) + - [ ] **B5.3** [Hamza] Implement `ProjectRepository` in `src/cleveragents/infrastructure/database/repositories.py`: + - [ ] Standard CRUD methods matching PlanRepository pattern + - [ ] Method `get_with_resources(project_id: str) -> Project | None` - eager load resources + - [ ] **B5.4** [Hamza] Implement `ResourceRepository` in `src/cleveragents/infrastructure/database/repositories.py`: + - [ ] Standard CRUD methods + - [ ] Method `get_by_project(project_id: str) -> list[Resource]` + - [ ] **B5.5** [Hamza] Create database model classes: + - [ ] `ProjectModel(Base)` with `to_domain()` and `from_domain()` + - [ ] `ResourceModel(Base)` with `to_domain()` and `from_domain()` - [ ] Tests: Integration tests for persistence + - [ ] **B5.6** [Rui] Write Behave scenarios in `features/project_persistence.feature`: + - [ ] Scenario: Create project persists to database + - [ ] Scenario: Add resource persists and links to project + - [ ] Scenario: Get project includes all resources + - [ ] Scenario: Delete project cascades to resources **M2 SUCCESS CRITERIA**: - [ ] Can create a project with resources via CLI @@ -600,207 +1160,1104 @@ Execute all required tests through the appropriate `nox` sessions—never call ` --- -### Section 5: Actors & Skills [WORKSTREAM C - 1 Developer] +### Section 5: Actors, Skills & Multi-File Generation [WORKSTREAM C - Aditya Lead] -**Target: Milestone M3 (+8 days)** +**Target: Milestone M3 (+14 days)** -- [ ] **Stage C1: Actor YAML Schema** (Day 1) +**WEEK 2 - CRITICAL FOR MVP** + +- [ ] **Stage C1: Actor YAML Schema Formalization** (Day 5-6) **[Aditya - Domain Expert]** - [ ] Code: Formalize actor YAML schema - - [ ] Document canonical actor YAML format (compatible with existing v2 format) - - [ ] Add skill definition in actor YAML (tool nodes with inline code) - - [ ] Add route definitions for graph-based actors - - [ ] Add context/memory configuration options - - [ ] Location: `src/cleveragents/actor/schema.py` + - [ ] **C1.1** [Aditya] Document canonical actor YAML format in `src/cleveragents/actor/schema.py`: + - [ ] Define `ActorConfigSchema` Pydantic model for v3 format validation + - [ ] Define `ActorType` enum: `LLM`, `TOOL`, `GRAPH` + - [ ] Define `NodeType` enum: `AGENT`, `TOOL`, `CONDITIONAL` + - [ ] Define `ToolDefinition` model for inline skill code + - [ ] Define `RouteDefinition` model for graph edges + - [ ] Define `ContextConfigSchema` for memory/context settings + - [ ] Ensure backwards compatibility with existing v2 format + - [ ] **C1.2** [Aditya] Create comprehensive example actors in `examples/actors/`: + - [ ] `simple_llm_actor.yaml` - Basic LLM wrapper with system prompt + - [ ] `tool_actor.yaml` - Actor with inline Python tool code + - [ ] `graph_actor.yaml` - Multi-node graph with routing + - [ ] `hierarchical_actor.yaml` - Actor referencing other actors + - [ ] `strategy_actor.yaml` - Example strategist for Strategize phase + - [ ] `execution_actor.yaml` - Example executor for Execute phase + - [ ] **C1.3** [Aditya] Add skill/tool definition support in actor YAML: + - [ ] `tools` section with inline Python code + - [ ] `name` field for tool identification + - [ ] `code` field for Python implementation + - [ ] `description` field for LLM to understand tool purpose + - [ ] `parameters` field for typed parameters (JSON Schema) + - [ ] `returns` field for return type documentation + - [ ] **C1.4** [Aditya] Add route definitions for graph-based actors: + - [ ] `routes` section defining graph topology + - [ ] `nodes` list with node definitions + - [ ] `edges` list with source/target/condition + - [ ] `entry_point` specifying start node + - [ ] Support for conditional edges based on state + - [ ] **C1.5** [Aditya] Add context/memory configuration options: + - [ ] `memory_enabled: bool` - whether actor maintains conversation memory + - [ ] `max_history: int` - maximum conversation turns to retain + - [ ] `context_window_fraction: float` - fraction of context for this actor + - [ ] `context_view: str` - role-based view (strategist, executor, reviewer) - [ ] Document: Create `docs/reference/actor_configuration.md` with full schema + - [ ] **C1.6** [Aditya] Write comprehensive actor configuration documentation: + - [ ] Full YAML schema with all fields explained + - [ ] Examples for each actor type + - [ ] Migration guide from v2 format + - [ ] Best practices for actor design -- [ ] **Stage C2: Actor Loading Enhancement** (Day 2-3) - - [ ] Code: Enhance actor loading - - [ ] Parse skill definitions from actor YAML - - [ ] Generate LangGraph tool nodes from skill code - - [ ] Compile actor config into executable LangGraph StateGraph - - [ ] Support actor references (actor can reference other actors) - - [ ] Location: `src/cleveragents/actor/compiler.py` +- [ ] **Stage C2: Actor Loading & Compilation** (Day 6-8) **[Aditya]** + - [ ] Code: Enhance actor loading and compilation to LangGraph + - [ ] **C2.1** [Aditya] Update `src/cleveragents/actor/config.py` to parse v3 actor configs: + - [ ] Parse `tools` section and validate tool definitions + - [ ] Parse `routes` section and validate graph structure + - [ ] Handle actor references (e.g., `actor: local/other-actor`) + - [ ] Validate all referenced actors exist + - [ ] **C2.2** [Aditya] Create `src/cleveragents/actor/compiler.py` for LangGraph compilation: + - [ ] Class `ActorCompiler`: + - [ ] Method `compile(config: ActorConfigSchema) -> CompiledActor`: + - [ ] Dispatch based on actor type (LLM, TOOL, GRAPH) + - [ ] Return CompiledActor with runnable LangGraph + - [ ] Method `compile_llm_actor(config) -> StateGraph`: + - [ ] Create single-node graph wrapping LLM + - [ ] Configure model, temperature, system prompt + - [ ] Add memory if enabled + - [ ] Method `compile_tool_actor(config) -> StateGraph`: + - [ ] Create tool nodes from inline code + - [ ] Wrap in LangGraph tool execution pattern + - [ ] Method `compile_graph_actor(config) -> StateGraph`: + - [ ] Create StateGraph with specified nodes + - [ ] Add edges and conditional routing + - [ ] Compile nested actor references + - [ ] **C2.3** [Aditya] Implement tool node generation from skill code: + - [ ] Parse Python code from `code` field + - [ ] Create LangGraph tool node wrapper + - [ ] Inject `context` and `input_data` parameters + - [ ] Handle return value routing to next node + - [ ] Add error handling and logging + - [ ] **C2.4** [Aditya] Implement actor reference resolution: + - [ ] When actor config references another actor by name: + - [ ] Load referenced actor from registry + - [ ] Compile referenced actor + - [ ] Create subgraph node for the reference + - [ ] Detect circular references and error + - [ ] Cache compiled actors for reuse + - [ ] **C2.5** [Aditya] Update `ActorRegistry` to support compilation: + - [ ] Method `get_compiled(name: str) -> CompiledActor`: + - [ ] Load actor config + - [ ] Check cache for compiled version + - [ ] Compile if not cached + - [ ] Return compiled actor + - [ ] Cache invalidation when actor config changes - [ ] Tests: Behave scenarios for actor compilation + - [ ] **C2.6** [Rui] Write Behave scenarios in `features/actor_compilation.feature`: + - [ ] Scenario: Compile simple LLM actor creates valid graph + - [ ] Scenario: Compile tool actor with inline code works + - [ ] Scenario: Compile graph actor creates correct topology + - [ ] Scenario: Actor referencing other actor compiles recursively + - [ ] Scenario: Circular reference detected and errors + - [ ] Scenario: Invalid actor config produces clear error -- [ ] **Stage C3: Skill Execution** (Day 3-4) +- [ ] **Stage C3: Skill Execution Framework** (Day 5-6) **[Jeff + Aditya - Critical Path]** - [ ] Code: Implement skill execution framework - - [ ] Define `Skill` protocol for executable skills - - [ ] Create skill executor that runs inline Python code - - [ ] Add context injection for skills (project resources, plan state) - - [ ] Implement subplan spawning skill (`context.spawn_subplan()`) - - [ ] Location: `src/cleveragents/actor/skills.py` + - [ ] **C3.1** [Jeff] Define `Skill` protocol in `src/cleveragents/actor/skills/protocol.py`: + - [ ] **C3.1a** Create abstract base using `typing.Protocol`: + ```python + class Skill(Protocol): + @property + def name(self) -> str: ... + @property + def description(self) -> str: ... + @property + def parameters(self) -> dict[str, Any]: ... # JSON Schema + @property + def metadata(self) -> SkillMetadata: ... + + async def execute( + self, + input_data: dict[str, Any], + context: SkillContext + ) -> SkillResult: ... + ``` + - [ ] **C3.1b** Define `SkillResult` dataclass: + - [ ] Field `success: bool` - whether execution succeeded + - [ ] Field `result: Any` - return value if successful + - [ ] Field `error: str | None` - error message if failed + - [ ] Field `changes: list[Change]` - changes made to resources + - [ ] Field `duration_ms: int` - execution time + - [ ] **C3.1c** Add docstrings explaining contract for skill implementers + - [ ] **C3.2** [Jeff] Define `SkillMetadata` Pydantic model in `src/cleveragents/actor/skills/metadata.py`: + - [ ] **C3.2a** Core capability fields: + - [ ] Field `read_only: bool = False` - only performs read operations + - [ ] Field `writes: bool = False` - can modify resources + - [ ] Field `write_scope: list[str] = []` - glob patterns for writable paths + - [ ] Field `idempotent: bool = False` - repeated calls produce same result + - [ ] Field `checkpointable: bool = False` - supports checkpoint/rollback + - [ ] Field `side_effects: list[str] = []` - external side effects (e.g., "network", "subprocess") + - [ ] **C3.2b** Safety and control fields: + - [ ] Field `human_approval_required: bool = False` - requires user confirmation + - [ ] Field `rate_limit: RateLimit | None = None` - calls per minute/hour + - [ ] Field `cost_profile: CostProfile | None = None` - estimated cost per call + - [ ] Field `timeout_seconds: int = 30` - maximum execution time + - [ ] **C3.2c** Define `RateLimit` and `CostProfile` models + - [ ] **C3.2d** Add validation to ensure `writes=True` if `write_scope` is non-empty + - [ ] **C3.3** [Jeff] Create `SkillContext` in `src/cleveragents/actor/skills/context.py`: + - [ ] **C3.3a** Define context fields: + - [ ] Field `plan_id: str` - current plan ULID + - [ ] Field `plan: Plan` - full plan object for reference + - [ ] Field `project: Project` - target project + - [ ] Field `resources: list[Resource]` - available resources + - [ ] Field `sandbox_manager: SandboxManager` - for sandbox access + - [ ] Field `changeset: ChangeSet` - accumulating changes + - [ ] Field `invocation_tracker: SkillInvocationTracker` - tracking calls + - [ ] Field `logger: logging.Logger` - skill-specific logger + - [ ] **C3.3b** Implement convenience methods: + - [ ] Method `get_file(path: str, resource: str | None = None) -> str`: + - [ ] Resolve path to sandboxed location + - [ ] Read and return file contents + - [ ] Raise FileNotFoundError if not exists + - [ ] Method `write_file(path: str, content: str, resource: str | None = None) -> Change`: + - [ ] Resolve path to sandboxed location + - [ ] Validate path against deny-list + - [ ] Create parent directories if needed + - [ ] Write content + - [ ] Create and record Change + - [ ] Return Change for tracking + - [ ] Method `edit_file(path: str, edits: list[Edit], resource: str | None = None) -> Change`: + - [ ] Read current content + - [ ] Apply edits sequentially + - [ ] Write modified content + - [ ] Record Change with edits + - [ ] Method `delete_file(path: str, resource: str | None = None) -> Change`: + - [ ] Validate file exists + - [ ] Delete file + - [ ] Record Change + - [ ] Method `list_files(pattern: str, resource: str | None = None) -> list[str]`: + - [ ] Resolve pattern to sandbox + - [ ] Return matching paths + - [ ] Method `search_files(pattern: str, content_pattern: str, resource: str | None = None) -> list[SearchResult]`: + - [ ] Search file contents with regex + - [ ] Return matches with file, line, context + - [ ] **C3.3c** Implement subplan spawning: + - [ ] Method `spawn_subplan(action: str, target_resources: list[str] | None = None, arguments: dict | None = None) -> str`: + - [ ] Validate action exists + - [ ] Create child plan with parent_plan_id = self.plan_id + - [ ] Queue subplan for execution + - [ ] Return subplan_id for tracking + - [ ] Record as `subplan_spawn` decision type + - [ ] **C3.3d** Implement read-only check enforcement: + - [ ] If plan.action.read_only is True, block all write operations + - [ ] Raise `ReadOnlyViolationError` if write attempted + - [ ] **C3.4** [Aditya] Implement `InlineSkillExecutor` in `src/cleveragents/actor/skills/inline_executor.py`: + - [ ] **C3.4a** Create class for executing inline Python code from actor YAML: + ```python + class InlineSkillExecutor: + def __init__(self, code: str, timeout: int = 30): + self.code = code + self.timeout = timeout + ``` + - [ ] **C3.4b** Create sandboxed execution environment: + - [ ] Restricted `__builtins__`: + - [ ] ALLOWED: `len`, `range`, `str`, `int`, `float`, `list`, `dict`, `set`, `tuple`, `bool`, `None`, `True`, `False`, `print`, `isinstance`, `hasattr`, `getattr`, `enumerate`, `zip`, `map`, `filter`, `sorted`, `reversed`, `any`, `all`, `min`, `max`, `sum`, `abs`, `round` + - [ ] BLOCKED: `open`, `exec`, `eval`, `compile`, `__import__`, `globals`, `locals`, `vars`, `dir`, `input` + - [ ] Inject `context: SkillContext` variable + - [ ] Inject `input_data: dict` variable + - [ ] Inject standard library modules: `re`, `json`, `datetime`, `collections`, `itertools`, `functools` + - [ ] **C3.4c** Execute code and capture result: + - [ ] Use `exec()` with restricted globals/locals + - [ ] Capture `result` variable as return value + - [ ] If no `result` variable, return None + - [ ] Wrap in asyncio.wait_for for timeout + - [ ] **C3.4d** Handle errors gracefully: + - [ ] Catch all exceptions during execution + - [ ] Convert to SkillResult with error message + - [ ] Include stack trace in error for debugging + - [ ] Log error with skill name and input + - [ ] **C3.4e** Add timeout support: + - [ ] Default 30 seconds + - [ ] Configurable via skill metadata + - [ ] Raise TimeoutError if exceeded + - [ ] **C3.5** [Aditya] Implement subplan spawning in skill context: + - [ ] **C3.5a** Update SkillContext.spawn_subplan to create real subplans: + - [ ] Call PlanLifecycleService.use_action() with parent_plan_id + - [ ] Set subplan's root_plan_id to parent's root_plan_id (or parent's id if root) + - [ ] Set subplan's automation_level from parent + - [ ] Return subplan_id + - [ ] **C3.5b** Add subplan tracking to parent plan: + - [ ] Store spawned subplan IDs in plan's execution_log + - [ ] Support querying all subplans of a plan + - [ ] **C3.5c** Add subplan completion handling: + - [ ] Parent plan can check subplan status + - [ ] Parent plan can collect subplan results + - [ ] Support waiting for subplan completion + - [ ] **C3.6** [Jeff + Luis] Implement built-in resource skills in `src/cleveragents/actor/skills/builtin/`: + - [ ] **C3.6a** [Jeff] Create base skill class in `__init__.py`: + ```python + class BuiltinSkill(ABC): + @abstractmethod + async def execute(self, input_data: dict, context: SkillContext) -> SkillResult: ... + + def _validate_path(self, path: str, context: SkillContext) -> str: + """Resolve and validate path against sandbox.""" + ... + ``` + - [ ] **C3.6b** [Jeff] File operation skills in `file_ops.py`: + - [ ] **ReadFileSkill**: + - [ ] Parameters: `path: str` (required) + - [ ] Metadata: `read_only=True` + - [ ] Implementation: resolve path, read via sandbox, return content + - [ ] Error handling: FileNotFoundError, PermissionError + - [ ] **WriteFileSkill**: + - [ ] Parameters: `path: str`, `content: str` + - [ ] Metadata: `writes=True, write_scope=['**/*']` + - [ ] Implementation: + - [ ] Validate path not in deny-list + - [ ] Create parent directories if needed + - [ ] Determine if create or modify operation + - [ ] Write content to sandbox + - [ ] Create Change record with operation type + - [ ] Record change in context.changeset + - [ ] Return: Change object with path and operation + - [ ] **EditFileSkill** (most complex - critical for coding): + - [ ] Parameters: `path: str`, `edits: list[Edit]` + - [ ] Metadata: `writes=True, idempotent=False` + - [ ] Implementation: + - [ ] Read original file content + - [ ] For each Edit in edits: + - [ ] If type=SEARCH_REPLACE: find `search` text, replace with `replace` + - [ ] If type=LINE_RANGE: replace lines start_line:end_line with content + - [ ] If type=INSERT_AFTER: insert content after matching line + - [ ] If type=INSERT_BEFORE: insert content before matching line + - [ ] If type=DELETE_LINES: remove lines start_line:end_line + - [ ] Track all changes made + - [ ] Write modified content + - [ ] Create Change with edits list + - [ ] Error handling: SearchTextNotFoundError, InvalidLineRangeError + - [ ] **DeleteFileSkill**: + - [ ] Parameters: `path: str` + - [ ] Metadata: `writes=True` + - [ ] Implementation: delete file, create DELETE Change + - [ ] **MoveFileSkill**: + - [ ] Parameters: `source: str`, `destination: str` + - [ ] Metadata: `writes=True` + - [ ] Implementation: move file, create MOVE Change with new_path + - [ ] **CopyFileSkill**: + - [ ] Parameters: `source: str`, `destination: str` + - [ ] Metadata: `writes=True` + - [ ] Implementation: copy file, create CREATE Change + - [ ] **C3.6c** [Luis] Directory operation skills in `dir_ops.py`: + - [ ] **CreateDirectorySkill**: + - [ ] Parameters: `path: str` + - [ ] Metadata: `writes=True` + - [ ] Implementation: create directory (and parents), record Change + - [ ] **ListDirectorySkill**: + - [ ] Parameters: `path: str`, `pattern: str = "*"`, `recursive: bool = False` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: list matching files/dirs, return paths + - [ ] **DeleteDirectorySkill**: + - [ ] Parameters: `path: str`, `recursive: bool = False` + - [ ] Metadata: `writes=True` + - [ ] Implementation: delete directory, record DELETE Changes for all contents + - [ ] **C3.6d** [Luis] Search skills in `search_ops.py`: + - [ ] **SearchFilesSkill**: + - [ ] Parameters: `pattern: str` (glob), `content_pattern: str` (regex), `max_results: int = 100` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: + - [ ] Find files matching glob pattern + - [ ] Search each file for content_pattern + - [ ] Return list of SearchResult(file, line_number, line_content, context) + - [ ] **FindDefinitionSkill** (uses tree-sitter for AST): + - [ ] Parameters: `symbol: str`, `language: str | None = None` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: + - [ ] Parse files with tree-sitter + - [ ] Find function/class/variable definitions + - [ ] Return list of Location(file, line, column, snippet) + - [ ] **FindReferencesSkill**: + - [ ] Parameters: `symbol: str` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: find all usages of symbol + - [ ] **GetFileInfoSkill**: + - [ ] Parameters: `path: str` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: return FileInfo(size, mtime, language, line_count) + - [ ] **C3.6e** [Hamza] Git operation skills in `git_ops.py`: + - [ ] **GitStatusSkill**: + - [ ] Parameters: (none) + - [ ] Metadata: `read_only=True` + - [ ] Implementation: run `git status --porcelain`, parse output + - [ ] **GitDiffSkill**: + - [ ] Parameters: `path: str | None = None`, `staged: bool = False` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: run `git diff [--staged] [path]` + - [ ] **GitLogSkill**: + - [ ] Parameters: `count: int = 10`, `path: str | None = None` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: run `git log --oneline -n {count}` + - [ ] **GitBlameSkill**: + - [ ] Parameters: `path: str`, `start_line: int | None`, `end_line: int | None` + - [ ] Metadata: `read_only=True` + - [ ] Implementation: run `git blame -L {start},{end} {path}` + - [ ] **C3.6f** [Jeff] All built-in skills must implement: + - [ ] Full SkillMetadata with accurate capability flags + - [ ] Proper error handling with descriptive messages + - [ ] Logging of all operations for debugging + - [ ] Path validation against sandbox and deny-lists + - [ ] Change recording for all write operations + - [ ] Async execution support + - [ ] **C3.6g** [Jeff] Create skill registration in `src/cleveragents/actor/skills/registry.py`: + - [ ] `BuiltinSkillRegistry` singleton with all built-in skills + - [ ] Method `get_skill(name: str) -> Skill | None` + - [ ] Method `list_skills() -> list[Skill]` + - [ ] Method `list_by_capability(read_only: bool = None, writes: bool = None) -> list[Skill]` + - [ ] Register all C3.6 skills on import + - [ ] **C3.7** [Aditya] Implement MCP skill adapter in `src/cleveragents/actor/skills/mcp_adapter.py`: + - [ ] **C3.7a** `MCPServerConnection` class: + - [ ] Connect to MCP server via stdio or SSE transport + - [ ] List available tools from server + - [ ] Call tools with JSON-RPC + - [ ] Handle server lifecycle (start/stop) + - [ ] **C3.7b** `MCPSkillAdapter` class: + - [ ] Wrap MCP tool as CleverAgents Skill + - [ ] Infer SkillMetadata from MCP tool schema + - [ ] Intercept calls for sandbox path rewriting + - [ ] Record changes when MCP tool modifies resources + - [ ] **C3.7c** Actor YAML integration: + - [ ] Parse `mcp_servers` config in actor definition + - [ ] Auto-register MCP tools as skills in actor context + - [ ] Environment variable substitution for secrets - [ ] Tests: Integration tests for skill execution + - [ ] **C3.8** [Rui] Write Behave scenarios in `features/skill_execution.feature`: + - [ ] Scenario: Execute inline Python skill with context + - [ ] Scenario: Skill can read files from sandbox + - [ ] Scenario: Skill can write files to sandbox + - [ ] Scenario: Skill with invalid code produces error + - [ ] Scenario: Skill timeout prevents infinite loops + - [ ] Scenario: spawn_subplan creates child plan + - [ ] **C3.9** [Rui] Write Behave scenarios in `features/builtin_skills.feature`: + - [ ] Scenario: WriteFileSkill creates file and records Change + - [ ] Scenario: EditFileSkill applies search/replace edit + - [ ] Scenario: DeleteFileSkill removes file and records Change + - [ ] Scenario: MoveFileSkill renames file and records Change + - [ ] Scenario: ListDirectorySkill returns matching files + - [ ] Scenario: SearchFilesSkill finds content matches + - [ ] Scenario: Skill respects deny-list patterns (.git/, node_modules/) + - [ ] Scenario: Skill enforces sandbox boundaries + - [ ] **C3.10** [Rui] Write Behave scenarios in `features/mcp_integration.feature`: + - [ ] Scenario: Connect to MCP server and list tools + - [ ] Scenario: MCP tool becomes available as skill + - [ ] Scenario: MCP tool call is intercepted for sandbox paths + - [ ] Scenario: MCP tool writes are recorded in ChangeSet -- [ ] **Stage C4: Built-in Provider Actors** (Day 5) +- [ ] **Stage C4: Tool-Based Change Tracking** (Day 8-10) **[Luis - Architectural]** + - [ ] Code: Implement tool-based change tracking (NOT output parsing) + - [ ] **CRITICAL ARCHITECTURE**: ChangeSet is built from skill/tool invocations, NOT by parsing LLM text output + - [ ] **C4.1** [Luis] Update `src/cleveragents/domain/models/core/change.py`: + - [ ] Enhance `Change` model with: + - [ ] Field `operation: OperationType` - create/modify/delete/move + - [ ] Field `path: str` - target resource path + - [ ] Field `new_path: str | None` - for move operations + - [ ] Field `content: str | None` - full content (for create) + - [ ] Field `edits: list[Edit] | None` - targeted edits (for modify) + - [ ] Field `patch: str | None` - unified diff (generated, not parsed) + - [ ] Field `language: str | None` - detected language + - [ ] Field `skill_invocation_id: str` - which skill call produced this + - [ ] Field `timestamp: datetime` - when change was made + - [ ] Field `validation_result: ValidationResult | None` + - [ ] Define `Edit` model for targeted edits: + - [ ] Field `type: EditType` - search_replace, line_range, insert_after, etc. + - [ ] Field `search: str | None` - text to find (for search_replace) + - [ ] Field `replace: str | None` - replacement text + - [ ] Field `start_line: int | None` - for line-based edits + - [ ] Field `end_line: int | None` - for line-based edits + - [ ] Field `content: str | None` - content to insert + - [ ] Enhance `ChangeSet` model with: + - [ ] Field `changes: list[Change]` - all resource changes + - [ ] Field `warnings: list[str]` - non-blocking issues + - [ ] Field `skill_invocations: list[SkillInvocation]` - full invocation history + - [ ] Field `generated_by_actor: str` - actor that produced this + - [ ] Field `validation: ChangeSetValidation` - overall validation + - [ ] Method `add_change(change: Change)` - append change from skill + - [ ] Method `get_change(path: str) -> Change | None` - find by path + - [ ] Method `get_changes_by_skill(skill_id: str) -> list[Change]` - changes from specific skill + - [ ] Method `file_paths() -> list[str]` - all affected paths + - [ ] Method `to_diff() -> str` - unified diff of all changes + - [ ] Method `rollback_to(change_id: str)` - remove changes after point + - [ ] **C4.2** [Luis] Implement `SkillInvocationTracker` in `src/cleveragents/actor/skills/tracker.py`: + - [ ] **C4.2a** `SkillInvocation` model: + - [ ] Field `id: str` - unique invocation ID + - [ ] Field `skill_name: str` - which skill was called + - [ ] Field `parameters: dict` - input parameters + - [ ] Field `result: Any` - skill return value + - [ ] Field `changes: list[Change]` - resource changes produced + - [ ] Field `timestamp: datetime` - when invoked + - [ ] Field `duration_ms: int` - execution time + - [ ] Field `error: str | None` - if skill failed + - [ ] **C4.2b** `SkillInvocationTracker` class: + - [ ] Method `start_invocation(skill: Skill, params: dict) -> str` - begin tracking + - [ ] Method `record_change(invocation_id: str, change: Change)` - record change + - [ ] Method `complete_invocation(invocation_id: str, result: Any)` - finish tracking + - [ ] Method `fail_invocation(invocation_id: str, error: Exception)` - record failure + - [ ] Method `get_invocations() -> list[SkillInvocation]` - full history + - [ ] Method `build_changeset() -> ChangeSet` - assemble from invocations + - [ ] **C4.3** [Luis] Implement `ToolCallRouter` in `src/cleveragents/actor/skills/router.py`: + - [ ] **C4.3a** Parse LLM tool calls (NOT text output): + - [ ] Handle OpenAI-style tool_calls from response + - [ ] Handle Anthropic-style tool_use blocks + - [ ] Handle LangChain AgentAction format + - [ ] **C4.3b** Route tool calls to skills: + - [ ] Look up skill by name in registry + - [ ] Validate parameters against skill schema + - [ ] Check capability metadata (read_only, writes, etc.) + - [ ] Enforce permission restrictions + - [ ] **C4.3c** Execute with tracking: + - [ ] Start invocation tracking + - [ ] Execute skill in sandbox context + - [ ] Record changes produced by skill + - [ ] Complete invocation tracking + - [ ] Return result to LLM + - [ ] **C4.4** [Luis] Implement resource path validation in `src/cleveragents/actor/skills/path_validator.py`: + - [ ] Validate paths against sandbox boundaries + - [ ] Enforce deny-list patterns (.git/, node_modules/, __pycache__/, etc.) + - [ ] Auto-create parent directories for new file paths + - [ ] Resolve relative paths to absolute sandbox paths + - [ ] Detect path traversal attempts (../) + - [ ] **C4.5** [Luis] Create diff generation in `src/cleveragents/agents/diff_generator.py`: + - [ ] Method `generate_unified_diff(change: Change, sandbox: Sandbox) -> str`: + - [ ] Compare sandbox state with original + - [ ] Generate unified diff format + - [ ] Include file headers with paths + - [ ] Method `generate_changeset_diff(changeset: ChangeSet, sandbox: Sandbox) -> str`: + - [ ] Combine all change diffs + - [ ] Add summary header (files created, modified, deleted) + - [ ] Include statistics (lines added/removed) + - [ ] Method `generate_edit_preview(edit: Edit, original: str) -> str`: + - [ ] Show what an edit will change + - [ ] Highlight search/replace matches + - [ ] Tests: Tool-based change tracking tests + - [ ] **C4.6** [Rui] Write Behave scenarios in `features/change_tracking.feature`: + - [ ] Scenario: Skill invocation creates Change record + - [ ] Scenario: Multiple skill calls accumulate in ChangeSet + - [ ] Scenario: ChangeSet correctly tracks skill invocation history + - [ ] Scenario: Failed skill invocation is recorded with error + - [ ] Scenario: Generate unified diff from ChangeSet + - [ ] Scenario: Rollback to specific change point + - [ ] **C4.7** [Rui] Write Behave scenarios in `features/tool_call_routing.feature`: + - [ ] Scenario: Route OpenAI-style tool call to skill + - [ ] Scenario: Route Anthropic-style tool_use to skill + - [ ] Scenario: Validate parameters against skill schema + - [ ] Scenario: Reject tool call for read_only skill trying to write + - [ ] Scenario: Path validation rejects traversal attempt + - [ ] Scenario: Path validation auto-creates directories + +- [ ] **Stage C5: Validation Pipeline** (Day 9-11) **[Luis]** + - [ ] Code: Implement real validation gates + - [ ] **C5.1** [Luis] Create `ValidationPipeline` in `src/cleveragents/application/services/validation_service.py`: + - [ ] Method `validate_changeset(changeset: ChangeSet, project: Project) -> ValidationResult`: + - [ ] Run all applicable validators + - [ ] Aggregate results + - [ ] Return pass/fail with details + - [ ] Method `validate_syntax(change: Change) -> ValidationResult`: + - [ ] Detect language from extension + - [ ] Run language-specific syntax check + - [ ] Method `validate_lint(change: Change, config: ValidationConfig) -> ValidationResult`: + - [ ] Run lint command from project config + - [ ] Parse lint output for errors + - [ ] Method `validate_tests(project: Project, config: ValidationConfig) -> ValidationResult`: + - [ ] Run test command from project config + - [ ] Parse test results + - [ ] Method `validate_build(project: Project, config: ValidationConfig) -> ValidationResult`: + - [ ] Run build command from project config + - [ ] Check for build errors + - [ ] **C5.2** [Luis] Implement language-specific validators: + - [ ] Python: `python -m py_compile ` + - [ ] JavaScript/TypeScript: `node --check ` or syntax parse + - [ ] JSON: `json.loads()` validation + - [ ] YAML: `yaml.safe_load()` validation + - [ ] **C5.3** [Luis] Implement validation failure handling: + - [ ] If validation fails, attempt repair loop: + - [ ] Send errors to LLM with request to fix + - [ ] Parse fixed output + - [ ] Re-validate + - [ ] Max 3 repair attempts + - [ ] If repair fails, mark changeset as errored + - [ ] Preserve original output for debugging + - [ ] **C5.4** [Luis] Remove stub validation from existing code: + - [ ] Replace "output length > 10" check with real validation + - [ ] Remove "PASS" stub validation + - [ ] Tests: Validation tests + - [ ] **C5.5** [Rui] Write Behave scenarios in `features/validation_pipeline.feature`: + - [ ] Scenario: Valid Python file passes syntax validation + - [ ] Scenario: Invalid Python file fails with clear error + - [ ] Scenario: Lint errors detected and reported + - [ ] Scenario: Test failures detected and reported + - [ ] Scenario: Validation repair loop fixes simple errors + - [ ] Scenario: Validation repair gives up after max attempts + +- [ ] **Stage C6: Built-in Provider Actors** (Day 10-11) **[Aditya]** - [ ] Code: Create built-in actors for each provider - - [ ] Generate `openai/gpt-4`, `openai/gpt-3.5-turbo`, etc. - - [ ] Generate `anthropic/claude-3-opus`, `anthropic/claude-3-sonnet`, etc. - - [ ] Generate `google/gemini-pro`, etc. - - [ ] Ensure built-in actors work as strategy/execution actors - - [ ] Location: `src/cleveragents/actor/builtins.py` + - [ ] **C6.1** [Aditya] Generate built-in actor configs in `src/cleveragents/actor/builtins.py`: + - [ ] `openai/gpt-4` - GPT-4 wrapper + - [ ] `openai/gpt-4-turbo` - GPT-4 Turbo wrapper + - [ ] `openai/gpt-3.5-turbo` - GPT-3.5 wrapper + - [ ] `anthropic/claude-3-opus` - Claude 3 Opus wrapper + - [ ] `anthropic/claude-3-sonnet` - Claude 3 Sonnet wrapper + - [ ] `anthropic/claude-3-haiku` - Claude 3 Haiku wrapper + - [ ] `google/gemini-pro` - Gemini Pro wrapper + - [ ] `google/gemini-ultra` - Gemini Ultra wrapper + - [ ] **C6.2** [Aditya] Ensure built-in actors work as strategy/execution actors: + - [ ] Add appropriate system prompts for each role + - [ ] Configure temperature defaults (lower for execution) + - [ ] Test with plan lifecycle + - [ ] **C6.3** [Aditya] Implement provider capability detection: + - [ ] Check which API keys are configured + - [ ] Only register actors for available providers + - [ ] Clear error message for unavailable providers - [ ] Tests: Verify built-in actors work in plan lifecycle + - [ ] **C6.4** [Rui] Write Behave scenarios in `features/builtin_actors.feature`: + - [ ] Scenario: Built-in OpenAI actor loads correctly + - [ ] Scenario: Built-in Anthropic actor loads correctly + - [ ] Scenario: Built-in actor can be used as strategy actor + - [ ] Scenario: Missing API key produces clear error -- [ ] **Stage C5: Plan-Actor Integration** (Day 6-8) +- [ ] **Stage C7: Plan-Actor Integration** (Day 11-14) **[Aditya + Luis]** - [ ] Code: Connect actors to plan lifecycle - - [ ] Strategize phase invokes `strategy_actor` with project context - - [ ] Implement dependency closure computation - - [ ] Resource-aware analysis (imports, includes, symbols, tests, build refs) - - [ ] Hierarchical task decomposition - - [ ] Bounded context generation per task - - [ ] Execute phase invokes `execution_actor` with strategy output - - [ ] Receives precise dependency closure - - [ ] Works within sandbox boundaries - - [ ] Can spawn subplans based on strategy decisions - - [ ] Actors receive plan description, project resources, and arguments - - [ ] Actor output flows to next phase - - [ ] Location: `src/cleveragents/application/services/plan_lifecycle_service.py` + - [ ] **C7.1** [Aditya] Update `PlanLifecycleService.execute_strategize()`: + - [ ] Load strategy_actor from action + - [ ] Compile actor to LangGraph + - [ ] Build strategy context: + - [ ] Project resources + - [ ] Plan description and arguments + - [ ] Definition of done + - [ ] Invoke actor graph with context + - [ ] Parse strategy output + - [ ] Store strategy in plan + - [ ] **C7.2** [Aditya] Implement dependency closure computation: + - [ ] Method `compute_closure(target: str, project: Project) -> ResourceClosure`: + - [ ] Find direct imports/includes + - [ ] Find symbol dependencies + - [ ] Find test dependencies + - [ ] Find build references + - [ ] Integrate with strategy actor context + - [ ] **C7.3** [Luis] Update `PlanLifecycleService.execute_execution()`: + - [ ] Load execution_actor from action + - [ ] Compile actor to LangGraph + - [ ] Build execution context: + - [ ] Strategy output + - [ ] Resource service for sandbox access + - [ ] Bounded dependency closure + - [ ] Invoke actor graph with context + - [ ] Parse output as ChangeSet + - [ ] Run validation pipeline + - [ ] Handle subplan spawning + - [ ] **C7.4** [Luis] Update `PlanLifecycleService.apply_plan()`: + - [ ] Verify execution completed successfully + - [ ] Commit all sandboxes + - [ ] Apply ChangeSet to resources + - [ ] Record applied artifacts + - [ ] Clean up sandboxes + - [ ] **C7.4a** [Luis] Implement ATOMIC apply: + - [ ] Apply must be all-or-nothing: + - [ ] Write all changes to temp files first + - [ ] Validate all writes succeeded + - [ ] Atomic rename/swap to final locations + - [ ] If any step fails, rollback all changes + - [ ] In git mode: + - [ ] All changes in single commit + - [ ] If commit fails, no partial changes applied + - [ ] Handle partial failure: + - [ ] Preserve sandbox for inspection + - [ ] Clear error message about what failed + - [ ] Allow retry after manual fix + - [ ] **C7.5** [Aditya] Implement hierarchical task decomposition: + - [ ] Strategy actor can emit subplan decisions + - [ ] Each subplan gets bounded context + - [ ] Parallel or sequential execution modes + - [ ] **C7.6** [Luis] Connect output parser to execution flow: + - [ ] After actor produces output, parse to ChangeSet + - [ ] Validate ChangeSet + - [ ] Store ChangeSet in plan + - [ ] **C7.7** [Luis] Implement diff review artifact storage: + - [ ] Store generated diff in plan metadata + - [ ] Create `DiffArtifact` model: + - [ ] Field `diff_id: str` - ULID + - [ ] Field `plan_id: str` - parent plan + - [ ] Field `unified_diff: str` - full unified diff + - [ ] Field `file_summaries: list[FileSummary]` - per-file summary + - [ ] Field `risk_markers: list[str]` - touched auth code, migrations, etc. + - [ ] Field `created_at: datetime` + - [ ] Display diff in `agents plan diff` command + - [ ] Display diff before apply in review-before-apply mode - [ ] Tests: End-to-end tests for full plan lifecycle with actors + - [ ] **C7.7** [Rui] Write Behave scenarios in `features/plan_actor_integration.feature`: + - [ ] Scenario: Full lifecycle with LLM actors (mocked) + - [ ] Scenario: Strategy actor receives correct context + - [ ] Scenario: Execution actor receives strategy output + - [ ] Scenario: ChangeSet applied correctly + - [ ] Scenario: Validation failure triggers repair loop + - [ ] **C7.8** [Rui] Write Robot integration test `robot/plan_actor_integration.robot`: + - [ ] Test: Full lifecycle with real sandbox + - [ ] Test: Multi-file generation and application - [ ] Tests: Dependency closure computation accuracy - - [ ] Tests: Large codebase task decomposition + - [ ] **C7.9** [Rui] Write Behave scenarios in `features/dependency_closure.feature`: + - [ ] Scenario: Python imports detected correctly + - [ ] Scenario: Test file dependencies included **M3 SUCCESS CRITERIA**: - [ ] Can define actors in YAML with skills - [ ] Actors compile to LangGraph graphs - [ ] Skills can execute inline Python code +- [ ] Built-in resource skills work (read/write/edit/delete files) +- [ ] MCP skill adapter connects to external servers - [ ] Built-in provider actors work -- [ ] Full plan lifecycle works: Action → Strategize (with actor) → Execute (with actor) → Apply +- [ ] Tool-based change tracking builds ChangeSet from skill invocations +- [ ] Validation pipeline catches errors +- [ ] Full plan lifecycle works: Action -> Strategize (with actor) -> Execute (with actor) -> Apply -**--- MERGE POINT: After M3, all workstreams coordinate ---** +**--- MERGE POINT 1: After M3, all workstreams coordinate ---** --- -### Section 6: Decision Tree [After M3 Merge - All Developers] +### Section 6: Decision Tree [After M3 Merge - Days 15-21] -**Target: Milestone M4 (+12 days)** +**Target: Milestone M4 (+21 days)** -- [ ] **Stage D1: Decision Data Model** (Day 9) +- [ ] **Stage D1: Decision Data Model** (Day 15-16) **[Hamza - Well Rounded]** - [ ] Code: Create Decision domain model - - [ ] Define `Decision` Pydantic model per spec (decision_id ULID, plan_id, parent_decision_id, decision_type, question, chosen_option, alternatives_considered, rationale, etc.) - - [ ] Define `DecisionType` enum (prompt_definition, strategy_choice, implementation_choice, resource_selection, subplan_spawn, tool_invocation, error_recovery, validation_response, user_intervention) - - [ ] Location: `src/cleveragents/domain/models/core/decision.py` + - [ ] **D1.1** [Hamza] Define `Decision` Pydantic model in `src/cleveragents/domain/models/core/decision.py`: + - [ ] Field `decision_id: str` - ULID identifier + - [ ] Field `plan_id: str` - parent plan + - [ ] Field `parent_decision_id: str | None` - tree structure + - [ ] Field `sequence_number: int` - order within plan + - [ ] Field `decision_type: DecisionType` - classification + - [ ] Field `question: str` - what question was answered + - [ ] Field `chosen_option: str` - the decision made + - [ ] Field `alternatives_considered: list[str]` - other options + - [ ] Field `confidence_score: float | None` - 0.0-1.0 + - [ ] Field `rationale: str` - why this choice + - [ ] Field `actor_reasoning: str | None` - raw LLM reasoning + - [ ] Field `context_snapshot: ContextSnapshot` - for replay + - [ ] Field `downstream_decision_ids: list[str]` - affected decisions + - [ ] Field `downstream_plan_ids: list[str]` - spawned subplans + - [ ] Field `artifacts_produced: list[str]` - created artifacts + - [ ] Field `is_correction: bool` - is this a correction + - [ ] Field `corrects_decision_id: str | None` - what it corrects + - [ ] Field `superseded_by: str | None` - if this was corrected + - [ ] Field `created_at: datetime` + - [ ] **D1.2** [Hamza] Define `DecisionType` enum: + - [ ] `PROMPT_DEFINITION` - root decision (the plan prompt) + - [ ] `STRATEGY_CHOICE` - high-level approach + - [ ] `IMPLEMENTATION_CHOICE` - how to implement + - [ ] `RESOURCE_SELECTION` - which resources to use + - [ ] `SUBPLAN_SPAWN` - decision to create subplan + - [ ] `TOOL_INVOCATION` - which tool/skill to use + - [ ] `ERROR_RECOVERY` - how to handle failure + - [ ] `VALIDATION_RESPONSE` - response to validation failure + - [ ] `USER_INTERVENTION` - user provided guidance + - [ ] **D1.3** [Hamza] Define `ContextSnapshot` model: + - [ ] Field `hot_context_hash: str` - cryptographic hash + - [ ] Field `hot_context_ref: str` - pointer to stored snapshot + - [ ] Field `relevant_resources: list[str]` - resource IDs + - [ ] Field `actor_state_ref: str` - LangGraph checkpoint - [ ] Tests: Behave scenarios for decision model + - [ ] **D1.4** [Rui] Write Behave scenarios in `features/decision_model.feature`: + - [ ] Scenario: Create decision with all fields + - [ ] Scenario: Decision type validation + - [ ] Scenario: Decision tree structure with parent/child + - [ ] Scenario: Context snapshot serialization -- [ ] **Stage D2: Decision Recording** (Day 10) +- [ ] **Stage D2: Decision Recording** (Day 16-18) **[Hamza]** - [ ] Code: Record decisions during Strategize - - [ ] Strategy actor outputs decisions as structured data - - [ ] Each decision gets a ULID and is persisted - - [ ] Build decision tree from parent_decision_id relationships - - [ ] Root decision is the plan's prompt_definition - - [ ] Capture complete context snapshots: - - [ ] Hot context hash (cryptographic) - - [ ] Full context snapshot storage - - [ ] List of all relevant resources - - [ ] Actor state checkpoint - - [ ] Record alternatives considered and confidence scores - - [ ] Implement semantic validation at decision time - - [ ] Location: `src/cleveragents/application/services/decision_service.py` + - [ ] **D2.1** [Hamza] Create `DecisionService` in `src/cleveragents/application/services/decision_service.py`: + - [ ] Method `record_decision(plan_id, decision_type, question, chosen_option, ...) -> Decision`: + - [ ] Generate ULID + - [ ] Capture context snapshot + - [ ] Persist decision + - [ ] Return created decision + - [ ] Method `get_decision_tree(plan_id: str) -> list[Decision]`: + - [ ] Query all decisions for plan + - [ ] Build tree structure + - [ ] Method `get_decision(decision_id: str) -> Decision | None` + - [ ] Method `get_children(decision_id: str) -> list[Decision]` + - [ ] Method `mark_superseded(decision_id: str, by: str) -> None` + - [ ] **D2.2** [Hamza] Integrate decision recording into strategy actor: + - [ ] Strategy actor outputs structured decisions + - [ ] Each strategic choice becomes a decision record + - [ ] Root decision is the prompt_definition + - [ ] Build decision tree from strategy output + - [ ] **D2.3** [Hamza] Implement context snapshot capture: + - [ ] Hash hot context content + - [ ] Store full snapshot in database/file + - [ ] Link snapshot to decision + - [ ] **D2.4** [Hamza] Record alternatives and confidence: + - [ ] Strategy actor should output alternatives_considered + - [ ] Capture confidence_score if actor provides it + - [ ] **D2.5** [Hamza] Populate downstream relationships during Execute: + - [ ] When subplan spawned, update parent decision's downstream_plan_ids + - [ ] When artifact created, update decision's artifacts_produced - [ ] Tests: Verify decision tree is built during Strategize - - [ ] Tests: Context snapshot preservation and retrieval - - [ ] Tests: Decision replay from context + - [ ] **D2.6** [Rui] Write Behave scenarios in `features/decision_recording.feature`: + - [ ] Scenario: Strategize creates root prompt_definition decision + - [ ] Scenario: Strategy choices recorded as decisions + - [ ] Scenario: Decision tree has correct parent/child relationships + - [ ] Scenario: Context snapshot captured with decision + - [ ] Scenario: Subplan spawn updates downstream_plan_ids -- [ ] **Stage D3: Decision CLI** (Day 11) - - [ ] Code: Decision viewing and correction commands - - [ ] `agents plan tree [plan_id]` - display decision tree (ASCII) - - [ ] `agents plan correct --mode= --guidance ""` - - [ ] `agents plan correct --mode= --guidance-file ` - - [ ] Location: `src/cleveragents/cli/commands/decision.py` - - [ ] Tests: CLI tests for decision commands +- [ ] **Stage D3: Decision CLI & Viewing** (Day 16-17) **[Hamza]** + - [ ] Code: Decision viewing commands + - [ ] **D3.1** [Hamza] Implement `agents plan tree [plan_id]`: + - [ ] **D3.1a** Fetch decision tree for plan via DecisionService.get_decision_tree() + - [ ] **D3.1b** Build tree structure from parent_decision_id links + - [ ] **D3.1c** Render ASCII tree using Rich library: + ``` + ├── [prompt_definition] "Increase test coverage to 85%" + │ ├── [strategy_choice] "Prioritize auth module" (confidence: 0.85) + │ │ ├── [subplan_spawn] "Write tests for auth" → subplan_01ABC + │ │ └── [subplan_spawn] "Write tests for payment" → subplan_01DEF + │ └── [implementation_choice] "Use pytest with mocks" + ``` + - [ ] **D3.1d** Show decision_type, question summary, chosen_option summary + - [ ] **D3.1e** Highlight corrected decisions in yellow + - [ ] **D3.1f** Mark superseded decisions with strikethrough + - [ ] **D3.2** [Hamza] Implement `agents plan tree --format=json`: + - [ ] Output full decision tree as JSON + - [ ] Include all fields for visualization tools + - [ ] Support piping to external tools (D3/Cytoscape) + - [ ] **D3.3** [Hamza] Implement `agents plan explain `: + - [ ] **D3.3a** Fetch decision by ID + - [ ] **D3.3b** Display formatted output: + ``` + Decision: 01ARZ3NDEKTSV4RRFFQ69G5FAV + Type: strategy_choice + Question: Which modules should be prioritized for test coverage? + + Chosen: Prioritize auth and payment modules + + Alternatives Considered: + - Focus on high-churn modules (rejected: less impact) + - Start with utilities (rejected: low risk) + + Confidence: 0.85 + + Rationale: Auth and payment are highest-risk modules with + lowest current coverage. + + Downstream Impact: + - 2 subplans spawned: auth-tests, payment-tests + - 15 files affected + + Context Snapshot: ctx_hash_abc123 + ``` + - [ ] **D3.3c** Show upstream decisions (what led to this) + - [ ] **D3.3d** Show downstream decisions (what this affects) + - [ ] **D3.4** [Hamza] Implement `--guidance-file` option: + - [ ] Read guidance text from file instead of command line + - [ ] Support stdin: `cat guidance.txt | agents plan correct --mode=revert --guidance-file=-` -- [ ] **Stage D4: Decision Persistence** (Day 12) +- [ ] **Stage D4: Decision Correction Mechanism** (Day 17-18) **[Jeff - Critical]** + - [ ] Code: Implement decision correction (core to large project autonomy) + - [ ] **D4.1** [Jeff] Implement correction service in `src/cleveragents/application/services/correction_service.py`: + - [ ] **D4.1a** Method `correct_decision_revert(decision_id: str, guidance: str) -> CorrectionResult`: + - [ ] Validate decision exists and plan is correctable (not Applied) + - [ ] Identify all downstream decisions that depend on this one + - [ ] Identify all downstream plans (subplans) that depend on this + - [ ] Create `correction_attempts` record with status='pending' + - [ ] Archive old subtree (decisions + artifacts) for comparison + - [ ] Mark original decision as `superseded_by` the new correction + - [ ] Create new decision with `is_correction=True`, `corrects_decision_id=original` + - [ ] Inject guidance into the new decision's context + - [ ] Rollback sandbox to state before original decision + - [ ] Re-execute plan from that point + - [ ] Update correction_attempt status to 'completed' or 'failed' + - [ ] Return CorrectionResult with new_decision_id, affected_count + - [ ] **D4.1b** Method `correct_decision_append(decision_id: str, guidance: str) -> CorrectionResult`: + - [ ] Keep all existing history intact + - [ ] Create new subplan to "fix" the outcome + - [ ] Subplan's prompt includes the guidance + - [ ] Link subplan to the original decision + - [ ] No rollback needed - additive fix + - [ ] Return CorrectionResult with subplan_id + - [ ] **D4.1c** Method `identify_downstream_impact(decision_id: str) -> ImpactAnalysis`: + - [ ] Recursively find all decisions dependent on this one + - [ ] Find all subplans spawned due to this decision + - [ ] Find all artifacts created under this decision + - [ ] Return ImpactAnalysis with counts and IDs + - [ ] **D4.2** [Jeff] Implement sandbox rollback for correction: + - [ ] **D4.2a** Track sandbox state at each decision point + - [ ] **D4.2b** Store checkpoint ID with decision + - [ ] **D4.2c** Rollback sandbox to decision's checkpoint + - [ ] **D4.2d** Discard all changes made after that point + - [ ] **D4.3** [Jeff] Implement re-execution from correction point: + - [ ] **D4.3a** Resume Strategize phase from corrected decision + - [ ] **D4.3b** Use guidance as additional context for strategy actor + - [ ] **D4.3c** Let strategy actor generate new decisions from that point + - [ ] **D4.3d** Continue normal execution flow + - [ ] **D4.4** [Hamza] Implement `agents plan correct --mode=revert --guidance ""`: + - [ ] Parse arguments + - [ ] Call CorrectionService.correct_decision_revert() + - [ ] Display progress (archiving, rolling back, re-executing) + - [ ] Show diff between old and new outcomes + - [ ] Handle errors (plan already applied, decision not found) + - [ ] **D4.5** [Hamza] Implement `agents plan correct --mode=append --guidance ""`: + - [ ] Parse arguments + - [ ] Call CorrectionService.correct_decision_append() + - [ ] Show created subplan ID + - [ ] Monitor subplan progress + - [ ] Tests: Correction mechanism tests (critical for 30-day goal) + - [ ] **D4.6** [Rui] Write Behave scenarios in `features/decision_correction.feature`: + - [ ] **D4.6a** Scenario: Correct early decision re-executes downstream work + - [ ] Given a plan with 3 decisions in sequence + - [ ] When I correct the first decision with new guidance + - [ ] Then decisions 2 and 3 are regenerated + - [ ] And the new results reflect the corrected decision + - [ ] **D4.6b** Scenario: Correct decision with subplans invalidates subplans + - [ ] Given a plan with a subplan_spawn decision + - [ ] When I correct that decision + - [ ] Then the old subplan is archived + - [ ] And a new subplan is created based on new guidance + - [ ] **D4.6c** Scenario: Append mode creates fix subplan + - [ ] **D4.6d** Scenario: Cannot correct decision in Applied plan + - [ ] **D4.6e** Scenario: Correction preserves history for comparison + +- [ ] **Stage D5: Decision Persistence** (Day 18-19) **[Hamza]** - [ ] Code: Decision database schema - - [ ] Alembic migration for decisions table - - [ ] Alembic migration for decision_dependencies table - - [ ] Alembic migration for correction_attempts table - - [ ] DecisionRepository - - [ ] Location: `alembic/versions/`, `src/cleveragents/infrastructure/database/` + - [ ] **D5.1** [Hamza] Create Alembic migration for `decisions` table: + - [ ] Schema matching Decision model with all fields + - [ ] Foreign key to lifecycle_plans(plan_id) with ON DELETE CASCADE + - [ ] Self-referential FK for parent_decision_id + - [ ] Indices on plan_id, parent_decision_id, decision_type + - [ ] **D5.2** [Hamza] Create Alembic migration for `decision_dependencies` table: + - [ ] Track downstream relationships (many-to-many) + - [ ] Columns: upstream_decision_id, downstream_decision_id, dependency_type + - [ ] **D5.3** [Hamza] Create Alembic migration for `correction_attempts` table: + - [ ] Track correction history + - [ ] Columns: attempt_id, plan_id, original_decision_id, new_decision_id, status, created_at + - [ ] **D5.4** [Hamza] Create Alembic migration for `context_snapshots` table: + - [ ] Store full context snapshots for replay + - [ ] Columns: snapshot_id, hash, content (BLOB or file reference) + - [ ] **D5.5** [Hamza] Implement `DecisionRepository`: + - [ ] Standard CRUD methods + - [ ] Method `get_tree(plan_id) -> list[Decision]` - recursive query + - [ ] Method `get_downstream(decision_id) -> list[Decision]` + - [ ] Method `mark_superseded(decision_id, by_id)` - [ ] Tests: Integration tests for decision persistence + - [ ] **D5.6** [Rui] Write Behave scenarios in `features/decision_persistence.feature`: + - [ ] Scenario: Decision persists with all fields + - [ ] Scenario: Decision tree query returns correct hierarchy + - [ ] Scenario: Context snapshot stored and retrievable by hash -**M4 SUCCESS CRITERIA**: -- [ ] Decisions are recorded during Strategize -- [ ] Decision tree can be viewed via CLI -- [ ] Basic correction mechanism works (re-runs affected subtree) +**M4 SUCCESS CRITERIA** (Day 21): +- [ ] Decisions are recorded during Strategize phase with full context +- [ ] Decision tree can be viewed via `agents plan tree` command +- [ ] `agents plan explain ` shows full decision details +- [ ] Correction with `--mode=revert` rolls back and re-executes from decision point +- [ ] Correction with `--mode=append` creates fix subplan without modifying history +- [ ] Decisions persist to database and survive restart +- [ ] Context snapshots stored and retrievable for replay --- -### Section 7: Subplans & Parallelism [After M4] +### Section 7: Subplans & Parallelism [Days 12-14 + 19-20] -**Target: Milestone M5 (+18 days)** +**Target: Milestone M5 (+25 days)** -- [ ] **Stage E1: Subplan Model** (Day 13) - - [ ] Code: Extend Plan model for hierarchy - - [ ] Add parent_plan_id, root_plan_id to plan model - - [ ] Track subplan execution mode (sequential/parallel) - - [ ] Add result merging strategy per resource type - - [ ] Location: Update `src/cleveragents/domain/models/core/plan.py` - - [ ] Tests: Behave scenarios for subplan model +**CRITICAL FOR 30-DAY GOAL**: Subplans enable large project handling (e.g., converting Firefox to Rust uses hierarchical decomposition into thousands of subplans) -- [ ] **Stage E2: Subplan Spawning** (Day 14-15) - - [ ] Code: Implement subplan spawning in Execute phase - - [ ] Subplan decisions recorded during Strategize - - [ ] Subplans actually spawned during Execute - - [ ] Support sequential and parallel execution modes - - [ ] Location: `src/cleveragents/application/services/plan_lifecycle_service.py` - - [ ] Tests: Integration tests for subplan spawning +- [ ] **Stage E1: Subplan Model** (Day 12) **[Luis]** + - [ ] **E1.1** [Luis] Extend Plan model for subplan hierarchy in `src/cleveragents/domain/models/core/plan.py`: + - [ ] **E1.1a** Verify `parent_plan_id: str | None` field exists and is indexed + - [ ] **E1.1b** Verify `root_plan_id: str | None` field (always points to topmost plan) + - [ ] **E1.1c** Add `execution_mode: ExecutionMode` field: + - [ ] Enum values: SEQUENTIAL, PARALLEL, DEPENDENCY_ORDERED + - [ ] **E1.1d** Add `subplan_config: SubplanConfig | None`: + - [ ] Field `merge_strategy: MergeStrategy` - how to combine results + - [ ] Field `max_parallel: int | None` - limit concurrent subplans + - [ ] Field `fail_fast: bool` - stop all on first failure + - [ ] Field `timeout_per_subplan_seconds: int | None` + - [ ] **E1.1e** Add computed properties: + - [ ] Property `is_subplan: bool` - True if parent_plan_id is set + - [ ] Property `is_root_plan: bool` - True if root_plan_id equals plan_id + - [ ] Property `depth: int` - distance from root plan + - [ ] **E1.2** [Luis] Define `SubplanStatus` tracking model: + - [ ] Field `subplan_id: str` + - [ ] Field `action_name: str` + - [ ] Field `status: ProcessingState` + - [ ] Field `started_at: datetime | None` + - [ ] Field `completed_at: datetime | None` + - [ ] Field `error: str | None` + - [ ] Field `changeset_summary: str | None` + - [ ] **E1.3** [Luis] Define subplan failure handling rules (codify spec): + - [ ] **E1.3a** Parallel mode: other subplans continue on failure + - [ ] **E1.3b** Sequential mode: stop processing on failure + - [ ] **E1.3c** Distinguish "error" (application bug) from "failure" (tests don't pass) + - [ ] **E1.3d** Plan failures handled via retry/escalation logic + - [ ] **E1.4** [Rui] Write Behave tests for subplan model: + - [ ] Scenario: Plan with parent_plan_id has correct is_subplan property + - [ ] Scenario: Root plan computes depth=0 + - [ ] Scenario: Nested subplan computes correct depth + - [ ] Scenario: Execution mode enum validates correctly -- [ ] **Stage E3: Result Merging** (Day 16-17) - - [ ] Code: Implement result merging - - [ ] Git-style merge for code resources - - [ ] Sequential application for databases - - [ ] Pluggable merge strategies - - [ ] Location: `src/cleveragents/application/services/merge_service.py` - - [ ] Tests: Integration tests for result merging +- [ ] **Stage E2: Subplan Spawning** (Day 12-13) **[Jeff + Luis]** + - [ ] **E2.1** [Jeff] Implement subplan spawning service in `src/cleveragents/application/services/subplan_service.py`: + - [ ] **E2.1a** Method `spawn_subplan(parent_plan: Plan, decision: Decision, action_name: str, **kwargs) -> Plan`: + - [ ] Create child plan using PlanLifecycleService.use_action() + - [ ] Set parent_plan_id = parent.plan_id + - [ ] Set root_plan_id = parent.root_plan_id or parent.plan_id + - [ ] Inherit automation_level from parent + - [ ] Copy relevant context from parent (bounded to decision scope) + - [ ] Return created subplan + - [ ] **E2.1b** Method `spawn_batch(parent_plan: Plan, decisions: list[Decision]) -> list[Plan]`: + - [ ] Create multiple subplans at once + - [ ] Set appropriate execution_mode on parent + - [ ] Return all created subplans + - [ ] **E2.1c** Method `get_subplans(parent_plan_id: str) -> list[Plan]`: + - [ ] Query all direct children + - [ ] Include status information + - [ ] **E2.1d** Method `get_full_tree(root_plan_id: str) -> PlanTree`: + - [ ] Recursively fetch all descendants + - [ ] Build tree structure for visualization + - [ ] **E2.2** [Aditya] Configure strategy actor to emit subplan_spawn decisions: + - [ ] **E2.2a** Update strategy actor YAML to include subplan tools + - [ ] **E2.2b** Strategy actor can call `context.plan_subplan(action, target_files=...)` + - [ ] **E2.2c** This creates a SUBPLAN_SPAWN decision, NOT an actual plan + - [ ] **E2.2d** Decision includes: action_name, target_resources, execution_mode, estimated_scope + - [ ] **E2.3** [Jeff] Execute phase processes subplan decisions: + - [ ] **E2.3a** After strategy completes, examine all SUBPLAN_SPAWN decisions + - [ ] **E2.3b** Group decisions by execution_mode (sequential vs parallel) + - [ ] **E2.3c** For sequential: spawn → execute → wait → spawn next + - [ ] **E2.3d** For parallel: spawn all → execute all → collect results + - [ ] **E2.3e** Update decision's downstream_plan_ids with spawned plan IDs + - [ ] **E2.4** [Luis] Implement subplan status tracking: + - [ ] **E2.4a** Parent plan maintains `subplan_statuses: list[SubplanStatus]` + - [ ] **E2.4b** Subscribe to subplan state changes + - [ ] **E2.4c** Update parent when any subplan transitions + - [ ] **E2.4d** Parent enters ERRORED only if all subplans fail (parallel) or one fails (sequential) + - [ ] **E2.5** [Luis] Implement bounded context for subplans: + - [ ] **E2.5a** Subplan only sees files/resources relevant to its scope + - [ ] **E2.5b** Context computed from decision's resource_selection + - [ ] **E2.5c** Prevents subplan from seeing/modifying unrelated files + - [ ] **E2.6** [Rui] Write integration tests for subplan spawning: + - [ ] Scenario: Subplan_spawn decision creates child plan in Execute + - [ ] Scenario: Sequential subplans execute in order + - [ ] Scenario: Parallel subplans execute concurrently + - [ ] Scenario: Failed subplan in parallel allows others to finish + - [ ] Scenario: Failed subplan in sequential stops processing -- [ ] **Stage E4: Multi-Project Plans** (Day 18) - - [ ] Code: Support plans targeting multiple projects - - [ ] Plan can reference multiple projects - - [ ] Strategy clarifies which steps affect which projects - - [ ] Apply commits to each project separately - - [ ] Location: Update plan lifecycle service - - [ ] Tests: End-to-end tests for multi-project plans +- [ ] **Stage E3: Parallel Execution** (Day 19) **[Jeff + Luis]** + - [ ] **E3.1** [Jeff] Implement async subplan executor: + - [ ] **E3.1a** Use asyncio for concurrent execution + - [ ] **E3.1b** Respect max_parallel limit + - [ ] **E3.1c** Use semaphore to control concurrency + - [ ] **E3.1d** Handle timeouts per subplan + - [ ] **E3.2** [Jeff] Implement dependency-ordered execution: + - [ ] **E3.2a** Build dependency DAG from decisions + - [ ] **E3.2b** Topological sort for execution order + - [ ] **E3.2c** Execute independent subplans in parallel + - [ ] **E3.2d** Wait for dependencies before starting dependent subplans + - [ ] **E3.3** [Luis] Implement subplan isolation: + - [ ] **E3.3a** Each subplan gets its own sandbox + - [ ] **E3.3b** Subplans cannot see each other's intermediate state + - [ ] **E3.3c** Parent coordinates final merge + - [ ] **E3.4** [Rui] Write tests for parallel execution: + - [ ] Scenario: 10 independent subplans run with max_parallel=5 + - [ ] Scenario: Dependency chain executes in correct order + - [ ] Scenario: Subplan timeout triggers failure -**M5 SUCCESS CRITERIA**: -- [ ] Plans can spawn subplans -- [ ] Subplans can run in parallel -- [ ] Results from subplans are merged correctly -- [ ] Plans can target multiple projects +- [ ] **Stage E4: Result Merging** (Day 20) **[Jeff + Luis]** + - [ ] **E4.1** [Jeff] Implement merge service in `src/cleveragents/application/services/merge_service.py`: + - [ ] **E4.1a** Method `merge_subplan_results(parent: Plan, subplans: list[Plan]) -> MergeResult`: + - [ ] Collect changesets from all completed subplans + - [ ] Group changes by resource + - [ ] Detect conflicts (same file modified by multiple subplans) + - [ ] Apply merge strategy per resource type + - [ ] Return MergeResult with merged changeset and conflicts list + - [ ] **E4.2** [Jeff] Implement git-style three-way merge for code: + - [ ] **E4.2a** Use `git merge-file` or Python equivalent (diff-match-patch) + - [ ] **E4.2b** Base = original file state before any subplan + - [ ] **E4.2c** Ours = subplan A changes + - [ ] **E4.2d** Theirs = subplan B changes + - [ ] **E4.2e** Non-conflicting changes auto-merge + - [ ] **E4.2f** Conflicts marked with conflict markers + - [ ] **E4.2g** Option to escalate to user for resolution + - [ ] **E4.3** [Luis] Implement sequential merge for non-mergeable resources: + - [ ] Apply changes in subplan completion order + - [ ] Verify consistency after each application + - [ ] Rollback all if any fails + - [ ] **E4.4** [Luis] Implement post-merge validation: + - [ ] **E4.4a** Run project validation commands on merged state + - [ ] **E4.4b** If tests fail, flag for review + - [ ] **E4.4c** Option to retry with different merge strategy + - [ ] **E4.5** [Rui] Write tests for result merging: + - [ ] Scenario: Two subplans modifying different files merge cleanly + - [ ] Scenario: Two subplans modifying same file, different lines, merge cleanly + - [ ] Scenario: Two subplans modifying same lines creates conflict markers + - [ ] Scenario: Post-merge validation catches broken code + +- [ ] **Stage E5: Multi-Project Plans** (Day 25) **[Hamza]** + - [ ] **E4.1** [Hamza] Plan can reference multiple projects: + - [ ] Plan has `projects: list[str]` (project IDs) + - [ ] Each project has its own sandbox + - [ ] Subplans can target specific projects + - [ ] **E4.2** [Hamza] Strategy clarifies steps per project: + - [ ] Strategy output includes project assignment per step + - [ ] Dependency graph may span projects + - [ ] Cross-project changes coordinated + - [ ] **E4.3** [Hamza] Apply commits to each project separately: + - [ ] Each project gets separate apply operation + - [ ] Separate approval per project (if required) + - [ ] Partial apply possible (some projects succeed, others fail) + - [ ] **E4.4** [Hamza] Handle cross-project dependencies: + - [ ] If Project A change depends on Project B change: + - [ ] Apply Project B first + - [ ] Verify success + - [ ] Then apply Project A + - [ ] **E4.5** [Rui] Write end-to-end tests for multi-project: + - [ ] Scenario: Plan targets two projects + - [ ] Scenario: Changes applied to each project separately + - [ ] Scenario: Cross-project dependency handled correctly + +**M5 SUCCESS CRITERIA** (Day 25): +- [ ] Plans can spawn subplans from SUBPLAN_SPAWN decisions +- [ ] Sequential subplan execution works (execute in order) +- [ ] Parallel subplan execution works (concurrent with max_parallel limit) +- [ ] Dependency-ordered execution respects DAG +- [ ] Results from multiple subplans merge correctly using three-way merge +- [ ] Merge conflicts are marked and can be resolved +- [ ] Plans can target multiple projects with separate sandboxes +- [ ] Cross-project dependencies handled correctly +- [ ] Large task (10+ subplans) completes successfully --- -### Section 8: Server Mode [After M5] +### Section 8: Server Mode [Days 26-30] -**Target: Milestone M6 (+25 days)** +**Target: Milestone M6 (+30 days)** -- [ ] **Stage F1: Server Infrastructure** (Day 19-20) - - [ ] Code: `agents serve` command - - [ ] FastAPI server setup - - [ ] Health/version endpoints - - [ ] OpenAPI documentation - - [ ] Location: `src/cleveragents/runtime/server.py` - - [ ] Tests: Server startup/shutdown tests +- [ ] **Stage F1: Server Infrastructure** (Day 26-27) **[Luis]** + - [ ] **F1.1** [Luis] Create FastAPI server in `src/cleveragents/runtime/server.py` + - [ ] **F1.2** [Luis] Health/version endpoints + - [ ] **F1.3** [Luis] OpenAPI documentation generation + - [ ] **F1.4** [Rui] Server startup/shutdown tests -- [ ] **Stage F2: Plan Execution API** (Day 21-22) - - [ ] Code: REST API for plan lifecycle - - [ ] POST /actions - create action - - [ ] POST /plans - use action to create plan - - [ ] POST /plans/{id}/execute - execute plan - - [ ] POST /plans/{id}/apply - apply plan - - [ ] GET /plans/{id} - get plan status - - [ ] Location: `src/cleveragents/runtime/api/` - - [ ] Tests: API integration tests +- [ ] **Stage F2: Plan Execution API** (Day 27-28) **[Luis]** + - [ ] **F2.1** [Luis] POST /actions - create action + - [ ] **F2.2** [Luis] POST /plans - use action to create plan + - [ ] **F2.3** [Luis] POST /plans/{id}/execute + - [ ] **F2.4** [Luis] POST /plans/{id}/apply + - [ ] **F2.5** [Luis] GET /plans/{id} - status + - [ ] **F2.6** [Rui] API integration tests -- [ ] **Stage F3: WebSocket Streaming** (Day 23-24) - - [ ] Code: Real-time plan status streaming - - [ ] WebSocket endpoint for plan updates - - [ ] Stream phase transitions, node completions - - [ ] Location: `src/cleveragents/runtime/api/websocket.py` - - [ ] Tests: WebSocket integration tests +- [ ] **Stage F3: WebSocket Streaming** (Day 28-29) **[Luis]** + - [ ] **F3.1** [Luis] WebSocket endpoint for plan updates + - [ ] **F3.2** [Luis] Stream phase transitions, node completions + - [ ] **F3.3** [Rui] WebSocket integration tests -- [ ] **Stage F4: Remote Project Execution** (Day 25) - - [ ] Code: Execute plans on remote projects - - [ ] Server can access remote resources - - [ ] Client sends execution requests to server - - [ ] Location: Update resource service - - [ ] Tests: End-to-end tests for remote execution +- [ ] **Stage F4: Remote Project Execution** (Day 29-30) **[Hamza]** + - [ ] **F4.1** [Hamza] Server can access remote resources + - [ ] **F4.2** [Hamza] Client sends execution requests to server + - [ ] **F4.3** [Rui] End-to-end tests for remote execution **M6 SUCCESS CRITERIA**: - [ ] `agents serve` starts a working API server @@ -808,107 +2265,169 @@ Execute all required tests through the appropriate `nox` sessions—never call ` - [ ] Real-time updates via WebSocket - [ ] Remote projects can be used +**--- MERGE POINT 2: Day 30 - Large Project Autonomy Target ---** + +By Day 30, the system must be able to: +- [ ] Handle projects with 10,000+ files +- [ ] Port source code from one language to another autonomously +- [ ] Use hierarchical subplans for large tasks +- [ ] Correct decisions without full re-execution + --- -### Section 9: Full Feature Set [After M6] +### Section 9: Full Feature Set [Days 31-35] **Target: Milestone M7 (+35 days)** -- [ ] **Stage G1: Automation Levels** (Day 26-27) - - [ ] Code: Implement automation level support - - [ ] Manual: User prompted for each decision - - [ ] Show context, alternatives, recommendation - - [ ] Accept explicit choice or custom guidance - - [ ] Record user decisions in decision tree - - [ ] Review-before-apply: Auto decisions, user reviews before Apply - - [ ] AI makes all decisions autonomously - - [ ] Execution completes in sandbox - - [ ] Human reviews complete diff before apply - - [ ] User can approve, reject, or correct specific decisions - - [ ] Full automation: All decisions automatic - - [ ] AI makes all decisions - - [ ] Execution proceeds through apply - - [ ] Human notified of completion - - [ ] Rollback available if issues detected - - [ ] Configurable per plan/session/global - - [ ] Progressive trust building: - - [ ] Track decision success rates - - [ ] Build codebase familiarity scores - - [ ] Confidence-based escalation even in full auto mode - - [ ] Semantic understanding of when to escalate - - [ ] Location: Update plan lifecycle service - - [ ] Tests: Tests for each automation level - - [ ] Tests: Confidence-based escalation scenarios - - [ ] Tests: Progressive automation upgrade paths +- [ ] **Stage G1: Automation Levels Enhancement** (Day 31-32) **[Luis]** + - [ ] **G1.1** [Luis] Full manual mode with decision prompts: + - [ ] Every decision point pauses for human input + - [ ] Display context, alternatives considered, recommendation + - [ ] Accept explicit choice or custom guidance + - [ ] Record user decisions in decision tree + - [ ] **G1.2** [Luis] Review-before-apply with diff display: + - [ ] AI makes all decisions autonomously during Strategize + - [ ] Execution completes in sandbox + - [ ] Human reviews complete diff before apply: + - [ ] Show changed files summary + - [ ] Show full unified diff with syntax highlighting + - [ ] Show risk warnings (auth code, migrations, etc.) + - [ ] User can approve, reject, or correct specific decisions + - [ ] **G1.3** [Luis] Full automation with confidence escalation: + - [ ] AI makes all decisions autonomously + - [ ] Execution proceeds through apply without pause + - [ ] Human notified of completion + - [ ] Rollback available if issues detected post-apply + - [ ] EVEN in full automation, critical decisions escalate: + - [ ] If confidence below threshold, request human guidance + - [ ] If touching critical files (defined by project), escalate + - [ ] If cost exceeds budget, escalate + - [ ] **G1.4** [Luis] Progressive trust building (track success rates): + - [ ] Track decision success rates per decision type + - [ ] Track codebase familiarity scores per project + - [ ] Confidence increases with successful history + - [ ] Allow automatic upgrade: manual -> review -> full + - [ ] After N successful plans in manual, suggest review mode + - [ ] After N successful plans in review, suggest full mode + - [ ] **G1.5** [Luis] Implement `AutonomyController` class: + - [ ] Method `assess_decision_confidence(decision, context) -> float` + - [ ] Method `should_escalate(decision, confidence, automation_level) -> bool` + - [ ] Method `get_historical_success(decision_type) -> float` + - [ ] Method `get_familiarity_score(project) -> float` + - [ ] **G1.6** [Rui] Tests for each automation level: + - [ ] Scenario: Manual mode pauses at each decision + - [ ] Scenario: Review-before-apply shows diff before apply + - [ ] Scenario: Full automation completes without pause + - [ ] Scenario: Low confidence in full automation escalates + - [ ] Scenario: Progressive trust upgrade suggestion shown -- [ ] **Stage G2: Checkpointing & Rollback** (Day 28-29) - - [ ] Code: Enhanced checkpointing - - [ ] Skill-level checkpointability declarations - - [ ] Plan-level rollback policy - - [ ] Rollback to checkpoint command - - [ ] Location: `src/cleveragents/infrastructure/checkpoint/` - - [ ] Tests: Checkpoint/rollback tests +- [ ] **Stage G2: Checkpointing & Rollback** (Day 32-33) **[Luis]** + - [ ] **G2.1** [Luis] Skill-level checkpoint declarations + - [ ] **G2.2** [Luis] Plan-level rollback policy + - [ ] **G2.3** [Luis] Rollback to checkpoint command + - [ ] **G2.4** [Rui] Checkpoint/rollback tests -- [ ] **Stage G2.5: Semantic Validation Framework** (Day 29-30) - - [ ] Code: Multi-layer semantic error prevention - - [ ] Decision-time validation in Strategize - - [ ] Alternatives evaluation with confidence scores - - [ ] Validation checks before committing to decision - - [ ] Execution-time semantic guards - - [ ] API compatibility checking - - [ ] Breaking change detection - - [ ] Auto-migration generation where possible - - [ ] Invariant enforcement system - - [ ] User-defined invariants - - [ ] Invariant checking during execution - - [ ] Violation handling and recovery - - [ ] Error pattern database - - [ ] Learn from historical failures - - [ ] Predictive error prevention - - [ ] Pattern matching for known issues - - [ ] Location: `src/cleveragents/application/services/semantic_validation_service.py` - - [ ] Tests: Semantic validation scenarios - - [ ] Tests: Invariant violation detection - - [ ] Tests: Error pattern learning +- [ ] **Stage G3: Semantic Validation Framework** (Day 33-34) **[Luis]** + - [ ] **G3.1** [Luis] Decision-time validation in Strategize: + - [ ] Every decision includes semantic validation + - [ ] Record `validation_performed` list on each decision + - [ ] Validate chosen option against alternatives + - [ ] Check for breaking changes, compatibility issues + - [ ] **G3.2** [Luis] Execution-time semantic guards: + - [ ] Actor configs can include validation nodes + - [ ] `validate_api_compatibility` - check for breaking API changes + - [ ] `validate_type_safety` - check types are preserved + - [ ] `auto_migrate` - generate migration plan for breaking changes + - [ ] Guards can auto-fix simple issues or escalate complex ones + - [ ] **G3.3** [Luis] Invariant enforcement system: + - [ ] User-defined invariants per project (see Section 15) + - [ ] Check invariants at each major step + - [ ] Fail execution on violation (if severity=error) + - [ ] Record invariant check results in plan metadata + - [ ] **G3.4** [Luis] Error pattern database: + - [ ] Store historical failures with context + - [ ] Identify patterns: "Async conversion in X module often causes Y" + - [ ] Before execution, check for known patterns + - [ ] Add preventive checks based on patterns + - [ ] Learn from successful corrections + - [ ] **G3.5** [Luis] Implement `SemanticValidationService`: + - [ ] Method `validate_decision(decision) -> ValidationResult` + - [ ] Method `check_invariants(project, changes) -> list[InvariantResult]` + - [ ] Method `check_error_patterns(context) -> list[PatternMatch]` + - [ ] Method `suggest_preventive_checks(pattern) -> list[Check]` + - [ ] **G3.6** [Rui] Semantic validation tests: + - [ ] Scenario: Decision with breaking API change is flagged + - [ ] Scenario: Invariant violation detected during execution + - [ ] Scenario: Known error pattern triggers preventive check -- [ ] **Stage G3: Context Tiers** (Day 30-31) - - [ ] Code: Hot/warm/cold context management - - [ ] Hot context: immediate LLM access (10-20 files for active work) - - [ ] Warm context: quick retrieval - - [ ] Recent decisions from current plan tree - - [ ] Indexed embeddings and vector search results - - [ ] Decision chain that led to current work - - [ ] Cold context: archived/compressed - - [ ] Historical decisions from past plans - - [ ] Past refactoring patterns - - [ ] Cross-project learnings - - [ ] Per-actor context views - - [ ] Strategist: architecture docs, READMEs, module boundaries - - [ ] Executor: precise code sections for edits - - [ ] Reviewer: diffs, tests, risk zones - - [ ] Promotion/demotion algorithms - - [ ] Context locality preservation for massive codebases - - [ ] Location: `src/cleveragents/application/services/context_tier_service.py` - - [ ] Tests: Context tier tests - - [ ] Tests: Large codebase simulation (50k+ files) - - [ ] Tests: Context view filtering by actor type +- [ ] **Stage G4: Context Tiers** (Day 34-35) **[Hamza]** + - [ ] **G4.1** [Hamza] Hot context management (10-20 files): + - [ ] Track files currently in LLM context window + - [ ] Implement LRU eviction when context limit reached + - [ ] Prioritize files based on current task relevance + - [ ] Support explicit pinning of critical files + - [ ] **G4.2** [Hamza] Warm context with vector search: + - [ ] Recent decisions and their contexts from current plan tree + - [ ] Indexed embeddings from project files + - [ ] Vector search results for quick retrieval + - [ ] Decision chain that led to current work + - [ ] **G4.3** [Hamza] Cold context for historical decisions: + - [ ] Historical decisions from past plans on this codebase + - [ ] Past refactoring patterns ("last time we did X...") + - [ ] Cross-project learnings (if enabled) + - [ ] Queryable but not in active memory + - [ ] **G4.4** [Hamza] Per-actor context views: + - [ ] Implement `ActorContextView` service + - [ ] Strategist view: architecture docs, READMEs, module boundaries, dependency graphs + - [ ] Executor view: precise code sections for edits, test files + - [ ] Reviewer view: diffs, tests, risk zones, style guides + - [ ] Each actor gets filtered view based on role + - [ ] **G4.5** [Hamza] Implement promotion/demotion algorithms: + - [ ] Analyze current query/task + - [ ] Promote relevant data upward (cold -> warm -> hot) + - [ ] Demote stale data out of hot to keep prompts tight + - [ ] Preserve complete context snapshots for every decision + - [ ] **G4.6** [Rui] Context tier tests: + - [ ] Scenario: Hot context respects file limit + - [ ] Scenario: Warm context includes recent decisions + - [ ] Scenario: Actor receives role-appropriate context view + - [ ] Scenario: Promotion moves relevant cold data to warm -- [ ] **Stage G4: Cost & Risk Estimation** (Day 32-33) - - [ ] Code: Optional estimation actor - - [ ] Analyze strategy output - - [ ] Estimate tokens/cost/time - - [ ] Provide risk assessment - - [ ] Location: `src/cleveragents/agents/estimation.py` - - [ ] Tests: Estimation accuracy tests +- [ ] **Stage G5: Cost & Risk Estimation** (Day 35) **[Hamza]** + - [ ] **G5.1** [Hamza] Estimation actor implementation: + - [ ] Create optional `estimation_actor` role in action model + - [ ] Estimation actor runs after Strategize completes, before Execute + - [ ] Input: strategy output, project context + - [ ] Output: cost estimate, risk assessment, time estimate + - [ ] **G5.2** [Hamza] Token/cost estimation: + - [ ] Analyze strategy to estimate number of LLM calls + - [ ] Estimate tokens per call based on context size + - [ ] Map model costs to get dollar estimate + - [ ] Estimate number of steps/subplans + - [ ] Provide confidence interval (min/expected/max) + - [ ] **G5.3** [Hamza] Risk assessment: + - [ ] Analyze strategy for risky operations: + - [ ] Touching auth/security code + - [ ] Database migrations + - [ ] Public API changes + - [ ] Infrastructure changes + - [ ] Calculate risk score (low/medium/high) + - [ ] Identify specific risk factors + - [ ] Estimate likelihood of rollback needed + - [ ] **G5.4** [Hamza] Display estimation before execute: + - [ ] Show estimated cost before user confirms execute + - [ ] Show risk assessment summary + - [ ] Allow user to abort if cost too high + - [ ] **G5.5** [Rui] Estimation tests: + - [ ] Scenario: Estimation actor produces cost estimate + - [ ] Scenario: High-risk strategy flagged appropriately + - [ ] Scenario: User can abort based on estimate -- [ ] **Stage G5: Full CLI Polish** (Day 34-35) - - [ ] Code: Complete CLI refinement - - [ ] Consistent help text across all commands - - [ ] Rich terminal output throughout - - [ ] Progress indicators for all long operations - - [ ] Error messages with recovery suggestions - - [ ] Tests: CLI UX tests - - [ ] Document: Complete user documentation +- [ ] **Stage G6: Full CLI Polish** (Day 35) **[All]** + - [ ] **G6.1** [All] Consistent help text + - [ ] **G6.2** [All] Rich terminal output + - [ ] **G6.3** [All] Progress indicators + - [ ] **G6.4** [All] Error messages with recovery suggestions **M7 SUCCESS CRITERIA**: - [ ] All spec features implemented @@ -918,35 +2437,583 @@ Execute all required tests through the appropriate `nox` sessions—never call ` --- -### Section 10: Async Infrastructure & Quality [Ongoing] +### Section 10: Async Infrastructure & Quality [Ongoing - Brent Lead] -- [ ] **Stage 8: Async Infrastructure** (Parallel with above) - - [ ] Implement async command execution (asyncio per ADR-002) - - [X] Implement the 33 retry patterns with tenacity (COMPLETED 2025-11-17) - - [X] Add circuit breaker for failures (COMPLETED 2025-11-17) - - [ ] Add background workers (convert 7 concurrency patterns to asyncio tasks) - - [ ] Integrate retry patterns into services +**[Brent - Detail Oriented, Low Contention Work]** -- [ ] **Stage 11: ADR Alignment Verification** - - [ ] Verify all 11 ADRs are followed in implementation - - [ ] ADR-001 through ADR-011 compliance check +This section runs in parallel throughout the project with Brent working independently. -- [ ] **Stage 12: Quality Metrics** - - [ ] 100% type coverage (no `Any` types) - - [ ] 85%+ test coverage maintained - - [ ] All 11 ADRs followed - - [ ] Zero linting errors (Ruff) - - [ ] Zero type errors (pyright) - - [ ] Performance targets met +- [ ] **Stage 8: Async Infrastructure** + - [ ] **8.1** [Brent] Implement async command execution (asyncio per ADR-002) + - [X] **8.2** Implement the 33 retry patterns with tenacity (COMPLETED 2025-11-17) + - [X] **8.3** Add circuit breaker for failures (COMPLETED 2025-11-17) + - [ ] **8.4** [Brent] Add background workers (convert 7 concurrency patterns to asyncio tasks) + - [ ] **8.5** [Brent] Integrate retry patterns into new services + +- [ ] **Stage 9: Code Review All Workstreams** **[Brent - Continuous]** + - [ ] **9.1** [Brent] Review all Plan Lifecycle PRs (Workstream A) + - [ ] **9.2** [Brent] Review all Projects & Resources PRs (Workstream B) + - [ ] **9.3** [Brent] Review all Actors & Skills PRs (Workstream C) + - [ ] **9.4** [Brent] Review Decision Tree PRs + - [ ] **9.5** [Brent] Review Server Mode PRs + +- [ ] **Stage 10: Linting & Type Checking Enforcement** **[Brent - Continuous]** + - [ ] **10.1** [Brent] Run `nox -s lint` after each PR merge, fix any issues + - [ ] **10.2** [Brent] Run `nox -s typecheck` after each PR merge, fix any issues + - [ ] **10.3** [Brent] Ensure zero Ruff warnings at all times + - [ ] **10.4** [Brent] Ensure zero pyright errors at all times + - [ ] **10.5** [Brent] Update type annotations as code evolves + +- [ ] **Stage 11: ADR Alignment Verification** **[Brent]** + - [ ] **11.1** [Brent] Verify ADR-001 (Package Layering) compliance + - [ ] **11.2** [Brent] Verify ADR-002 (Asyncio) compliance + - [ ] **11.3** [Brent] Verify ADR-003 (DI) compliance + - [ ] **11.4** [Brent] Verify ADR-004 (Pydantic) compliance + - [ ] **11.5** [Brent] Verify ADR-005 (Error Handling) compliance + - [ ] **11.6** [Brent] Verify ADR-006 (Environment Variables) compliance + - [ ] **11.7** [Brent] Verify ADR-007 (Repository Pattern) compliance + - [ ] **11.8** [Brent] Verify ADR-008 (Provider Plugin) compliance + - [ ] **11.9** [Brent] Verify ADR-009 (CLI Framework) compliance + - [ ] **11.10** [Brent] Verify ADR-010 (Logging) compliance + - [ ] **11.11** [Brent] Verify ADR-011 (LangGraph Integration) compliance + +- [ ] **Stage 12: Quality Metrics Maintenance** **[Brent - Weekly]** + - [ ] **12.1** [Brent] Maintain 100% type coverage (no `Any` types) + - [ ] **12.2** [Brent] Maintain 85%+ test coverage + - [ ] **12.3** [Brent] Zero linting errors + - [ ] **12.4** [Brent] Zero type errors + - [ ] **12.5** [Brent] Performance benchmarking (weekly) + +- [ ] **Stage 13: Documentation Review** **[Brent]** + - [ ] **13.1** [Brent] Review all docstrings for accuracy + - [ ] **13.2** [Brent] Review README.md + - [ ] **13.3** [Brent] Review actor configuration docs + - [ ] **13.4** [Brent] Review CLI help text consistency --- -### Section 11: Deferred Work +### Section 11: Security & Safety [WORKSTREAM F - Luis + Brent] -The following items from the previous implementation plan are deferred or no longer applicable: +**Target: Throughout project, critical items by Day 14** + +**CRITICAL SECURITY BLOCKERS** (Must be addressed before any production use) + +- [ ] **Stage SEC1: Remove eval() Vulnerability** (Day 1-2) **[Luis - CRITICAL]** + - [ ] Code: Remove all eval() from config parsing + - [ ] **SEC1.1** [Luis] Audit all files for `eval()` usage in `src/cleveragents/`: + - [ ] Search for `eval(`, `exec(`, `compile(` calls + - [ ] Document each occurrence with file path and line number + - [ ] Classify as: (a) test-only, (b) removable, (c) requires redesign + - [ ] **SEC1.2** [Luis] Replace eval-based config transforms: + - [ ] Create whitelist of allowed transform operators + - [ ] Implement safe expression parser (no arbitrary code execution) + - [ ] Or: transforms must reference named functions from a registry + - [ ] **SEC1.3** [Luis] Remove eval from reactive routing config: + - [ ] Audit `src/cleveragents/reactive/config_parser.py` + - [ ] Replace dynamic code execution with safe alternatives + - [ ] **SEC1.4** [Brent] Code review all eval removal changes + - [ ] Tests: Security tests + - [ ] **SEC1.5** [Rui] Write Behave scenarios in `features/security_eval.feature`: + - [ ] Scenario: Config with code injection attempt is rejected + - [ ] Scenario: Malicious transform expression does not execute + - [ ] Scenario: Valid config still works after eval removal + +- [ ] **Stage SEC2: Template Injection Prevention** (Day 3-4) **[Luis]** + - [ ] Code: Secure template rendering + - [ ] **SEC2.1** [Luis] Replace `str.format()` with safe template engine: + - [ ] Use Jinja2 with sandboxed environment + - [ ] Or: restrict token set severely (only `{variable}` substitution) + - [ ] Prevent access to `__class__`, `__globals__`, etc. + - [ ] **SEC2.2** [Luis] Implement input sanitization for prompts: + - [ ] Treat user input as data, not instruction overrides + - [ ] Escape special characters in user-provided text + - [ ] Strict role separation in prompts (system vs user) + - [ ] **SEC2.3** [Luis] Add prompt injection mitigations: + - [ ] Detect common injection patterns + - [ ] Warn or reject suspicious inputs + - [ ] Log potential injection attempts + - [ ] Tests: Template security tests + - [ ] **SEC2.4** [Rui] Write Behave scenarios in `features/security_templates.feature`: + - [ ] Scenario: Template with Jinja2 injection attempt fails safely + - [ ] Scenario: User input with special characters is escaped + - [ ] Scenario: Prompt injection attempt is detected + +- [ ] **Stage SEC3: Exception Handling Audit** (Day 4-5) **[Brent]** + - [ ] Code: Stop swallowing exceptions + - [ ] **SEC3.1** [Brent] Audit all try/except blocks in `src/cleveragents/`: + - [ ] Find bare `except:` or `except Exception:` that silently continue + - [ ] Document each occurrence + - [ ] **SEC3.2** [Brent] Fix silent exception handling: + - [ ] Capture exception details + - [ ] Attach to message metadata or error state + - [ ] Fail the stream/plan with clear error state + - [ ] Log at appropriate level (error, not debug) + - [ ] **SEC3.3** [Brent] Add error context propagation: + - [ ] Errors should include stack trace reference + - [ ] Errors should identify the component that failed + - [ ] Errors should suggest recovery actions where possible + - [ ] Tests: Exception handling tests + - [ ] **SEC3.4** [Rui] Write Behave scenarios in `features/security_exceptions.feature`: + - [ ] Scenario: Component failure surfaces as clear error + - [ ] Scenario: Error includes actionable information + - [ ] Scenario: No silent failures in normal operation + +- [ ] **Stage SEC4: Async Lifecycle Correctness** (Day 5-6) **[Brent]** + - [ ] Code: Fix async resource leaks + - [ ] **SEC4.1** [Brent] Audit event loop usage: + - [ ] Find all `asyncio.new_event_loop()` calls + - [ ] Ensure loops are properly closed + - [ ] Prefer `asyncio.run()` or managed loop policy + - [ ] **SEC4.2** [Brent] Fix RxPy subscription leaks: + - [ ] Ensure subscriptions are disposed on shutdown + - [ ] Dispose subscriptions on stream reconfiguration + - [ ] Track active subscriptions for debugging + - [ ] **SEC4.3** [Brent] Fix LangGraph checkpoint file leaks: + - [ ] Audit checkpoint file creation + - [ ] Implement cleanup for old checkpoint files + - [ ] Add retention policy for checkpoints + - [ ] Tests: Resource leak tests + - [ ] **SEC4.4** [Rui] Write Behave scenarios in `features/security_async.feature`: + - [ ] Scenario: Long-running process does not leak memory + - [ ] Scenario: Shutdown cleans up all subscriptions + - [ ] Scenario: Checkpoint files cleaned after retention period + +- [ ] **Stage SEC5: Secrets Management** (Day 6-7) **[Hamza]** + - [ ] Code: Secure credential handling + - [ ] **SEC5.1** [Hamza] Implement secrets masking in logs: + - [ ] Detect API keys in log output + - [ ] Mask sensitive values (show only last 4 chars) + - [ ] Never log full credentials + - [ ] **SEC5.2** [Hamza] Secure environment variable handling: + - [ ] Validate API key format before use + - [ ] Clear error if required key missing + - [ ] Support secrets from file (for containerized environments) + - [ ] **SEC5.3** [Hamza] Prevent secrets in generated code: + - [ ] Detect hardcoded API keys in LLM output + - [ ] Warn if generated code contains potential secrets + - [ ] Block apply if secrets detected without override + - [ ] Tests: Secrets management tests + - [ ] **SEC5.4** [Rui] Write Behave scenarios in `features/security_secrets.feature`: + - [ ] Scenario: API key in log output is masked + - [ ] Scenario: Generated code with hardcoded key is flagged + - [ ] Scenario: Missing API key produces clear error + +- [ ] **Stage SEC6: Read-Only Action Enforcement** (Day 7-8) **[Luis]** + - [ ] Code: Enforce read_only actions + - [ ] **SEC6.1** [Luis] Add skill metadata validation at execution time: + - [ ] Check if action has `read_only: true` + - [ ] If read_only, verify all skills have `read_only: true` metadata + - [ ] Block execution if write skill detected in read-only action + - [ ] **SEC6.2** [Luis] Implement safety profile validation: + - [ ] Action can specify `safety_profile` with: + - [ ] `allowed_skill_categories: list[str]` + - [ ] `require_checkpoints: bool` + - [ ] `require_sandbox: bool` + - [ ] `require_human_approval: bool` + - [ ] Enforce safety profile at execution time + - [ ] Tests: Safety enforcement tests + - [ ] **SEC6.3** [Rui] Write Behave scenarios in `features/security_readonly.feature`: + - [ ] Scenario: Read-only action blocked from using write skill + - [ ] Scenario: Safety profile with require_sandbox enforced + - [ ] Scenario: Safety profile with require_checkpoints enforced + +- [ ] **Stage SEC7: Audit Logging** (Day 8-9) **[Hamza]** + - [ ] Code: Comprehensive audit trail + - [ ] **SEC7.1** [Hamza] Implement apply audit logging: + - [ ] Record who applied, what changed, when, why + - [ ] Include plan ID, action ID, project ID + - [ ] Include changeset summary (files affected) + - [ ] Store in audit table with retention policy + - [ ] **SEC7.2** [Hamza] Create Alembic migration for `audit_log` table: + - [ ] Schema: `audit_id`, `event_type`, `user_id`, `plan_id`, `details`, `created_at` + - [ ] Index on `event_type`, `plan_id`, `created_at` + - [ ] **SEC7.3** [Hamza] Implement `agents audit list` CLI command: + - [ ] List recent audit events + - [ ] Filter by event type, plan, date range + - [ ] Tests: Audit logging tests + - [ ] **SEC7.4** [Rui] Write Behave scenarios in `features/security_audit.feature`: + - [ ] Scenario: Apply creates audit log entry + - [ ] Scenario: Audit log queryable by plan ID + - [ ] Scenario: Audit list CLI shows recent events + +--- + +### Section 12: Session & Provider Fixes [WORKSTREAM G - Hamza] + +**Target: Days 8-12** + +- [ ] **Stage SESS1: Session Management** (Day 8-9) **[Hamza]** + - [ ] Code: Implement stable session persistence + - [ ] **SESS1.1** [Hamza] Define `Session` model in `src/cleveragents/domain/models/core/session.py`: + - [ ] Field `session_id: str` - ULID identifier + - [ ] Field `user_id: str | None` - optional user identity + - [ ] Field `automation_level: AutomationLevel` - session-level setting + - [ ] Field `current_plan_id: str | None` - active plan + - [ ] Field `plan_history: list[str]` - recent plan IDs + - [ ] Field `created_at: datetime` + - [ ] Field `last_active_at: datetime` + - [ ] Field `metadata: dict[str, Any]` - extensible metadata + - [ ] **SESS1.2** [Hamza] Create `SessionService` in `src/cleveragents/application/services/session_service.py`: + - [ ] Method `create_session() -> Session` - create new session with ULID + - [ ] Method `get_session(session_id: str) -> Session | None` + - [ ] Method `get_or_create_session() -> Session` - resume or create + - [ ] Method `update_activity(session_id: str) -> None` - touch last_active_at + - [ ] Method `set_current_plan(session_id: str, plan_id: str) -> None` + - [ ] Method `set_automation_level(session_id: str, level: AutomationLevel) -> None` + - [ ] **SESS1.3** [Hamza] Create Alembic migration for `sessions` table: + - [ ] Schema matching Session model + - [ ] Index on `last_active_at` for cleanup queries + - [ ] **SESS1.4** [Hamza] Implement session persistence across CLI invocations: + - [ ] Store session ID in `~/.cleveragents/session` + - [ ] Resume session on CLI startup if exists + - [ ] Clear session file on `agents session end` command + - [ ] **SESS1.5** [Hamza] Add session CLI commands: + - [ ] `agents session start` - create new session explicitly + - [ ] `agents session end` - end current session + - [ ] `agents session set automation-level ` - set session automation + - [ ] `agents session info` - show current session details + - [ ] Tests: Session tests + - [ ] **SESS1.6** [Rui] Write Behave scenarios in `features/session_management.feature`: + - [ ] Scenario: Session persists across CLI invocations + - [ ] Scenario: Session automation level overrides global + - [ ] Scenario: Session end clears session state + - [ ] Scenario: New CLI invocation resumes existing session + +- [ ] **Stage SESS2: Memory Service Persistence** (Day 9-10) **[Hamza]** + - [ ] Code: Fix memory loss between invocations + - [ ] **SESS2.1** [Hamza] Update `MemoryService` to use session-based storage: + - [ ] Store conversation history keyed by session_id + - [ ] Load history on session resume + - [ ] Support configurable history limits + - [ ] **SESS2.2** [Hamza] Create Alembic migration for `conversation_history` table: + - [ ] Schema: `history_id`, `session_id`, `plan_id`, `role`, `content`, `created_at` + - [ ] Foreign key to sessions + - [ ] Index on `session_id`, `plan_id` + - [ ] **SESS2.3** [Hamza] Add explicit memory configuration: + - [ ] `CLEVERAGENTS_MEMORY_BACKEND=sqlite|redis|memory` + - [ ] Document that `memory` backend loses history between invocations + - [ ] Default to `sqlite` for persistence + - [ ] **SESS2.4** [Hamza] Surface warning if memory not persistent: + - [ ] On first CLI invocation, warn if memory backend is `memory` + - [ ] Suggest configuring persistent backend + - [ ] Tests: Memory persistence tests + - [ ] **SESS2.5** [Rui] Write Behave scenarios in `features/memory_persistence.feature`: + - [ ] Scenario: Conversation history survives CLI restart + - [ ] Scenario: Memory backend warning shown for in-memory mode + - [ ] Scenario: Plan-specific memory isolated from other plans + +- [ ] **Stage PROV1: Provider Fixes** (Day 10-11) **[Luis]** + - [ ] Code: Fix provider issues + - [ ] **PROV1.1** [Luis] Remove FakeListLLM as default behavior: + - [ ] Audit where FakeListLLM is used outside tests + - [ ] Ensure production code never falls back to FakeListLLM + - [ ] If no provider configured, fail fast with clear message: + ``` + Error: No LLM provider configured. + Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or configure an actor. + See: agents help providers + ``` + - [ ] **PROV1.2** [Luis] Fix auto-debug hardcoded provider: + - [ ] Auto-debug currently hardcoded to OpenAI GPT-4 + - [ ] Change to use configured default actor + - [ ] Or: use action/actor system (auto-debug is just an action) + - [ ] **PROV1.3** [Luis] Verify OpenRouter implementation: + - [ ] OpenRouter listed in spec but may not be fully implemented + - [ ] Test OpenRouter adapter with real API + - [ ] Fix any issues found + - [ ] **PROV1.4** [Luis] Implement provider auto-detection: + - [ ] On startup, detect which API keys are configured + - [ ] Register only available providers + - [ ] Clear message about which providers are available: + ``` + Available providers: openai (gpt-4, gpt-3.5-turbo), anthropic (claude-3-opus) + Missing: google (GEMINI_API_KEY not set) + ``` + - [ ] Tests: Provider tests + - [ ] **PROV1.5** [Rui] Write Behave scenarios in `features/provider_fixes.feature`: + - [ ] Scenario: No provider configured produces clear error + - [ ] Scenario: Auto-debug uses configured actor not hardcoded + - [ ] Scenario: Provider detection shows available providers + - [ ] Scenario: FakeListLLM only used in test mode + +- [ ] **Stage PROV2: Provider Fallback & Cost Controls** (Day 11-12) **[Luis]** + - [ ] Code: Implement cost controls and fallback + - [ ] **PROV2.1** [Luis] Add token tracking per plan: + - [ ] Track input tokens, output tokens per LLM call + - [ ] Aggregate by plan, phase, actor + - [ ] Store in plan metadata + - [ ] **PROV2.2** [Luis] Add cost estimation: + - [ ] Map model to token cost ($ per 1K tokens) + - [ ] Calculate estimated cost per call + - [ ] Aggregate plan total cost + - [ ] **PROV2.3** [Luis] Implement budget limits: + - [ ] Per-plan max cost limit + - [ ] Per-session max cost limit + - [ ] Global max cost limit + - [ ] Warn when approaching limit, fail when exceeded + - [ ] **PROV2.4** [Luis] Implement rate limiting: + - [ ] Per-actor max calls per minute + - [ ] Per-plan max retries + - [ ] Exponential backoff on rate limit errors + - [ ] **PROV2.5** [Luis] Implement provider fallback: + - [ ] If primary provider fails, try fallback provider + - [ ] Configurable fallback order + - [ ] Log fallback events + - [ ] Tests: Cost control tests + - [ ] **PROV2.6** [Rui] Write Behave scenarios in `features/cost_controls.feature`: + - [ ] Scenario: Plan cost tracked and reported + - [ ] Scenario: Plan exceeding budget limit fails + - [ ] Scenario: Rate limit triggers exponential backoff + - [ ] Scenario: Provider fallback on transient failure + +--- + +### Section 13: Additional CLI Commands & UX [Days 10-14] + +**Commands missing from initial plan** + +- [ ] **Stage CLI1: Plan Interaction Commands** (Day 10-11) **[Hamza]** + - [ ] Code: Implement additional plan commands + - [ ] **CLI1.1** [Hamza] Implement `agents plan prompt ""`: + - [ ] Provide additional instructions to a stuck plan + - [ ] Works when plan is in errored state + - [ ] Resumes execution with new guidance + - [ ] **CLI1.2** [Hamza] Implement `agents plan diff `: + - [ ] Show diff of changes made by plan + - [ ] Works for plans in Execute or Apply phase + - [ ] Color-coded unified diff output + - [ ] **CLI1.3** [Hamza] Implement `agents plan diff `: + - [ ] Compare old vs new after correction + - [ ] Show what changed between correction attempts + - [ ] **CLI1.4** [Hamza] Implement `agents plan artifacts `: + - [ ] List all artifacts produced by plan + - [ ] Show file paths, operation types, sizes + - [ ] Tests: Plan interaction CLI tests + - [ ] **CLI1.5** [Rui] Write Behave scenarios in `features/plan_interaction_cli.feature`: + - [ ] Scenario: Plan prompt resumes stuck plan + - [ ] Scenario: Plan diff shows color-coded output + - [ ] Scenario: Correction diff comparison works + +- [ ] **Stage CLI2: Configuration Commands** (Day 11-12) **[Hamza]** + - [ ] Code: Implement config commands + - [ ] **CLI2.1** [Hamza] Implement `agents config set `: + - [ ] Set global configuration values + - [ ] Supported keys: `automation-level`, `default-actor`, `log-level` + - [ ] Persist to `~/.cleveragents/config.toml` + - [ ] **CLI2.2** [Hamza] Implement `agents config get `: + - [ ] Get current configuration value + - [ ] Show source (default, file, environment) + - [ ] **CLI2.3** [Hamza] Implement `agents config list`: + - [ ] List all configuration values + - [ ] Show current value and source + - [ ] **CLI2.4** [Hamza] Implement `agents providers list`: + - [ ] List available providers + - [ ] Show which are configured vs missing API keys + - [ ] Tests: Config CLI tests + - [ ] **CLI2.5** [Rui] Write Behave scenarios in `features/config_cli.feature`: + - [ ] Scenario: Config set persists value + - [ ] Scenario: Config get shows current value + - [ ] Scenario: Providers list shows available/missing + +--- + +### Section 14: Concurrency & Cleanup [Days 12-14] + +- [ ] **Stage CONC1: Plan Locking** (Day 12) **[Luis]** + - [ ] Code: Prevent concurrent plan modification + - [ ] **CONC1.1** [Luis] Implement plan-level locking: + - [ ] Database row lock on plan during execution + - [ ] Or: advisory lock using plan_id + - [ ] Prevent two processes from executing same plan + - [ ] **CONC1.2** [Luis] Implement project-level locking: + - [ ] Lock project during apply (can't apply two plans to same project) + - [ ] Allow parallel plans in different sandboxes + - [ ] **CONC1.3** [Luis] Add lock timeout and retry: + - [ ] Configurable lock wait timeout + - [ ] Clear error if lock cannot be acquired + - [ ] Tests: Concurrency tests + - [ ] **CONC1.4** [Rui] Write Behave scenarios in `features/concurrency.feature`: + - [ ] Scenario: Two processes cannot execute same plan + - [ ] Scenario: Two applies to same project blocked + - [ ] Scenario: Lock timeout produces clear error + +- [ ] **Stage CONC2: Resumable Execution** (Day 12-13) **[Luis]** + - [ ] Code: Implement plan resume capability + - [ ] **CONC2.1** [Luis] Persist step-level progress: + - [ ] Record each completed step in plan + - [ ] Store intermediate state for resume + - [ ] **CONC2.2** [Luis] Implement `agents plan resume `: + - [ ] Detect where plan was interrupted + - [ ] Resume from last completed step + - [ ] Restore sandbox state + - [ ] **CONC2.3** [Luis] Handle graceful shutdown: + - [ ] On SIGINT/SIGTERM, save progress before exit + - [ ] Mark plan as "interrupted" not "errored" + - [ ] Tests: Resume tests + - [ ] **CONC2.4** [Rui] Write Behave scenarios in `features/plan_resume.feature`: + - [ ] Scenario: Interrupted plan can be resumed + - [ ] Scenario: Resume continues from correct step + - [ ] Scenario: Graceful shutdown saves progress + +- [ ] **Stage CONC3: Garbage Collection** (Day 13-14) **[Brent]** + - [ ] Code: Cleanup abandoned resources + - [ ] **CONC3.1** [Brent] Implement sandbox garbage collection: + - [ ] On startup, find orphaned sandbox directories + - [ ] Clean sandboxes from crashed processes + - [ ] Add `agents cleanup sandboxes` CLI command + - [ ] **CONC3.2** [Brent] Implement checkpoint file cleanup: + - [ ] Track checkpoint files in database + - [ ] Retention policy (default: 7 days after plan completion) + - [ ] Add `agents cleanup checkpoints` CLI command + - [ ] **CONC3.3** [Brent] Implement session cleanup: + - [ ] Clean sessions with no activity for 30 days + - [ ] Clean associated conversation history + - [ ] **CONC3.4** [Brent] Add automatic cleanup on startup: + - [ ] Run cleanup for orphaned resources + - [ ] Log what was cleaned + - [ ] Tests: Cleanup tests + - [ ] **CONC3.5** [Rui] Write Behave scenarios in `features/garbage_collection.feature`: + - [ ] Scenario: Orphaned sandbox cleaned on startup + - [ ] Scenario: Old checkpoints cleaned by retention policy + - [ ] Scenario: Cleanup commands work manually + +--- + +### Section 15: Definition of Done & Invariants [Days 14-15] + +- [ ] **Stage DOD1: Definition of Done Enforcement** (Day 14) **[Luis]** + - [ ] Code: Implement DoD validation + - [ ] **DOD1.1** [Luis] Parse DoD must/should/may structure: + - [ ] Parse action's `definition_of_done` field + - [ ] Identify MUST, SHOULD, MAY requirements + - [ ] Generate validation checklist from DoD + - [ ] **DOD1.2** [Luis] Validate DoD after execution: + - [ ] Run DoD checklist after Execute completes + - [ ] MUST requirements block apply if failed + - [ ] SHOULD requirements warn but allow apply + - [ ] MAY requirements are informational only + - [ ] **DOD1.3** [Luis] Display DoD validation results: + - [ ] Show checklist in CLI output + - [ ] Color-code: green (pass), red (fail), yellow (warn) + - [ ] Tests: DoD tests + - [ ] **DOD1.4** [Rui] Write Behave scenarios in `features/definition_of_done.feature`: + - [ ] Scenario: DoD MUST failure blocks apply + - [ ] Scenario: DoD SHOULD failure warns but allows apply + - [ ] Scenario: DoD validation results displayed + +- [ ] **Stage DOD2: Invariant System** (Day 14-15) **[Luis]** + - [ ] Code: Implement user-defined invariants + - [ ] **DOD2.1** [Luis] Define `Invariant` model: + - [ ] Field `invariant_id: str` + - [ ] Field `project_id: str` + - [ ] Field `description: str` - human readable + - [ ] Field `check_command: str | None` - shell command to verify + - [ ] Field `check_code: str | None` - Python code to verify + - [ ] Field `severity: str` - error|warning + - [ ] **DOD2.2** [Luis] Implement `agents project add-invariant`: + - [ ] Add invariant to project + - [ ] Specify check command or code + - [ ] **DOD2.3** [Luis] Check invariants during execution: + - [ ] Run invariant checks after each major step + - [ ] Fail execution if invariant violated (severity=error) + - [ ] Warn if invariant violated (severity=warning) + - [ ] Tests: Invariant tests + - [ ] **DOD2.4** [Rui] Write Behave scenarios in `features/invariants.feature`: + - [ ] Scenario: Invariant violation blocks execution + - [ ] Scenario: Invariant warning allows continuation + - [ ] Scenario: Invariant with command check works + +--- + +### Section 16: Context Indexing [Days 15-17] + +- [ ] **Stage CTX1: Repository Indexing** (Day 15-16) **[Hamza]** + - [ ] Code: Implement repo indexing for large codebases + - [ ] **CTX1.1** [Hamza] Create `IndexingService` in `src/cleveragents/application/services/indexing_service.py`: + - [ ] Method `index_project(project: Project) -> Index`: + - [ ] Scan all files in project resources + - [ ] Apply ignore patterns + - [ ] Build file tree index + - [ ] Detect language per file + - [ ] Method `search(query: str, project_id: str) -> list[SearchResult]`: + - [ ] Full-text search across indexed files + - [ ] Return file paths, line numbers, snippets + - [ ] Method `refresh_index(project_id: str) -> None`: + - [ ] Update index for changed files only + - [ ] **CTX1.2** [Hamza] Implement file tree representation: + - [ ] Parse directory structure + - [ ] Include file sizes, modification times + - [ ] Support efficient subtree queries + - [ ] **CTX1.3** [Hamza] Add language detection: + - [ ] Detect language from file extension + - [ ] Detect language from shebang/magic bytes + - [ ] Store language in index + - [ ] Tests: Indexing tests + - [ ] **CTX1.4** [Rui] Write Behave scenarios in `features/context_indexing.feature`: + - [ ] Scenario: Project indexing creates searchable index + - [ ] Scenario: Search returns relevant results + - [ ] Scenario: Index refresh updates changed files only + +- [ ] **Stage CTX2: Embedding Index** (Day 16-17) **[Hamza]** + - [ ] Code: Optional embedding-based search + - [ ] **CTX2.1** [Hamza] Integrate with VectorStoreService: + - [ ] Chunk files into segments + - [ ] Generate embeddings for each chunk + - [ ] Store in FAISS index + - [ ] **CTX2.2** [Hamza] Implement semantic search: + - [ ] Method `semantic_search(query: str, project_id: str) -> list[SearchResult]` + - [ ] Use query embedding to find similar chunks + - [ ] Return ranked results with relevance scores + - [ ] **CTX2.3** [Hamza] Make embedding index optional: + - [ ] Only build if `CLEVERAGENTS_ENABLE_EMBEDDINGS=true` + - [ ] Fall back to full-text search if not available + - [ ] Tests: Embedding tests + - [ ] **CTX2.4** [Rui] Write Behave scenarios in `features/embedding_search.feature`: + - [ ] Scenario: Semantic search returns conceptually similar results + - [ ] Scenario: System works without embedding index + +--- + +### Section 17: Skill Registry [Days 17-18] + +- [ ] **Stage SKILL1: Skill Catalog** (Day 17-18) **[Aditya]** + - [ ] Code: Implement skill registry for safety validation + - [ ] **SKILL1.1** [Aditya] Create `SkillRegistry` in `src/cleveragents/actor/skills/registry.py`: + - [ ] Method `register_skill(skill: Skill) -> None` + - [ ] Method `get_skill(name: str) -> Skill | None` + - [ ] Method `list_skills() -> list[Skill]` + - [ ] Method `list_skills_by_capability(read_only: bool) -> list[Skill]` + - [ ] **SKILL1.2** [Aditya] Auto-register skills from actor configs: + - [ ] When actor config parsed, extract tool definitions + - [ ] Register each tool as a skill with metadata + - [ ] **SKILL1.3** [Aditya] Validate skill usage against plan requirements: + - [ ] Check skill capabilities against action requirements + - [ ] Fail if incompatible skill used + - [ ] **SKILL1.4** [Aditya] Implement `agents skills list`: + - [ ] List all registered skills + - [ ] Show capabilities (read_only, checkpointable, etc.) + - [ ] Tests: Skill registry tests + - [ ] **SKILL1.5** [Rui] Write Behave scenarios in `features/skill_registry.feature`: + - [ ] Scenario: Skills auto-registered from actor config + - [ ] Scenario: Skill capability query works + - [ ] Scenario: Incompatible skill usage detected + +--- + +### Section 18: Deferred Work + +The following items are deferred or no longer applicable: - [ ] **Deferred: REPL Mode** - Focus on CLI first, REPL is optional enhancement - [ ] **Deferred: Auth/Team Commands** - Requires server infrastructure +- [ ] **Deferred: TUI/Web Interface** - After CLI is complete +- [ ] **Deferred: Database Resources** - After source code resources work +- [ ] **Deferred: Cloud Infrastructure Resources** - After source code resources work +- [ ] **Deferred: Permission System** - Server mode prerequisite + - [ ] Namespace-level permissions (who can create/edit org actions) + - [ ] Project-level permissions (who can modify resources, apply changes) + - [ ] Plan-level permissions (can this plan write, require approvals) + - [ ] Skill-level permissions (require approval per call or elevated role) - [ ] **Removed: Old 67-command structure** - Replaced by new command structure - [ ] **Removed: Configuration migration utilities** - CleverAgents is standalone @@ -954,24 +3021,126 @@ The following items from the previous implementation plan are deferred or no lon ## Timeline Summary -| Week | Milestone | Focus | -|------|-----------|-------| -| Week 1 (Days 1-3) | M1 | Plan Lifecycle basics | -| Week 1-2 (Days 4-5) | M2 | Projects & Resources | -| Week 2 (Days 6-8) | M3 | Actors & Skills, MERGE | -| Week 2-3 (Days 9-12) | M4 | Decision Tree | -| Week 3-4 (Days 13-18) | M5 | Subplans & Parallelism | -| Week 4-5 (Days 19-25) | M6 | Server Mode | -| Week 5-6 (Days 26-35) | M7 | Full Feature Set | +### TEAM ROLES AND ASSIGNMENTS -**Aggressive assumptions**: -- 2-3 developers working full-time -- Existing LangGraph infrastructure is reusable -- Actor system (Stage 7.5) provides foundation -- No major architectural surprises +| Developer | Role | Primary Focus Areas | Notes | +|-----------|------|---------------------|-------| +| **Jeff** | CTO/Lead Architect | Critical path items, architectural decisions, complex integrations | Fastest, most expert developer - handles blocking issues | +| **Luis** | Senior Python Architect | Domain models, persistence, algorithms, state machines | Good architecture but can be pedantic - needs clear requirements | +| **Aditya** | Domain Expert (Agents/LLMs) | Actor YAML configs, hierarchical actors, skill execution | Understands topic best but code may need cleanup | +| **Hamza** | Python/RDF Expert | Resources, sandbox, database, general Python | Well-rounded, no agent experience - assign infrastructure | +| **Rui** | Fast Developer | Testing (Behave/Robot), simpler implementations | New to Python - assign testing and straightforward tasks | +| **Brent** | Quality Specialist | Code review, linting, type checking, documentation | Slow but detail-oriented - low contention independent work | +| **Mike/Brian** | Sysadmins | Deployment, infrastructure setup | Minimal coding tasks | -**Risk factors**: -- Sandbox implementation complexity (esp. git worktrees) -- Decision tree correction mechanism -- Multi-project merge conflicts -- Server mode stability +### Week 1 (Days 1-7) - MVP Target (Source Code Only) +| Day | Morning Focus | Owner | Afternoon Focus | Owner | +|-----|---------------|-------|-----------------|-------| +| 1 | A5.1-A5.4 Plan/Action DB Schema | Jeff + Luis | B1.1-B1.6 Project/Resource Models | Hamza | +| 2 | A5.5-A5.9 Plan/Action Repositories | Jeff | B2.1-B2.4 Project CLI Commands | Hamza + Rui (tests) | +| 3 | B3.1-B3.6 Sandbox Protocol + Git | Jeff + Hamza | B3.7-B3.13 Sandbox Manager + Tests | Luis + Rui | +| 4 | C1.1-C1.6 Actor YAML Schema | Aditya | C2.1-C2.8 Actor Compiler | Aditya + Jeff | +| 5 | C3.1-C3.5 Skill Protocol | Jeff | C3.6 Built-in File Skills | Luis + Jeff | +| 6 | C3.7 MCP Adapter | Aditya + Jeff | C4.1-C4.3 Change Tracking | Luis | +| 7 | C4.4-C4.7 Tool Router + Diff | Jeff | C5.1-C5.5 Validation Pipeline | Luis + Rui | + +### Week 2 (Days 8-14) - M3 Complete + Plan-Actor Integration +| Day | Focus | Owner | Deliverable | +|-----|-------|-------|-------------| +| 8 | C6.1-C6.8 Plan-Actor Integration | Jeff + Aditya | Full execute phase working | +| 9 | C7.1-C7.6 Apply Phase + Diff Review | Jeff + Luis | Apply with review gates | +| 10 | D1.1-D1.8 Decision Model | Hamza + Jeff | Decision recording foundation | +| 11 | D2.1-D2.6 Decision Recording | Jeff + Hamza | Decisions captured in Strategize | +| 12 | E1.1-E1.6 Subplan Model | Luis | Subplan spawning design | +| 13 | E2.1-E2.5 Subplan Execution | Jeff + Luis | Sequential subplan execution | +| 14 | End-to-end integration testing | All + Rui | M3 milestone verified | + +### Week 3 (Days 15-21) - M4 Target (Decision Tree + Correction) +| Day | Focus | Owner | Deliverable | +|-----|-------|-------|-------------| +| 15 | D3.1-D3.6 Decision Tree Storage | Hamza | Decision persistence | +| 16 | D4.1-D4.5 Decision CLI Commands | Hamza + Rui | `agents plan tree`, `agents plan explain` | +| 17 | D5.1-D5.8 Decision Correction | Jeff | `agents plan correct` implementation | +| 18 | D5.9-D5.12 Replay Mechanism | Jeff + Luis | Downstream recomputation | +| 19 | E3.1-E3.5 Parallel Subplan Execution | Luis | Concurrent subplans | +| 20 | E4.1-E4.5 Result Merging | Jeff + Luis | Git-style merge for subplans | +| 21 | M4 integration testing | All | Decision correction working | + +### Week 4 (Days 22-30) - M5/M6 Target (Large Projects + Server) +| Day | Focus | Owner | Deliverable | +|-----|-------|-------|-------------| +| 22-23 | F1.1-F1.8 Context Indexing | Hamza | Large codebase indexing | +| 24-25 | F2.1-F2.6 Hot/Warm/Cold Context | Jeff + Hamza | Three-tier memory | +| 26-27 | G1.1-G1.8 Server Mode Foundation | Jeff + Luis | `agents serve` command | +| 28-29 | G2.1-G2.6 Remote Projects | Hamza + Luis | Network resource access | +| 30 | M5/M6 integration testing | All | Server mode operational | + +### Week 5 (Days 31-35) - M7 Target (Autonomy + Polish) +| Day | Focus | Owner | +|-----|-------|-------| +| 31 | Automation level refinement | Jeff + Luis | +| 32 | Cost estimation actors | Aditya | +| 33 | Error recovery mechanisms | Jeff | +| 34 | Performance optimization | Luis + Jeff | +| 35 | Final integration + documentation | All | + +### Continuous Tasks (Throughout) + +**Brent (Quality - Independent, Low Contention)**: +- Review all PRs within 4 hours of submission +- Run `nox -s typecheck` on all branches before merge +- Run `nox -s lint` and ensure 0 warnings +- Monitor test coverage (must stay >85%) +- Update documentation for API changes +- Security audit: no eval(), no template injection, no secrets in code + +**Rui (Testing - Parallel with Feature Work)**: +- Write Behave scenarios for each feature (before implementation starts) +- Write Robot integration tests for each milestone +- Run full test suite daily +- Report test failures immediately +- Maintain test fixtures and mocks in `features/` + +### Critical Path Dependencies + +``` +Day 1: A5 (Persistence) ────────────────────────────────┐ +Day 2: B1-B2 (Project/Resource) ──────┐ │ +Day 3: B3 (Sandbox) ──────────────────┼─────────────────┤ +Day 4: C1-C2 (Actor) ─────────────────┘ │ +Day 5: C3 (Skills) ─────────────────────────────────────┤ +Day 6: C4 (Change Tracking) ────────────────────────────┤ +Day 7: C5 (Validation) ─────────────────────────────────┘ + │ +Day 8-9: C6-C7 (Integration + Apply) ───────────────────┤ +Day 10-14: D1-E2 (Decisions + Subplans) ────────────────┤ + │ + MERGE POINT M3 ◄──────────────┘ + │ +Day 15-21: D3-E4 (Correction + Parallel) ───────────────┤ + │ + MERGE POINT M4 ◄──────────────┘ + │ +Day 22-30: F-G (Context + Server) ──────────────────────┘ +``` + +### Risk Mitigation + +| Risk | Mitigation | Owner | +|------|------------|-------| +| Git worktree complexity | Jeff handles sandbox implementation | Jeff | +| Multi-file generation reliability | Extensive testing, fallback mechanisms | Luis + Rui | +| Decision tree correction bugs | Jeff reviews all correction logic | Jeff | +| Large codebase performance | Early profiling, lazy loading | Luis + Hamza | +| Server mode stability | Incremental rollout, feature flags | Jeff + Luis | + +### Definition of Done (Each Task) + +1. ✅ Code implemented with full type annotations +2. ✅ Behave scenarios written and passing +3. ✅ Robot integration tests (for CLI/E2E tasks) passing +4. ✅ `nox -s typecheck` passes with 0 errors +5. ✅ `nox -s lint` passes with 0 warnings +6. ✅ Test coverage >85% +7. ✅ PR reviewed by Brent (or Jeff for critical items) +8. ✅ Implementation notes added to this document diff --git a/specification.md b/specification.md index b358b54e7..618428168 100644 --- a/specification.md +++ b/specification.md @@ -993,25 +993,90 @@ Execution should be treated like a transactional pipeline: This is explicitly motivated by "partial failure leaves codebase inconsistent" and the need for transaction rollback. -### Parsing and File Generation Expectations +### Tool-Based Resource Modification (Modern Architecture) -The notes call out planned improvements: +**IMPORTANT: CleverAgents does NOT parse LLM output to extract code.** Instead, it uses the modern tool-based approach pioneered by Claude Code, Cursor, and Aider where: -* Extract code blocks properly (avoid markdown explanation text in output files). -* Avoid generic file names like `generated.py`. -* Improve file structure generation. -* Handle invalid python responses better than wrapping in docstrings. +1. **LLMs call tools/skills directly** (`edit_file()`, `write_file()`, `delete_file()`, etc.) +2. **Tools operate on the sandbox** - each tool invocation modifies sandbox state directly +3. **ChangeSet is built from tool invocations** - not by parsing LLM text output +4. **Validation runs on sandbox state** - after tools execute, not on parsed output -Therefore, CleverAgents should define a **standard output parsing pipeline**: +This architecture provides: -1. Parse model output. -2. Identify code blocks and associated filenames (if present). -3. If filename missing, infer from context and existing project structure. -4. Validate syntax (when language known). -5. If invalid, either: +* **Atomic operations**: Each tool call is a discrete, trackable change +* **No parsing ambiguity**: Tools have structured parameters (path, content, etc.) +* **Resource-agnostic**: Same pattern works for files, databases, APIs, any resource type +* **Safety by design**: Tools run in sandbox with defined capabilities and restrictions +* **MCP compatibility**: Skills map directly to MCP tools for external integrations - * request correction from actor, or - * quarantine the output as a "draft artifact" rather than writing it as real source. +#### How It Works + +``` +LLM Response (with tool calls) + ↓ +┌─────────────────────────────────────┐ +│ Skill/Tool Router │ +│ - Routes each tool call to handler │ +│ - Validates parameters │ +│ - Enforces capability restrictions │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ Sandbox Execution │ +│ - Tool operates on sandboxed state │ +│ - Each invocation recorded │ +│ - Checkpoint created if needed │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ ChangeSet Accumulation │ +│ - Each resource-modifying call → │ +│ becomes a Change record │ +│ - ChangeSet = history of changes │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ Validation & Review │ +│ - Run validators on sandbox state │ +│ - Generate diff from ChangeSet │ +│ - Present for review before Apply │ +└─────────────────────────────────────┘ +``` + +#### Built-in Resource Skills + +CleverAgents provides these core skills for resource manipulation: + +| Skill | Description | Creates Change? | +|-------|-------------|-----------------| +| `read_file(path)` | Read file contents | No | +| `write_file(path, content)` | Create/overwrite file | Yes | +| `edit_file(path, changes)` | Apply targeted edits | Yes | +| `delete_file(path)` | Remove file | Yes | +| `move_file(src, dst)` | Rename/move file | Yes | +| `create_directory(path)` | Create directory | Yes | +| `list_files(pattern)` | List files matching glob | No | +| `search_files(pattern, content)` | Search file contents | No | +| `get_file_info(path)` | Get file metadata | No | + +Each skill automatically: +* Operates within sandbox boundaries +* Records changes to the ChangeSet +* Validates parameters against project configuration +* Enforces deny-list patterns (`.git/`, `node_modules/`, etc.) + +#### Why Not Parse LLM Output? + +The obsolete approach of parsing markdown code fences has fundamental problems: + +1. **Ambiguity**: Is text explanation or code? Where does one file end and another begin? +2. **Fragility**: Models output varying formats; regex parsing is brittle +3. **Loss of semantics**: You lose the intent (create vs modify vs delete) +4. **No atomicity**: Can't rollback individual operations +5. **Resource-limited**: Only works for files, not databases or other resources + +The tool-based approach solves all of these by making each operation explicit, typed, and trackable. ## Semantic Error Prevention @@ -1688,6 +1753,182 @@ This registry supports: * plan validation ("this plan requires checkpointable write skills; do we have them?") * safe automation ("don't ask permission for every tiny command—use sandbox/checkpoints instead") +### MCP Integration Architecture + +CleverAgents fully integrates with the **Model Context Protocol (MCP)** while extending it for agentic workflows: + +#### MCP Concepts Mapping + +| MCP Concept | CleverAgents Equivalent | Extension | +|------------|------------------------|-----------| +| Tool | Skill | Extended metadata (write_scope, checkpointable) | +| Resource | Resource | Read AND write operations | +| Prompt | Action template | Full plan lifecycle | +| Server | MCP Server (external) | Integrated via skill adapters | + +#### Using External MCP Servers + +CleverAgents can connect to any MCP server and expose its tools as skills: + +```yaml +actors: + github_ops: + type: tool + config: + mcp_servers: + - name: github + command: "npx @anthropic/mcp-github" + env: + GITHUB_TOKEN: "${GITHUB_TOKEN}" + - name: filesystem + command: "npx @anthropic/mcp-filesystem" + args: ["--root", "/workspace"] +``` + +When an actor specifies `mcp_servers`, all tools from those servers become available as skills within that actor's execution context. + +#### MCP Tool → Skill Adapter + +External MCP tools are automatically wrapped with CleverAgents skill semantics: + +``` +┌─────────────────────────────────────┐ +│ MCP Server │ +│ - Exposes tools via JSON-RPC │ +│ - Has MCP metadata (read-only, etc) │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ MCPSkillAdapter │ +│ - Wraps MCP tool as Skill │ +│ - Infers extended metadata │ +│ - Intercepts calls for: │ +│ - Sandbox path rewriting │ +│ - Change tracking │ +│ - Permission enforcement │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ Skill Execution │ +│ - Runs in plan's sandbox context │ +│ - Changes recorded to ChangeSet │ +│ - Checkpoints created as needed │ +└─────────────────────────────────────┘ +``` + +#### Skill Execution Flow (Tool-Based Architecture) + +When an LLM decides to use a skill, the following flow occurs: + +``` +1. LLM generates tool call: edit_file(path="src/main.py", changes=[...]) + ↓ +2. Tool Router receives call + - Validates parameters against schema + - Checks skill capability metadata + - Enforces permission restrictions + ↓ +3. Sandbox Context Resolution + - Maps logical path to sandbox path + - Ensures sandbox exists for resource + - Creates checkpoint if skill is checkpointable + ↓ +4. Skill Execution + - Runs skill code (built-in or MCP) + - Operations occur on sandboxed state + - Result captured + ↓ +5. Change Recording + - If skill modifies resources, create Change record + - Append Change to plan's ChangeSet + - Update sandbox state + ↓ +6. Return to LLM + - Return skill result + - LLM continues with next action +``` + +#### Built-in Skills (Core Resource Operations) + +CleverAgents provides these built-in skills that work with any resource through the unified abstraction layer: + +**File Operations:** +```python +read_file(path: str) -> str +write_file(path: str, content: str) -> None +edit_file(path: str, edits: list[Edit]) -> None +delete_file(path: str) -> None +move_file(source: str, destination: str) -> None +copy_file(source: str, destination: str) -> None +``` + +**Directory Operations:** +```python +create_directory(path: str) -> None +list_directory(path: str, pattern: str = "*") -> list[str] +delete_directory(path: str, recursive: bool = False) -> None +``` + +**Search Operations:** +```python +search_files(pattern: str, content_pattern: str = None) -> list[Match] +find_definition(symbol: str) -> list[Location] +find_references(symbol: str) -> list[Location] +``` + +**Git Operations (when resource is git repository):** +```python +git_status() -> GitStatus +git_diff(path: str = None) -> str +git_log(count: int = 10) -> list[Commit] +git_blame(path: str) -> list[BlameLine] +``` + +Each built-in skill: +* Has fully defined capability metadata +* Operates through the resource abstraction layer +* Automatically tracks changes to the ChangeSet +* Respects sandbox boundaries and deny-lists + +#### Change Tracking from Tool Invocations + +**Critical Architecture Point:** The ChangeSet is NOT built by parsing LLM output. It is built by recording the effects of tool/skill invocations: + +```python +class SkillExecutionContext: + """Context provided to skill execution.""" + + def __init__(self, plan: Plan, sandbox: Sandbox): + self.plan = plan + self.sandbox = sandbox + self.changes: list[Change] = [] + + def record_change(self, change: Change) -> None: + """Record a change made by a skill.""" + self.changes.append(change) + self.plan.changeset.add_change(change) + + +class WriteFileSkill: + """Built-in skill for writing files.""" + + def execute(self, path: str, content: str, ctx: SkillExecutionContext) -> None: + # Get the resource handler for this path + handler = ctx.sandbox.get_handler(path) + + # Perform the write (returns Change record) + change = handler.write(path, content, ctx.sandbox) + + # Record the change + ctx.record_change(change) +``` + +This approach means: +* Every resource modification is explicit and tracked +* The ChangeSet accurately reflects what was done, not what was said +* Rollback is precise (replay inverse of recorded changes) +* Audit logs show exactly what each skill invocation did + ## Session ### What a Session Is @@ -1882,6 +2123,85 @@ This enables: * better auditing * accurate sandbox scoping +### Unified Resource Abstraction Layer + +CleverAgents provides a unified abstraction that allows skills to work with any resource type through a consistent interface. This enables: + +1. **Resource-agnostic skills**: A skill like `read_content(path)` works whether the path refers to a file, database record, or API endpoint +2. **Consistent sandbox semantics**: All resources support the same sandbox lifecycle (create, read, write, checkpoint, rollback) +3. **Pluggable resource handlers**: New resource types can be added without modifying existing skills +4. **Unified change tracking**: All resource modifications flow into the same ChangeSet model + +#### Resource Handler Interface + +Every resource type implements this interface: + +```python +class ResourceHandler(Protocol): + """Handler for a specific resource type.""" + + def read(self, path: str, sandbox: Sandbox) -> Content: + """Read content from the sandboxed resource.""" + ... + + def write(self, path: str, content: Content, sandbox: Sandbox) -> Change: + """Write content and return the Change record.""" + ... + + def delete(self, path: str, sandbox: Sandbox) -> Change: + """Delete resource and return the Change record.""" + ... + + def list(self, pattern: str, sandbox: Sandbox) -> list[str]: + """List paths matching pattern.""" + ... + + def diff(self, path: str, sandbox: Sandbox) -> str: + """Generate diff between sandbox and original state.""" + ... + + def supports_operation(self, operation: OperationType) -> bool: + """Check if this resource supports the given operation.""" + ... +``` + +#### Built-in Resource Handlers + +| Resource Type | Handler | Read | Write | Delete | Sandbox Strategy | +|--------------|---------|------|-------|--------|------------------| +| Filesystem | `FilesystemHandler` | ✓ | ✓ | ✓ | copy_on_write | +| Git Repository | `GitHandler` | ✓ | ✓ | ✓ | git_worktree | +| PostgreSQL | `PostgresHandler` | ✓ | ✓ | ✓ | transaction | +| SQLite | `SQLiteHandler` | ✓ | ✓ | ✓ | copy_on_write | +| HTTP API | `HTTPHandler` | ✓ | ✓* | ✓* | none | +| S3 Bucket | `S3Handler` | ✓ | ✓ | ✓ | versioning | + +*HTTP writes may not be sandboxable depending on the API + +#### Resource Path Resolution + +Paths in skills are resolved through a resource routing system: + +``` +path://resource-name/relative/path + ↓ +┌─────────────────────────────────────┐ +│ Resource Router │ +│ - Parses path scheme │ +│ - Looks up resource by name │ +│ - Routes to appropriate handler │ +└─────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ Handler (e.g., GitHandler) │ +│ - Resolves relative path │ +│ - Operates on sandboxed state │ +│ - Returns Change record │ +└─────────────────────────────────────┘ +``` + +For convenience, paths without a scheme default to the project's primary filesystem resource. + ## Context Context in is not "dump all files into an LLM." It is a system that: @@ -2354,56 +2674,73 @@ Where `Change` includes: * `patch` (optional unified diff) * `language` (optional but helpful for validation) -**Key requirement:** the pipeline must stop treating a plan as "one output string"; it must treat the plan as "a structured set of file ops." +**Key requirement:** the pipeline must stop treating a plan as "one output string"; it must treat the plan as "a structured set of resource ops." -#### B. Force a structured LLM output contract (JSON-first) +#### B. Implement Tool-Based Resource Modification (Modern Architecture) -To get multi-file reliably, require the execution actor (or a dedicated "renderer" actor) to output **strict JSON** that conforms to a schema, for example: +**CRITICAL: Do NOT parse LLM output to extract code.** Instead, use the modern tool-based approach: -```json -{ - "changes": [ - {"operation": "create", "path": "src/main.py", "content": "..."}, - {"operation": "create", "path": "src/routes/users.py", "content": "..."}, - {"operation": "modify", "path": "README.md", "patch": "...unified diff..."} - ], - "notes": ["Run tests: pytest", "Add env var: DATABASE_URL"] -} +``` +LLM → calls tools/skills directly → tools modify sandbox → ChangeSet built from tool invocations ``` Implementation details: -* Define a JSON schema (or Pydantic model) and validate strictly. -* If invalid JSON: +1. **Provide built-in resource skills** that LLMs call directly: + * `read_file(path)` - Read file contents + * `write_file(path, content)` - Create/overwrite file + * `edit_file(path, edits)` - Apply targeted edits (search/replace or line-based) + * `delete_file(path)` - Remove file + * `move_file(src, dst)` - Rename/move file + * `create_directory(path)` - Create directory + * `list_files(pattern)` - List files matching glob + * `search_files(pattern)` - Search file contents - * run an automatic "repair" step (LLM or deterministic fixer), - * if still invalid, fail the phase with a clear error and keep artifacts for review (don't write junk into files). +2. **Each skill invocation that modifies resources** creates a `Change` record: + ```python + # When write_file("src/main.py", content) is called: + change = Change( + operation=OperationType.CREATE, + path="src/main.py", + content=content, + language="python" + ) + changeset.add_change(change) + ``` -**Why JSON-first matters:** the current "strip only the outer fences" behavior is not enough and will always regress into "explanations in code." +3. **The ChangeSet is the accumulated history** of resource-modifying skill calls, NOT parsed LLM text. -#### C. Provide a fallback parser (markdown/code-fence tolerant) but never "raw dump" +**Why tool-based is superior to parsing:** -Even with JSON-first, a fallback parser is practical. But the fallback must produce the same `ChangeSet` structure. +| Aspect | Parsing Approach | Tool-Based Approach | +|--------|------------------|---------------------| +| Ambiguity | "Is this code or explanation?" | Each operation is explicit | +| Atomicity | Parse entire response | Each tool call is discrete | +| Rollback | Reconstruct from diff | Replay inverse of recorded changes | +| Resource types | Files only | Any resource (files, DBs, APIs) | +| Audit trail | What model said | What actually happened | -A robust fallback should: +#### C. Support MCP Tools and Custom Skills -* Parse multiple fenced blocks -* Detect per-block file paths from: +Skills can come from multiple sources, all producing the same `Change` records: - * headings like `### path/to/file.py` - * inline hints like `// file: ...` - * or an explicit preamble list -* Reject/strip explanatory prose **unless** it is explicitly routed to a non-code artifact (e.g., `notes.md` or `PLAN.md`) +1. **Built-in skills**: Core file operations, git, search +2. **MCP servers**: External tools wrapped with sandbox interception +3. **Custom inline skills**: Python code in actor YAML -**Never again** write the entire model response into a source file. +All skills operate through the unified resource abstraction layer: +* Paths are resolved to sandboxed locations +* Write operations create Change records +* Capability metadata enforces safety restrictions #### D. Implement directory creation and scaffolding rules -Once you can create multiple files, you need deterministic rules for directories: +Skills automatically handle directory operations: -* auto-create directories for new files (safe, idempotent) -* enforce project root boundaries (never escape the repo root) -* enforce ignore patterns / deny lists (e.g., don't create inside `.git/`) +* Auto-create parent directories for new file paths (safe, idempotent) +* Enforce project root boundaries (never escape the sandbox) +* Enforce deny-list patterns (`.git/`, `node_modules/`, etc.) +* Respect project `.gitignore` and custom exclusion rules This directly addresses the "create REST API" expectation (routes/, models/, etc.) that current code cannot meet.