374 KiB
CleverAgents Implementation Plan
CRITICAL: Execute These Rules Without Exception
- Strictly adhere to guidelines in
./CONTRIBUTING.md: All rules and guidelines outlined in this file must be strictly followed at all times. - Python implementation scope only: Every action described here pertains to building an idiomatic Python codebase that implements the CleverAgents architecture.
- NO BACKWARDS COMPATIBILITY: CleverAgents is a NEW standalone project. Do NOT maintain any backwards compatibility. No migration guides, no compatibility shims, no support for old configurations or data.
- Living document protocol: After finishing each checklist item (and its testing sub-items), immediately append every decision, discovery, open question, or deviation to this document under the matching Notes section. This plan remains the authoritative record.
- Single documentation surface: Do not create auxiliary notes elsewhere unless explicitly required. All architectural updates, troubleshooting outcomes, and contextual knowledge must flow back into this markdown file.
- Sequential discipline: Always begin with the first unchecked item in the checklist. Do not progress until that item, its documentation update, and its testing sub-items (including any spawned remediation tasks) are fully resolved.
- USE MODERN PYTHON TOOLING: This is a cutting-edge Python project that must use modern build tools and workflows. NO Makefiles, NO legacy approaches, NO helper scripts. Use Hatch exclusively for project management, nox for task automation, pyproject.toml for all configuration. Commands should be Python-native (e.g.,
hatch env create,nox -s test) not shell scripts or make targets. All tooling must be from the current Python ecosystem (2024+). When current tooling (such as "Behave" and "Robot Framework") can be used to solve a problem, use them rather than adding new tooling, keep it simple. NO wrapper scripts - use tools directly as designed. - Unit + integration testing mandate: For every coding task, author or update both unit and integration tests, run them, and achieve passing results before marking the task complete. Testing subtasks are non-optional.
- Behavior-driven testing stack: Use Behave feature suites under
features/for unit-level and scenario tests and Robot Framework suites underrobot/for integration and end-to-end coverage. Keep both synchronized with the code under test and document all updates in this plan. - Do not use pytest style unit tests: Under no circumstances should you write pytest styled unit tests, all unit tests should be Behave based (as noted in the last bullet point), which follows the Cucumber/Gherkin style of tests as seen under
features/, this is why there is intentionally notests/folder. - Test execution via nox: Run every unit, integration, Behave, Robot, and benchmark suite exclusively through the designated
noxsessions (e.g.,nox -s unit_tests,nox -s integration_tests). Do not invokebehave,robot, or similar runners directly; if anoxsession is missing required tooling, add the dependency to the session before rerunning. - Failure capture: Any Behave or Robot failure instantly spawns a new unchecked sub-item under the same step titled
Fix – <short failure summary>. Document the failure context in the Notes section and resolve it before moving forward. - Traceability requirement: When a decision impacts future work, reference the relevant functions or modules in the Notes section using the
file_path:line_numberpattern for fast navigation. - unit tests coverage above 97% at all times: unit test coverage must remain above 97% at all times. Unit tests can be run with
nox -e unit_testsand is run as part of the default test suite run withnox. - must be statically typed: All code at all times must use statically typed typing and must pass the static check run with
nox -e typecheckwhich is run as part of the default test suite withnox. Under no circumstances at no point should you ignore type checking, this means never turn it off in the config files, and never use inline comments to force an type checking error to be suppressed. - Use existing tooling: Always prefer nox sessions over raw commands, Behave for unit tests over new frameworks, Robot for integration tests, Hatch for dependency management.
- Mock placement rule: ALL mocks, test doubles, and mock implementations MUST exist only in
features/directory. Production code insrc/and utility scripts inscripts/must NEVER contain mock implementations, test data, or conditional testing behavior. Use dependency injection to swap implementations during tests. - CRITICAL - Implementation Checklist Separation: The "Implementation Checklist" section MUST always remain separate and be the LAST section of this document. All development notes, design decisions, progress updates, technical details, and discoveries belong in their respective phase Notes sections (e.g., Phase 0 Notes, Phase 1 Notes, Phase 2 Notes) which appear BEFORE the Implementation Checklist. Never add content after the checklist section. The checklist is for tracking what needs to be done; the Notes sections are for documenting what was done and how.
CONTINUOUS CHECKLIST AND KNOWLEDGE STEWARDSHIP (MANDATORY)
- Immediate documentation loop: After completing any amount of work toward a checklist item, append the newly discovered information, assumptions, implementation notes, and open questions to this document before proceeding. No discovery, decision, or workaround may remain undocumented.
- Dynamic checklist maintenance: Before marking an item complete—or returning from work in progress—review all remaining checklist entries. Update their descriptions, add clarifying subtasks, and insert new entries capturing follow-on tasks, bug fixes, or future enhancements uncovered during implementation. Place new items in the phase where the work logically belongs (current or future) and note cross-phase dependencies.
- Implementation traceability: Record substantive code decisions (design pattern choices, module ownership, testing strategy, risk mitigations) back into the corresponding Notes section and checklist subtasks immediately after each coding/testing session.
- Checklist integrity: Never remove checklist items unless they are explicitly retired with documented reasoning. Mark completed work by checking the item(s) and append new tasks or restructuring bullets only when required—preserve original wording for historical traceability.
- Enforcement: Treat omissions as blocking bugs—if the plan falls out of sync with reality, halt work, reconcile the discrepancy here, and only then continue.
CleverAgents Vision
CleverAgents is your command center for AI agents—a unified platform for orchestrating any task you want agents to accomplish, from developing large software projects to writing comprehensive technical papers, administering databases, managing cloud infrastructure, or any complex multi-step workflow. The core value proposition is enabling long-running, complex, large-scale tasks to execute autonomously with minimal human intervention, making it ideal for building entire software systems, producing extensive documentation, or managing sophisticated operations largely hands-off.
When connected to a CleverAgents server (developed independently), the client becomes a gateway to a collaborative hub where teams can share resources—prompts, actors, actions, and projects—while executing plans on the server. This enables a consistent experience across all your devices: start a complex task on your laptop, check progress from your phone, and review results from any machine. Note: The server is a separate project; this implementation plan covers the client only.
While CleverAgents leverages LangGraph and LangChain for the underlying LLM runtime primitives (tool calling, graphs, routing), its value lies in what it builds on top:
- CleverAgents provides:
- A first-class plan lifecycle (Action/Strategize/Execute/Apply) for breaking down and tracking complex work,
- A project + resource model for grounding tasks in real codebases, databases, documents, and infrastructure,
- A consistent actor abstraction for defining and composing intelligent agents,
- A consistent skill abstraction for anything an agent can execute,
- A sandbox + checkpoint safety model for safe, reversible execution,
- A CLI/TUI/Web UX for controlling and monitoring large multi-step autonomous work.
Key Concepts
| Concept | Definition |
|---|---|
| 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 <namespace>/<name>. |
| Project | A collection of resources + configuration. Created via CLI commands (NOT YAML files). |
| Resource | Anything that can be read/written/queried. Each resource defines its own sandbox strategy. |
| Skill | A callable capability defined inline in actor YAML as tool nodes. |
| Namespace | Scoping mechanism: local/, <username>/, <orgname>/, or provider namespaces (openai/, anthropic/). |
| Decision | A recorded choice point made during Strategize that affects downstream work. Forms a tree enabling correction and replay. |
Objectives and Guiding Principles
- Ship a Python-based, feature-complete application named CleverAgents implementing the four-phase plan lifecycle with actors, projects, resources, and sandbox-based execution.
- Implement functionality using Pythonic architecture: dependency inversion, strategy, adapter, observer, state, builder, factory, template method, event sourcing, and decorator patterns where appropriate.
- Build a unified Python executable (
agents) that operates as a client-only application, supporting stand-alone local-only mode or connecting to an independently developed server for multi-user deployments. - Enforce fail-fast error handling, rich logging, and comprehensive type coverage with docstrings and runtime validation aligned to Python best practices.
- Provide a pluggable ORM abstraction supporting heavy (PostgreSQL/MySQL) and lightweight (SQLite/DuckDB/in-memory) backends, with zero-code configuration switches.
- Generate fresh documentation via MkDocs (Material for MkDocs) integrated within the
docs/directory of the CleverAgents project.
Core Architectural Requirements
Scalability: The system must handle massive codebases (50,000+ files) through:
- Three-tier memory architecture (hot/warm/cold)
- Hierarchical task decomposition
- Bounded dependency closures
- Lazy resource sandboxing
Reliability: Prevent cascading failures through:
- Complete execution isolation via sandboxes
- Multi-layer semantic error prevention
- Checkpoint-based rollback capabilities
- Invariant enforcement throughout execution
Autonomy with Control: Progressive automation through:
- Three-level automation system (manual, review-before-apply, full)
- Decision correction without full re-execution
- Confidence-based escalation
- Semantic understanding of when human input is needed
Continuous Testing and Documentation Policy
- Do not mark any parent checklist item complete until all subordinate Code, Document, Tests tasks and any generated
Fix – …tasks are resolved and the associated Notes section has the latest context. - Every time new information appears, extend the corresponding Notes section immediately with explicit references to code locations and decisions.
- Maintain a running catalog of Behave commands, Robot suites, fixtures, and environments in the Notes sections to assist subsequent contributors.
- Expand the nested Code/Document/Tests sub-bullets with newly discovered tasks as implementation advances so the plan always mirrors ground truth.
Completion Criteria
The implementation concludes only when every checklist item and spawned remediation task is checked, all Notes sections contain final decisions and references, and the full Behave and Robot test suites (unit, integration, end-to-end, benchmarking, packaging, documentation) pass without outstanding failures.
Architecture Overview
Plan Lifecycle Phases
Action -> Strategize -> Execute -> Apply -> Applied (terminal)
| Current Phase | Command Verb | Next Phase |
|---|---|---|
| (none) | create |
Action |
| Action | use |
Strategize |
| Strategize | execute |
Execute |
| Execute | apply |
Applied |
Plan States (Per Phase)
Action phase states: available, draft, archived
Strategize / Execute / Apply phase states: queued, processing, errored, complete, cancelled
Key Architectural Components
Multi-tier Memory System:
- Hot tier: Immediate working context in LLM context window
- Warm tier: Recent decisions and contexts from current plan tree
- Cold tier: Historical decisions from past plans, queryable but not in active memory
- Context snapshots with cryptographic hashes preserve complete decision context
Dependency Closure Computation:
- Resource-aware analysis during Strategize
- Hierarchical scoping with explicit resource lists
- Lazy expansion prevents closure explosion
- Interface-based boundaries for modular changes
Execution Coordination:
- Complete isolation via per-plan sandboxes
- Resource-specific sandbox strategies (git worktrees, transactions, etc.)
- Hierarchical merge resolution
- Checkpoint-based coordination for rollback
Semantic Error Prevention:
- Decision-time validation during Strategize
- Execution-time semantic guards in actors
- Invariant enforcement throughout
- Pattern-based predictive error prevention
Namespace Rules
| Namespace | Scope | Storage |
|---|---|---|
local/ |
Current machine only | Local database |
<username>/ |
Personal server namespace | Server database |
<orgname>/ |
Organization namespace | Server database |
openai/, anthropic/, etc. |
Built-in LLM actors | N/A (built-in) |
Configuration Philosophy
- Actions: Created via CLI commands (
agents [--data-dir PATH] [--config-path PATH] action create --config <file> ...) - Projects: Created via CLI commands (
agents [--data-dir PATH] [--config-path PATH] project create ...) - Actors: Defined via YAML configuration files (the ONLY YAML configuration)
- Resources: Registered via
agents resource add, then linked viaagents project link-resource
Environment Variables for Testing
All environment variables needed during testing are stored in the .env file in the project root. This file contains API keys and tokens for various LLM providers and services. When implementing provider integrations or any features that require external services, use the environment variable names from this file or add new ones following the same pattern.
Current Environment Variables
| Variable Name | Service | Usage |
|---|---|---|
OPENROUTER_API_KEY |
OpenRouter | Access to multiple LLM models through OpenRouter API |
OPENAI_API_KEY |
OpenAI | Direct access to OpenAI models (GPT-3.5, GPT-4, etc.) |
ANTHROPIC_API_KEY |
Anthropic | Access to Claude models |
GOOGLE_API_KEY |
Google AI | Access to Google's API for web searches |
GEMINI_API_KEY |
Google Gemini | Access to Google's Gemini models |
HF_TOKEN |
Hugging Face | Access to Hugging Face models and datasets |
Development Log
This section will be updated with notes about each phase/task as they are implemented as well as forward looking remarks or insights.
Phase 0: Discovery and Requirements Elaboration (Python Tooling)
Status: [X] COMPLETE
All core Phase 0 discovery tasks have been successfully completed. See the Phase 0 section in the Implementation Checklist for detailed completion records.
Phase 0 Notes
- 2025-11-01: Implemented CLI inventory extraction tools, server endpoint extraction, data contract extraction, shell asset extraction
- 2025-11-02: Implemented environment variable extraction and implicit behavior extraction tools
- 2025-11-04: Completed workflow parity matrix generator and cloud features identification
- All discovery artifacts stored in
docs/reference/
Phase 1: Target Architecture Definition
Status: [X] COMPLETE
All 10 ADRs have been created and package structure established. See the Phase 1 section in the Implementation Checklist for detailed completion records.
Phase 1 Notes
- 2025-11-04: Completed all 10 Architecture Decision Records
- 2025-11-05: Package structure created based on ADR-001
- All ADRs documented in
docs/architecture/decisions/ - 2026-02-11: CLI syntax updated to spec-aligned forms (action create via
--config, plan use positional args, project create positional). Legacy--name/--projectexamples retained in historical notes only. - 2026-02-11: Action config YAML baseline (spec-aligned):
name: local/example-action description: Example action for CLI flows strategy_actor: openai/gpt-4 execution_actor: openai/gpt-4 definition_of_done: "All steps complete"
Phase 2: Runtime Foundation (Completed Work)
Status: Substantially Complete - Transitioning to new Architecture
The following work from the previous implementation has been completed and will be preserved/adapted:
Completed Infrastructure
- LangChain/LangGraph dependencies and integration (ADR-011)
- PlanGenerationGraph, ContextAnalysisAgent, AutoDebugGraph workflows
- Memory service with EntityMemory
- SQLite persistence with Alembic migrations
- CLI streaming integration
- Provider adapters (OpenAI, Anthropic, Google, OpenRouter)
- Actor configuration system (Stage 7.5)
- Test coverage at 95%
Phase 2 Notes (Preserved from Previous Work)
2025-11-22: Week 12 Complete, Phase 2 Core Functionality DONE
- CLI Streaming Integration fully implemented
- AutoDebugGraph Implementation complete
- Mock provider enhancements with configurable failure modes
- Infrastructure improvements (DebugAttempt model, repositories)
- 2026-02-11: CLI syntax refreshed to spec-aligned forms in current execution sections; legacy
--name/--projectexamples retained only in historical notes.
2025-12-05: LangSmith observability integration complete 2025-12-08: Actor-first provider wiring complete 2025-12-17: Stage 7 performance optimization complete 2026-02-02: Stage 7.5 Actor Configuration System complete 2026-02-05: Stage A1 & A2 Complete - Plan and Action Domain Models
- Created
src/cleveragents/domain/models/core/plan.pywith:PlanPhaseenum (ACTION, STRATEGIZE, EXECUTE, APPLY, APPLIED)ActionStateenum (AVAILABLE, DRAFT, ARCHIVED)ProcessingStateenum (QUEUED, PROCESSING, ERRORED, COMPLETE, CANCELLED)NamespacedNamemodel with parse() and str() methodsPlanIdentitymodel with ULID validationPlanmodel with full lifecycle supportcan_transition()function for phase transition validation
- Created
src/cleveragents/domain/models/core/action.pywith:ActionArgumentmodel with parse() method for CLI argument parsingActionmodel with strategy/execution actor references- Argument validation including type checking
- Added 52 Behave test scenarios across 2 feature files:
features/plan_model.feature(30 scenarios)features/action_model.feature(22 scenarios)
- All new tests pass, existing tests unaffected
2026-02-05: Stage A3 Complete - PlanLifecycleService
- Created
src/cleveragents/application/services/plan_lifecycle_service.pywith:- Full plan lifecycle management (Action -> Strategize -> Execute -> Apply -> Applied)
- Action CRUD operations (create, get, list, make_available, archive)
- Plan creation via
use_action()which transitions Action to Strategize - Phase transition methods:
execute_plan(),apply_plan() - State management:
start_*(),complete_*(),fail_*()for each phase cancel_plan()for non-terminal plans- Custom exceptions:
InvalidPhaseTransitionError,ActionNotAvailableError,PlanNotReadyError - In-memory storage (to be replaced with persistence in Stage A5)
- Added python-ulid dependency for ULID generation
- Added 29 Behave test scenarios in
features/plan_lifecycle_service.feature - Total new test scenarios: 81 (30 + 22 + 29)
2026-02-05: Stage A4 In Progress - Plan CLI Commands
- Created
src/cleveragents/cli/commands/action.pywith:agents [--data-dir PATH] [--config-path PATH] action create- Create new action with strategy/execution actors, definition of done, argumentsagents [--data-dir PATH] [--config-path PATH] action list- List actions with filtering by namespace, stateagents [--data-dir PATH] [--config-path PATH] action show- Show action details by ID or nameagents [--data-dir PATH] [--config-path PATH] action available- Make draft action available for useagents [--data-dir PATH] [--config-path PATH] action archive- Archive an action (soft delete)
- Extended
src/cleveragents/cli/commands/plan.pywith v3 lifecycle commands:agents [--data-dir PATH] [--config-path PATH] plan use <action> --project <id>- Use action to create plan in Strategize phaseagents [--data-dir PATH] [--config-path PATH] plan execute [plan_id]- Transition plan from Strategize to Executeagents [--data-dir PATH] [--config-path PATH] plan apply [plan_id]- Transition plan from Execute to Applyagents [--data-dir PATH] [--config-path PATH] plan status [plan_id]- Show v3 plan status and detailsagents [--data-dir PATH] [--config-path PATH] plan list- List v3 lifecycle plans with filteringagents [--data-dir PATH] [--config-path PATH] plan cancel <plan_id>- Cancel a non-terminal plan
- Registered action commands in CLI main.py
- Added 15 Behave test scenarios in
features/action_cli.feature - Total test scenarios: 96 (81 + 15)
2026-02-09: Task Q0.6b Complete - README.md Setup Instructions [Brent]
- Updated README.md Quick Start: added
devextras topip install, addedscripts/setup-dev.shstep - Updated README.md Developing section: fixed
oxttypo ->nox, added quality/security nox sessions (security_scan, dead_code, complexity, pre_commit, adr_compliance), added note about pre-commit hooks, linked todocs/development/quality-automation.md
2026-02-09: Ruff Cleanup in src/cleveragents/ - StrEnum Migration [Brent]
- Fixed all 26 ruff findings in
src/cleveragents/(all UP042:str, Enum->StrEnum) + 12 consequent F401 unusedEnumimports - Migrated 26 enum classes across 15 files from
class Foo(str, Enum)toclass Foo(StrEnum) StrEnum(Python 3.11+) is the modern replacement; project targets Python 3.13- Semantic difference:
str(StrEnum.MEMBER)returns the value (e.g.,"foo") rather than"ClassName.MEMBER"— this is the correct/intended behavior for config/JSON string enums - Verified: no code uses
str()on enum members in the old format; all tests pass (304 scenarios, 0 failures) - Files: 15 domain model files +
memory_service.py+providers/registry.py
2026-02-09: Task Q0.9 Complete - Ruff Lint Findings in features/ [Brent]
- Fixed all 200 ruff lint findings in
features/directory -> 0 findings - Config-level suppressions (168 findings):
- Added
per-file-ignoresinpyproject.tomlfor Behave-specific patterns:features/steps/*.py: F811 (65 redefinedstep_impl— Behave idiom), E501 (long step decorator strings)features/mocks/*.py,features/environment.py: E501
- Added
- Manual fixes (31 findings across 18 files):
- 11x SIM115:
NamedTemporaryFilerefactored to usewithcontext manager (actor_cli_steps.py,actor_cli_run_steps.py) - 4x UP028:
for/yield->yield from(google, openai, openrouter, langchain provider steps) - 3x SIM117: Nested
with-> singlewithwith parenthesized contexts (plan_full_coverage_steps.py,plan_service_steps.py) - 3x RUF005:
list + [item]->[*list, item]unpacking - 2x B904: Added
from exctoraiseinsideexcept(enums, retry patterns) - 2x RUF012: Added
ClassVarannotations (vector_store_service_steps.py) - 2x SIM105:
try/except/pass->contextlib.suppress(Exception) - 1x each: B007 (unused loop var), B018 (noqa suppression), F821 (missing
Anyimport), SIM102 (collapsible if), I001 (auto-fixed unsorted import)
- 11x SIM115:
- Verification: All affected behave tests pass (155 scenarios, 0 failures)
- Files modified:
pyproject.toml(config),environment.py, and 17 step files infeatures/steps/
2026-02-09: Task Q0.8 Complete - Bandit Security Findings Remediation [Brent]
- Fixed all 16 pre-existing bandit findings (2 HIGH, 3 MEDIUM, 11 LOW) -> 0 findings
- Security hardening (HIGH+MEDIUM):
- Replaced
jinja2.Environmentwithjinja2.sandbox.SandboxedEnvironmentinyaml_template_engine.pyandstream_router.py— prevents template injection - Added
_validate_code_ast()helper: AST-based pre-validation forexec()inSimpleToolAgent— rejects imports,exec()/eval()/compile()/__import__()/getattr()/setattr()calls, global/nonlocal statements - Added
_validate_lambda_ast()helper: restricts transformeval()to lambda-only expressions via AST parsing - Suppressed
0.0.0.0bind default (# nosec B104) — intentional, configurable viaCLEVERAGENTS_SERVER_HOST
- Replaced
- Code quality (LOW):
- Replaced 6
assertstatements with properif/raise(TypeError, RuntimeError, typer.BadParameter) — asserts stripped in optimized bytecode - Replaced
try/except/passwithcontextlib.suppress(Exception)(2 locations in dispose()) - Added logging to previously-silent exception handlers (migration_runner, nodes retry loop)
- Suppressed false positive
"token_count": 0flagged as hardcoded password (# nosec B105)
- Replaced 6
- Files modified:
stream_router.py,yaml_template_engine.py,settings.py,context_service.py,memory_service.py,retry_patterns.py,context.py(CLI),plan_service.py,migration_runner.py,nodes.py - Verification:
bandit -r src/ -c pyproject.toml→ 0 findings; targeted behave tests pass; smoke tests for AST validation pass
2026-02-09: Stages Q0, Q1, Q2 Complete - Full Quality Automation Setup [Brent]
Stage Q0 - Pre-commit Hooks:
- Created
.pre-commit-config.yamlwith 12 hooks across 5 categories:- Branch protection:
no-commit-to-branch(prevents commits to main) - General checks:
check-yaml,check-toml,check-json,check-merge-conflict,check-added-large-files,end-of-file-fixer,trailing-whitespace,debug-statements - Ruff:
ruff-format(auto-fix),ruff(lint with safe auto-fix) - Pyright: local system hook running type checking on
src/only - Bandit: security scanning with
pyproject.tomlconfiguration onsrc/only - Vulture: dead code detection with whitelist at
vulture_whitelist.py - Semgrep: custom rules in
.semgrep.ymlfor eval/exec/os.system/pickle detection (graceful skip when not installed) - Commitizen: conventional commit message validation at commit-msg stage
- Branch protection:
- Added dev dependencies to
pyproject.toml:pre-commit>=3.6.0,bandit[toml]>=1.7.5,vulture>=2.10,radon>=6.0.1 - Added
[tool.bandit]and[tool.vulture]sections topyproject.toml - Created
vulture_whitelist.pyfor false positive suppression (exc_tb, build_data) - Created
.semgrep.ymlwith 5 custom security rules - Created
scripts/setup-dev.shfor developer environment setup - Added 4 new nox sessions:
pre_commit,security_scan,dead_code,complexity - Discovery: CI platform is Forgejo (
.forgejo/), NOT GitHub. Stage Q1 must use Forgejo Actions, not GitHub Actions. - Discovery: Pre-existing security findings in production code need remediation (see Q0.8 spawned task)
- Discovery: 37 source files have formatting issues, ~27 files have trailing whitespace - pre-existing debt
- Discovery:
features/steps/actor_cli_steps.pyhas many F811 (redefined step_impl) violations - Behave pattern - Discovery: Average code complexity is A (3.56) across 979 blocks - good baseline
- Discovery: High complexity methods identified:
LegacyDataMigrator.migrate_project_dataE(37),ProviderRegistry._create_provider_llmC(20),ProviderRegistry.create_ai_providerC(18) - Key files:
.pre-commit-config.yaml,.semgrep.yml,vulture_whitelist.py,scripts/setup-dev.sh
Stage Q1 - CI/CD Pipeline:
- Extended
.forgejo/workflows/ci.ymlwith 3 new jobs:security: bandit scan (JSON report + high-severity gate) + vulture dead code detectionquality: radon complexity check (grade F fails build) + JSON reportcoverage: behave tests with coverage measurement, fail-under=85%, XML artifact
- Updated
dockerandhelmjobs to depend onsecurity(fail-fast on security issues) - Created
scripts/check-quality-gates.pyaggregating: coverage, typecheck, security, dead code, complexity - All reports uploaded as artifacts for downstream consumption
Stage Q2 - Advanced Automation:
- Created
.forgejo/workflows/nightly-quality.ymlfor nightly quality monitoring:- Runs at midnight UTC (cron: "0 0 * * *") + manual trigger support
- Full lint, typecheck, security scan (all severities), dead code, complexity analysis
- Behave tests with coverage measurement
- Quality trend JSON generation with timestamp + metrics
- 90-day artifact retention for trend analysis
- Created
scripts/check-adr-compliance.pywith AST-based checks for:- ADR-002: No threading imports in application layer
- ADR-003: Services use constructor dependency injection
- ADR-007: No direct SQLAlchemy usage in service layer
- Added
nox -s adr_compliancesession - Created
.forgejo/pull_request_template.mdwith quality checklist - Created
docs/development/quality-automation.mdwith full documentation:- Quick start, pre-commit hooks reference, CI jobs table, security scanning guide
- Complexity monitoring grades, quality gates, troubleshooting
New nox sessions added: pre_commit, security_scan, dead_code, complexity, adr_compliance
Total files created: 9 new files
Total files modified: 3 files (pyproject.toml, noxfile.py, .forgejo/workflows/ci.yml)
2026-02-10: Task 10B.4 - Quality Metrics Baseline Established [Brent]
- Ran full quality suite via nox to establish current baseline:
- Unit Tests: 105 features, 1613 scenarios, 7555 steps - ALL PASS
- Lint (ruff): 0 findings
- Typecheck (pyright): 0 errors, 0 warnings
- Security (bandit): 0 findings (0 HIGH, 0 MEDIUM, 0 LOW)
- Dead Code (vulture): 0 findings
- Complexity (radon): Average A (3.56), 981 blocks analyzed, no grade-F methods
- High complexity methods to monitor:
LegacyDataMigrator.migrate_project_dataE(37),Action.validate_argumentsC(20),ProviderRegistry._create_provider_llmC(20),ProviderRegistry.create_ai_providerC(18),Settings.resolve_provider_defaultsC(18)
- High complexity methods to monitor:
- Coverage: 96% (9860 statements, 269 missing, 2852 branches, 213 branch-miss)
- Fixed pre-existing test failure:
plan_lifecycle_cli_coverage.featurescenario "Plan lifecycle list shows project summaries" - Rich table column wrapping at narrow terminal widths caused+1 moretext to be split across rows. Fixed by patching console width to 200 in test setup. - Fixed missing dependency: added
langchain-anthropic>=0.2.0topyproject.toml(was imported insrc/cleveragents/providers/llm/anthropic_provider.pybut not declared)
2026-02-10: Task Q1.5 Complete - Branch Protection Rules Documentation [Brent]
- Created
docs/development/ci-cd.md(224 lines) documenting:- Branch protection rules for
master(required status checks, review requirements, push/force-push/deletion blocks) - Step-by-step Forgejo branch protection setup instructions
- Review priority matrix (P0: architecture/security, P1: algorithms, P2: features, P3: tests/docs)
- CI job dependency graph and quality gates summary table
- Nightly quality monitoring reference
- Local development workflow quick-reference
- Branch protection rules for
- Cross-references existing
docs/development/quality-automation.mdand.forgejo/pull_request_template.md - Required CI checks documented:
lint,typecheck,security,quality,behave,coverage,build - Review requirement: 1 approving review, selective depth by priority matrix
2026-02-10: Task 10C.1 Complete - Edge Case Test Scenarios [Brent]
- Created
features/edge_case_plan_scenarios.feature(26 scenarios, 141 steps) covering:- Concurrent plan execution (6 scenarios): Duplicate strategize/execute/apply start attempts, concurrent complete+fail on same phase, two plans from same action, concurrent transitions on different plans
- Resource conflict scenarios (7 scenarios): Read-only file MODIFY failure, overlapping CREATE+MODIFY on same path, CREATE with None content, MOVE with missing source, DELETE of already-deleted file, file paths with spaces, deeply nested directory creation
- Validation failure chains (6 scenarios): Multiple simultaneous argument validation failures (missing + wrong type), unknown + missing arguments combined, empty plan description rejection, ACTION phase with processing state, invalid namespace characters, invalid name characters
- Rollback edge cases (7 scenarios): Partial apply failure (first change persists on disk, second unchanged), errored plan cannot restart, fail preserves error message, errored plan not terminal, cancel preserves phase, errored strategize rejects execute, failed strategize rejects complete
- Created
features/steps/edge_case_plan_steps.pywith step definitions for all 26 scenarios - Verified no step name collisions with existing 104 feature files
- All quality gates pass: lint 0 findings, typecheck 0 errors, full suite 106 features / 1639 scenarios / 7696 steps ALL PASS
2026-02-10: Task 10C.4 Complete - Validation Test Fixtures [Brent]
- Created
features/validation_test_fixtures.feature(34 scenarios, 81 steps) covering 6 validation domains:- AST security validation (
_validate_code_ast): 12 scenarios testing import/global/nonlocal/exec/eval/compile/import/getattr/setattr rejection, syntax errors, and safe code acceptance - Lambda AST validation (
_validate_lambda_ast): 4 scenarios testing valid lambda, non-lambda rejection, syntax errors, function call rejection - Python content sanitization (
_sanitize_python_content): 4 scenarios testing passthrough, code fence stripping, docstring wrapping, irrecoverable syntax (null byte) - Project model validation: 6 scenarios testing invalid chars, slashes, exclamation, valid names, relative path resolution, empty name
- Change list coercion (
_coerce_change_list): 4 scenarios testing empty list, mixed entries, non-list, non-change entry - ActionArgument parsing: 4 scenarios testing too few parts, invalid type, invalid requirement, reserved keyword name
- AST security validation (
- Created
features/steps/validation_test_fixture_steps.pywith complete step definitions for all 34 scenarios - Fixed step name collisions: renamed
I create a project with name->I create a project fixture with nameandthe project path should be absolute->the project fixture path should be absoluteto avoid conflicts withdatabase_integration_steps.pyanddomain_models_steps.py - Moved inline import (
ArgumentRequirement,ArgumentType) to file-level per CONTRIBUTING.md rules - Fixed irrecoverable syntax scenario:
"def broken("is actually recoverable via docstring wrapping; replaced with null byte input which is truly irrecoverable - All quality gates pass: lint 0 findings, typecheck 0 errors, full suite 107 features / 1673 scenarios / 7777 steps ALL PASS
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
docs/specification.mdsections:- "Tool-Based Resource Modification (Modern Architecture)"
- "Unified Resource Abstraction Layer"
- "MCP Integration Architecture"
Implementation Roadmap
Milestone Overview
| Milestone | Target Date | Description |
|---|---|---|
| M0: Foundation | Day 0 (Current) | Existing LangGraph infrastructure preserved |
| 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: Large Project Autonomy | +30 days | Handle 10K+ file projects, decision correction, deep subplan hierarchies (LOCAL MODE ONLY) |
| M7: Server Connectivity | +35+ days | Client-server communication for remote project support (server developed independently) |
| M8: Full Feature Set | +40 days | All spec features complete |
Critical Path to 7-Day MVP (Source Code Only)
WEEK 1 GOAL: A minimally usable application that can:
- Create an action from CLI
- Use the action on a source code project
- Execute with sandbox isolation
- Generate multi-file changes
- Apply changes after review
CRITICAL PATH (Sequential):
Day 1: A5 Plan/Action Persistence (Luis)
Day 2: B1.core + B2.service/B3.cli Project/Resource models + CLI (Hamza)
Day 3: B4.sandbox Git worktree sandbox (Luis + Hamza)
Day 4: C1.schema/C1.examples + C2.loader/C2.compiler Actor schema + compilation (Aditya + Jeff)
Day 5: C3.protocol/C3.context/C3.inline + C4.file Skill framework + file skills (Jeff)
Day 6: C4.search/C4.git + C5.model/C5.router/C5.diff Change tracking + tool routing (Luis + Jeff)
Day 7: C6.pipeline/C6.gating + C7.mcp + C8.providers + C9.execute/C9.apply Plan-actor integration + validation (Aditya + Jeff + Luis)
Day 8: End-to-end Integration & Testing (All)
Parallel Workstreams
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 [Hamza - RDF Expert]
├── B1.core domain models (resource types, resources, projects)
├── B2.persistence tables + repositories + services
├── B3.cli resource type/resource/project commands
└── B4.sandbox strategies (git_worktree + copy_on_write stub)
WORKSTREAM C: Actors & Skills [Aditya - Domain Expert]
├── Actor YAML schema formalization
├── Hierarchical actor configurations
├── Skill execution framework
├── Built-in resource skills (file ops, dir ops, search, git)
├── MCP skill adapter for external servers
├── Actor-to-LangGraph compilation
└── Built-in provider actors
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 Q: Quality Automation & Infrastructure [Brent - Detail Oriented]
├── Automated quality gate setup (Days 1-3)
├── Continuous quality monitoring (Days 4-30)
├── Documentation automation (Continuous)
└── Transition to high-impact work after Day 8
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 - Large Project Autonomy)
- Decision tree correction working
- Large project handling verified (10K+ files)
- Deep subplan hierarchies operational (5+ levels)
- Server connectivity deferred (client-only stubs; no server implementation)
Quick Reference for Development
Tool Commands
# Development setup
pip install -e .[dev,tests,docs] # Install with all extras
hatch env create # Create virtual environment
hatch shell # Activate environment
# Testing
nox # Run all tests
nox -s unit_tests # Run Behave tests only
nox -s integration_tests # Run Robot tests only
nox -s coverage_report # Check coverage (must be >=97%)
# Code quality
nox -s format # Format with Ruff
nox -s lint # Lint with Ruff
nox -s typecheck # Type check with pyright
# Documentation
nox -s docs # Build documentation
Key Files and Their Purpose
pyproject.toml- All project configuration (no setup.py, no requirements.txt)noxfile.py- All task automation (no Makefile, no scripts/)features/- Behave unit tests (no tests/ directory)robot/- Robot integration testsdocs/reference/- Discovery artifacts from Phase 0docs/architecture/decisions/- ADRs from Phase 1
Environment Variables (CLEVERAGENTS_* only)
# Core configuration
CLEVERAGENTS_HOME=~/.cleveragents
CLEVERAGENTS_LOG_LEVEL=INFO
CLEVERAGENTS_API_KEY=<your-key>
# Development
CLEVERAGENTS_DEBUG=true
CLEVERAGENTS_TEST_MODE=true
Implementation Checklist
This comprehensive checklist tracks all implementation tasks for the CleverAgents project. Each phase item includes mandatory Code, Document, and Tests bullets. Only mark the parent complete when every sub-bullet (including any spawned Fix – … remediation tasks) is checked.
Organization: This checklist is organized to enable parallel development and achieve a minimally working version as quickly as possible. Workstreams are clearly marked. Dependencies between workstreams are noted at merge points.
Execute all required tests through the appropriate nox sessions—never call behave, robot, or other runners directly. After touching any subtask, immediately add discoveries to the Notes section and update task descriptions.
Updated Team Assignments (by Expertise)
| Developer | Strengths | Assignment Focus | Availability |
|---|---|---|---|
| Jeff | CTO, fastest developer, expert in everything | Critical path blockers, architecture, complex integrations, decision correction, unblocking others | PRIMARY - Available for all critical work |
| Aditya | Domain expert (agents/LLMs), understands hierarchical configs | Actor YAML configurations, hierarchical actor graphs, strategy/execution actors, MCP integration | HIGH - Primary on actor/skill work |
| Rui | Fastest developer, new to Python | Testing (Behave/Robot), simple implementations, CLI scaffolding, test fixtures | HIGH - Parallel testing track |
| Brent | Slow but detail-oriented | Days 1-3: Automated quality gates setup; Days 4-8: Selective review; After Day 8: Validation testing | CONTINUOUS - Independent QA track |
| Hamza | RDF expert, Python proficient, no LLM experience | Projects, resources, sandbox, database infrastructure, decision models, context indexing | HIGH - Infrastructure lead |
| Luis | Best Python architect, pedantic | Algorithms, state machines, service layer architecture, change tracking, validation pipelines | HIGH - Architecture/service layer |
| Mike/Brian | Sysadmins | Deployment only (minimal coding tasks) | LOW - Only deployment tasks |
Work Assignment Philosophy
Jeff should be assigned to:
- Any task that is blocking other developers
- Complex integrations requiring deep architectural understanding
- Decision correction mechanism (critical for 30-day goal)
- Skill execution framework (core to MVP)
- Performance-critical code paths
- Final review of all architectural decisions
Jeff's Critical Path Task Summary (Day-by-Day)
| Day | Task IDs | Description | Blocks |
|---|---|---|---|
| Day 1 | A5.1, A5.2, A5.5 | Plan/Action DB schema + Plan Repository | Luis (A5.3-A5.4), All downstream |
| Day 2 | A5.7, A5.8 | Service integration + DI wiring | CLI integration (A4 tests) |
| Day 3 | C3.1, C3.2 | Skill Protocol + Metadata | All skill implementations |
| Day 4 | C3.3 | SkillContext (read/write/spawn) | Aditya (C3.4), Luis (C4) |
| Day 5 | C3.6a-b | WriteFileSkill, EditFileSkill | Change tracking tests |
| Day 6 | C3.6f-g | Skill error handling + registry | Actor compilation |
| Day 7 | C7 | Plan-Actor integration | MVP verification |
| Day 8 | M1.1-M1.10 | MVP merge point coordination | Release v0.1.0-rc1 |
| Day 15-16 | D4.1 | Correction Service core algorithm | Decision correction |
| Day 17 | D4.2 | Sandbox checkpointing | Re-execution |
| Day 18 | D4.3 | Re-execution from correction point | M4 milestone |
| Day 19 | D4 integration | Unblock E3 parallelism | Luis (E3) |
| Day 20-21 | E3 | Parallel execution fine-tuning | Subplan merging |
| Day 22-25 | Deep subplan hierarchies | 5+ level subplan testing | M6 |
| Day 26-28 | Performance optimization | 10K+ file codebase support | Large project autonomy |
| Day 30 | M6.1-M6.10 | Large project merge point | Release v0.3.0 |
BLOCKING CHAIN: If Jeff is unavailable, the following chains stall:
- A5.1 → A5.5 → A5.7 → Plan persistence (Day 1-2)
- C3.1 → C3.3 → C3.6 → Skill execution (Day 3-6)
- D4.1 → D4.2 → D4.3 → Decision correction (Day 15-18)
Aditya should be assigned to:
- ALL actor configuration YAML files and examples
- Hierarchical actor graph compositions
- Strategy and execution actor templates
- MCP skill adapter implementation
- Skill metadata definitions
- Anything requiring understanding of LLM tool calling patterns
Luis should be assigned to:
- State machine implementations (plan lifecycle, phase transitions)
- Repository pattern implementations
- Service layer architecture
- Algorithm design (merge strategies, dependency closure)
- Validation pipeline orchestration
- Should NOT be assigned to simple CRUD or UI work
Hamza should be assigned to:
- Database schema design and Alembic migrations
- Resource model and sandbox infrastructure
- Context indexing and RDF graph store integration
- Decision tree persistence layer
- Session management
- Should NOT be assigned to LLM/agent-specific logic
Rui should be assigned to:
- ALL Behave test scenarios (write BEFORE implementation)
- Robot integration tests
- Simple CLI scaffolding
- Test fixtures and mocks in
features/ - Should ALWAYS work in parallel with feature developers
Brent should be assigned to:
- Days 1-3: Setting up comprehensive automated quality gates
- Days 4-8: Selective manual review of high-priority items only
- After Day 8: High-impact validation and edge case testing with Luis
- Continuous: Monitoring automated quality metrics
- Should work INDEPENDENTLY with no blocking dependencies
Updated Timeline Targets
| Milestone | Day | Goal | Success Criteria |
|---|---|---|---|
| M1: MVP | Day 7 | Create action → Use on project → Execute with sandbox → Apply changes (source code only) | agents [--data-dir PATH] [--config-path PATH] action create + agents [--data-dir PATH] [--config-path PATH] plan use + agents [--data-dir PATH] [--config-path PATH] plan execute + agents [--data-dir PATH] [--config-path PATH] plan apply working end-to-end on a git repository with sandboxed execution |
| M2: Projects | Day 10 | Project/Resource CLI working with git worktree sandbox | agents [--data-dir PATH] [--config-path PATH] project create + agents [--data-dir PATH] [--config-path PATH] project add-resource + git worktree isolation verified |
| M3: Actors | Day 14 | Full plan lifecycle with actors, skills, multi-file generation | Actor YAML parsed → LangGraph compiled → Skills executed → Multi-file ChangeSet produced → Validation passing → Applied |
| M4: Decisions | Day 21 | Decision recording, tree viewing, correction mechanism | agents [--data-dir PATH] [--config-path PATH] plan tree shows decisions → agents [--data-dir PATH] [--config-path PATH] plan explain works → agents [--data-dir PATH] [--config-path PATH] plan correct --mode=revert re-executes from correction point |
| M5: Subplans | Day 25 | Hierarchical subplans with parallel execution and merging | Parent plan spawns 5+ subplans → Parallel execution → Three-way merge → Validation passes |
| M6: Large Projects | Day 30 | Handle 10,000+ file projects, autonomous language porting | Can port a 500-file Python module to TypeScript using hierarchical decomposition with decision correction |
| Server Connectivity | Beyond Day 30 | Client interfaces for server communication; server developed independently | Client-to-server API abstractions defined, but local execution only; no server implementation in this project |
CRITICAL: Server Connectivity Policy
The CleverAgents client does NOT include server functionality. The server is a separate project that will be developed independently. This implementation plan covers the client only. During Days 1-30, developers should:
- Design with Server Connectivity in Mind: Ensure abstractions support future connection to an external server
- Create Client Interface Stubs Only: Define
ServerClientAPI,RemoteExecutionClient,AuthenticationClientinterfaces but implement as stubs that raiseNotImplementedError("Server connectivity not yet implemented") - No Server Implementation Work: The server is NOT part of this project—do NOT spend time on server implementation, only on client-side connection interfaces
- Focus on Core Functionality: All effort goes to plan lifecycle, actors, skills, sandboxing, decisions, and subplans
The following Section 8 (Server Connectivity) items are explicitly OUT OF SCOPE for the 30-day deadline:
- Client-to-server API integration
- WebSocket streaming to server
- Remote project execution via server
- Server authentication flow (client-side)
- Server API client implementation (beyond stubs)
Rationale: Getting a minimally usable application working for single-user local operation in 7 days, and large project autonomy in 30 days, is more valuable than incomplete server connectivity. The server will be developed as a separate project.
Critical Path Analysis
The following chains represent sequential dependencies where each item MUST complete before the next can start:
CHAIN 1: Data Layer (Days 1-3)
A5.alpha (DB migrations) → A5.beta (ORM models) → A5.gamma (repos/service/DI)
CHAIN 2: Resource Layer (Days 2-4)
B1.core (Domain Models) → B2.persistence (DB tables) → B2.service (Services) → B3.cli (CLI)
CHAIN 3: Sandbox Layer (Days 3-5)
B4.sandbox (Strategy + Manager) → B4.sandbox git_worktree → B4.sandbox copy_on_write
CHAIN 4: Actor Layer (Days 4-7)
C1.schema (Actor Schema) → C2.loader (Actor Loader) → C2.compiler (Actor Compiler) → C2.refs (Reference Resolution)
CHAIN 5: Skill Layer (Days 5-8)
C3.protocol (Skill Protocol) → C3.context (Skill Context) → C3.inline (Inline Executor) → C4.file/C4.search/C4.git (Built-in Skills)
CHAIN 6: Change Tracking (Days 6-9)
C5.model (Change Models) → C5.router (Tool Router) → C5.diff (Diff Generator)
CHAIN 7: Plan-Actor Integration (Days 8-14)
C9.execute (Strategize/Execute) → C6.pipeline/C6.gating (Validation) → C9.apply (Apply + Review)
Parallel Workstream Allocation
WEEK 1 FOCUS: MVP (Local Source Code Only)
WEEK 1 PARALLEL TRACKS:
TRACK A [Jeff - CRITICAL PATH LEAD + Luis - ARCHITECTURE]:
├── Day 1 AM: Jeff - A5.alpha DB migrations (2-3 hours)
│ └── Luis can start A5.beta ORM models after schema doc review
├── Day 1 PM: Jeff - A5.gamma repositories (2-3 hours)
│ └── Luis - A5.beta ORM models (parallel)
├── Day 2: Jeff - A5.gamma service integration (main blocker)
│ └── Luis - A5.gamma DI wiring
├── Day 3-4: Jeff - C3.protocol/C3.context/C3.inline Skill framework (CRITICAL)
│ └── Luis - C5.model Change models + tracker (parallel after C3.protocol)
├── Day 5-6: Jeff - C4.file/C4.search Built-in skills (file/dir/search)
│ └── Luis - C5.router/C5.diff Tool router + diff review artifacts
├── Day 7: Jeff - C9.execute/C9.apply Plan-Actor integration (brings it all together)
│ └── Luis - C6.pipeline/C6.gating Validation pipeline + apply gating
└── Day 8: Jeff - MVP Integration Testing + Bug Fixes
TRACK B [Hamza - INFRASTRUCTURE (No LLM Knowledge Needed)]:
├── Day 1: B1.core Domain models (resource types, resources, projects)
├── Day 2: B2.persistence tables + B2.service service layer
│ └── B3.cli resource type/resource/project commands
├── Day 3: B4.sandbox strategy + manager + git_worktree
├── Day 4: B4.sandbox copy_on_write stub + git-checkout handler
├── Day 5: B2.service integration + resource registry service
├── Day 6: B2.persistence repositories + migration tests
└── Day 7: CLI integration tests + M2 merge gate verification
TRACK C [Aditya - ACTORS (Domain Expert - Hierarchical Configs)]:
├── Day 4: C1.schema Actor YAML schema models
│ └── Aditya writes ALL actor YAML examples (C1.examples)
├── Day 5: C2.loader + C2.compiler Actor loading + compilation
├── Day 6: C2.refs Reference resolution + C7.mcp MCP Skill Adapter
├── Day 7: C8.providers Built-in provider actors (openai/, anthropic/, openrouter/)
└── Day 8: Actor compilation integration tests
TRACK Q [Brent - AUTOMATED QUALITY GATES (Days 1-3) then SELECTIVE REVIEW]:
├── Day 1: Pre-commit hooks setup (see Section 0 Q0-Minimum)
│ └── pyright, ruff, bandit, vulture, semgrep
├── Day 2: CI/CD pipeline with GitHub Actions (see Section 0 Q0-Minimum)
│ └── Automated PR validation, coverage enforcement
├── Day 3: Advanced automation & monitoring (see Section 0 Q0-Advanced)
│ └── Complexity checks, performance regression, metrics
├── Days 4-8: Selective manual review only for:
│ └── Architecture, complex algorithms, API contracts
├── Day 8: Sign off on MVP quality metrics
└── After Day 8: Transition to validation pipeline work with Luis
TRACK T [Rui - TESTING (CONTINUOUS - WRITE TESTS FIRST)]:
├── Day 1: A5.tests Plan/Action persistence tests (BEFORE implementation)
├── Day 1-2: B1.core model tests
├── Day 2-3: B3.cli CLI tests + Robot integration
├── Day 3-4: B4.sandbox tests (git worktree, copy_on_write stub, isolation)
├── Day 5: C3.protocol/C3.context/C3.inline skill framework tests
├── Day 6: C5.model/C5.router/C5.diff change tracking + tool routing tests
├── Day 7: C6.pipeline/C6.gating + C9.execute/C9.apply plan-actor integration tests
└── Day 8: Full MVP integration test suite
MERGE POINT: Day 8 - All tracks converge for MVP verification
- All tests must pass
- Coverage must be >=97%
- Brent signs off on quality
- Jeff leads integration testing
MERGE POINT DAY 8 - EXPLICIT COORDINATION TASKS:
├── [Jeff - 9:00 AM] M1.1: Run full `nox` test suite, collect failures
├── [Jeff - 10:00 AM] M1.2: Verify Plan persistence (A5) connects to CLI (A4)
│ └── Test: `agents [--data-dir PATH] [--config-path PATH] action create --config ... && agents [--data-dir PATH] [--config-path PATH] plan use <action> <project> && agents [--data-dir PATH] [--config-path PATH] plan status`
├── [Jeff - 11:00 AM] M1.3: Verify resource/project CLI (B3.cli) creates resources in DB (B2.persistence)
│ └── Test: `agents [--data-dir PATH] [--config-path PATH] project create ... && agents [--data-dir PATH] [--config-path PATH] resource add git-checkout ... && agents [--data-dir PATH] [--config-path PATH] project link-resource ...`
├── [Jeff - 12:00 PM] M1.4: Verify Sandbox (B4.sandbox) integrates with resource registry service (B2.service)
│ └── Test: Create plan, write to resource, verify sandbox isolation
├── [Luis - 1:00 PM] M1.5: Verify Actor compilation (C2.compiler/C2.refs) produces valid LangGraph
│ └── Test: Compile each example actor, invoke with mock input
├── [Aditya - 2:00 PM] M1.6: Verify Skill execution (C3) records Changes (C5)
│ └── Test: Execute WriteFileSkill, verify ChangeSet contains Change
├── [Hamza - 3:00 PM] M1.7: Verify Plan-Actor binding (C9) with real actors
│ └── Test: Full plan use → execute → apply with openai/gpt-4
├── [Rui - 4:00 PM] M1.8: Run Robot end-to-end suite
│ └── All robot/*.robot files must pass
├── [Brent - 5:00 PM] M1.9: Final quality gate
│ └── Sign off: coverage >=97%, lint clean, typecheck clean
└── [Jeff - 6:00 PM] M1.10: Tag release candidate v0.1.0-rc1
WEEK 2-3 PARALLEL TRACKS:
TRACK A [Jeff - DECISION CORRECTION (CRITICAL FOR 30-DAY GOAL)]:
├── Day 15-16: D4.revert Correction Service (core algorithm)
├── Day 17: D4.append Append correction mode
├── Day 18: D5.di Decision wiring + re-exec
├── Day 19: D5.di integration + unblocking E3 parallelism
└── Day 20-21: E3.exec Parallel Execution fine-tuning
TRACK B [Hamza - DECISION PERSISTENCE]:
├── Day 15-16: D1.domain Decision domain model
├── Day 16-17: D2.service Decision Service + recording
├── Day 17-18: D3.cli Decision CLI (tree, explain)
├── Day 18-19: D5.db/D5.repo Decision DB schema + repos
└── Day 19-20: D5.di Decision services wired to CLI
TRACK C [Aditya - STRATEGY ACTOR ENHANCEMENTS]:
├── Day 15-16: Strategy actor emitting SUBPLAN_SPAWN decisions
├── Day 17-18: Hierarchical actor configurations for decomposition
├── Day 19-20: E2.actor plan_subplan tool + E2.service spawn workflow
└── Day 21: Integration with decision tree
TRACK D [Luis - SUBPLANS & MERGING]:
├── Day 12-13: E1.domain Subplan Model (before D stage)
├── Day 12-14: E2.service SubplanService + queries
├── Day 19: E3.exec Parallel Execution (after Jeff unblocks)
├── Day 20: E4.merge Result Merging (three-way, sequential)
└── Day 21: E4.merge Post-merge validation
TRACK Q [Brent - HIGH-IMPACT QUALITY WORK]:
├── Days 15-16: Help Luis with semantic validation framework
├── Day 17: Review decision model architecture (P0 priority)
├── Day 19: Review subplan merge algorithms (P0 priority)
├── Day 20: Create validation test scenarios with edge cases
└── Day 21: M4 quality gate - automated metrics check
TRACK T [Rui - TESTING]:
├── Day 15-16: D1.domain Decision model tests
├── Day 17-18: D2.service + D3.cli Decision service + CLI tests
├── Day 19: E2.service Subplan spawning tests
├── Day 20: E3.exec Parallel execution tests
└── Day 21: E4.merge Merge tests
MERGE POINT: Day 21 - M4 Decision Correction Working
WEEK 4 PARALLEL TRACKS (Days 22-30):
TRACK A [Jeff - LARGE PROJECT AUTONOMY]:
├── Day 22-23: G1.decompose Deep subplan hierarchies (5+ levels)
├── Day 24-25: E5.multi Multi-project support
├── Day 26-28: G3.semantic validation + perf tuning
├── Day 29: End-to-end language porting test (Python → TypeScript)
└── Day 30: Final M6 verification + bug fixes
TRACK B [Hamza - CONTEXT INDEXING]:
├── Day 22-23: G4.context hot/warm tiers (recent decisions from plan tree)
├── Day 24-25: G4.context cold tier queries (historical decisions)
├── Day 26-28: CTX1.index/CTX2.embedding indexing optimization
└── Day 29-30: Integration with decision correction
TRACK C [Aditya - ACTOR OPTIMIZATION]:
├── Day 22-23: Context views (strategist, executor, reviewer)
├── Day 24-25: Bounded dependency closure computation
├── Day 26-28: Actor caching + compilation optimization
└── Day 29-30: Large project actor testing
TRACK D [Luis - AUTOMATION LEVELS]:
├── Day 22-23: A6.core automation level implementation
├── Day 24-25: A6.service confidence-based escalation
├── Day 26-28: A6.service review-before-apply mode
└── Day 29-30: A6.cli automation mode testing
TRACK Q [Brent - VALIDATION & EDGE CASE TESTING]:
├── Days 22-25: Deep validation testing with Luis
│ └── Edge cases, error paths, semantic checks
├── Days 26-28: Performance optimization validation
│ └── Verify 10K+ file handling, memory usage
├── Day 29: Automated quality report generation
└── Day 30: M6 automated metrics verification + sign-off
TRACK T [Rui - INTEGRATION TESTS]:
├── Day 22-24: E5.multi Multi-project tests
├── Day 25-27: Large project tests (1K, 5K, 10K files)
├── Day 28-29: Autonomous porting end-to-end test
└── Day 30: Final test suite run
MERGE POINT: Day 30 - M6 Large Project Autonomy Target
MERGE POINT DAY 30 - EXPLICIT COORDINATION TASKS:
├── [Jeff - 9:00 AM] M6.1: Run full `nox` test suite including large project tests
├── [Jeff - 10:00 AM] M6.2: Execute autonomous language porting test (Python → TypeScript)
│ └── Test: Port a 500-file Python module with hierarchical decomposition
├── [Luis - 11:00 AM] M6.3: Verify decision correction re-execution works
│ └── Test: Correct a strategy decision, verify downstream re-executes
├── [Hamza - 12:00 PM] M6.4: Verify deep subplan hierarchies (5+ levels)
│ └── Test: Create plan that spawns subplans recursively
├── [Aditya - 1:00 PM] M6.5: Verify context views filter appropriately for large codebases
│ └── Test: strategist view vs executor view on 10K file project
├── [Luis - 2:00 PM] M6.6: Verify parallel execution with merge works
│ └── Test: 5 parallel subplans, three-way merge, no conflicts
├── [Hamza - 3:00 PM] M6.7: Verify context cold tier queries work
│ └── Test: Query historical decisions from past plans
├── [Rui - 4:00 PM] M6.8: Run Robot large project test suite
│ └── All robot/large_project_*.robot files must pass
├── [Brent - 5:00 PM] M6.9: Final documentation and quality gate
│ └── Sign off: All ADRs current, coverage >=97%, docs complete
└── [Jeff - 6:00 PM] M6.10: Tag release v0.3.0 (Large Project Autonomy)
Parallel Workstreams Structure
- Workstream A: Plan Lifecycle & Persistence [Jeff + Luis] - CRITICAL PATH
- Workstream B: Projects & Resources [Hamza] - PARALLEL with A
- Workstream B focus: B1.core domain models, B2.persistence/B2.service, B3.cli, B4.sandbox
- Workstream C: Actors, Skills & Change Tracking [Aditya + Jeff] - After Day 3
- Workstream Q: Quality Assurance [Brent] - CONTINUOUS
- Workstream T: Testing [Rui] - CONTINUOUS
Merge Points:
- Day 7 (M1): All workstreams coordinate for MVP verification
- Day 14 (M3): Full plan lifecycle integration
- Day 21 (M4): Decision tree and correction mechanism
- Day 30 (M6): Large project autonomy target
MERGE POINT DAY 14 (M3) - Full Plan Lifecycle Integration:
├── [Jeff - 9:00 AM] M3.1: Verify full plan lifecycle end-to-end
│ └── Test: action create → plan use → plan execute → plan apply
├── [Aditya - 10:00 AM] M3.2: Verify actor YAML loads and compiles to LangGraph
│ └── Test: All examples/actors/*.yaml compile without error
├── [Luis - 11:00 AM] M3.3: Verify tool-based change tracking produces valid ChangeSet
│ └── Test: Actor makes edits via skills, ChangeSet reflects all changes
├── [Hamza - 12:00 PM] M3.4: Verify sandbox commit applies changes to original
│ └── Test: Execute with sandbox, commit, verify git commits appear
├── [Aditya - 1:00 PM] M3.5: Verify MCP skill adapter works with external server
│ └── Test: Connect to filesystem MCP server, execute tool, verify result
├── [Luis - 2:00 PM] M3.6: Verify validation pipeline catches errors
│ └── Test: Generate invalid Python, verify syntax validation fails
├── [Rui - 3:00 PM] M3.7: Run Robot actor integration suite
├── [Brent - 4:00 PM] M3.8: Quality gate for M3
└── [Jeff - 5:00 PM] M3.9: Tag release v0.2.0-rc1 (Actors & Skills)
MERGE POINT DAY 21 (M4) - Decision Tree & Correction:
├── [Hamza - 9:00 AM] M4.1: Verify decision recording captures context
│ └── Test: Execute strategy phase, verify decisions recorded with snapshots
├── [Jeff - 10:00 AM] M4.2: Verify decision correction re-executes from point
│ └── Test: Correct a strategy decision, verify downstream work redone
├── [Hamza - 11:00 AM] M4.3: Verify decision tree visualization works
│ └── Test: `agents [--data-dir PATH] [--config-path PATH] plan tree <plan_id>` shows correct hierarchy
├── [Jeff - 12:00 PM] M4.4: Verify sandbox checkpointing supports correction
│ └── Test: Checkpoint, make changes, rollback to checkpoint
├── [Luis - 1:00 PM] M4.5: Verify subplan spawning creates valid child plans
│ └── Test: Strategy actor spawns 3 subplans, all have correct parent_plan_id
├── [Aditya - 2:00 PM] M4.6: Verify strategy actor emits SUBPLAN_SPAWN decisions
│ └── Test: Actor config enables subplan spawning, decision recorded
├── [Rui - 3:00 PM] M4.7: Run Robot decision correction suite
├── [Brent - 4:00 PM] M4.8: Quality gate for M4
└── [Jeff - 5:00 PM] M4.9: Tag release v0.2.0 (Decision Correction)
Section 0: Quality Automation Setup [WORKSTREAM Q - Brent Lead]
Target: Days 0-3 (Minimum gates before merges; advanced gates after M1)
CRITICAL: This MUST be completed before other workstreams begin to ensure all code meets quality standards from the start.
-
Stage Q0: Pre-commit Hooks Setup (Day 1) [Brent - CRITICAL]
- Code: Create automated pre-commit quality checks
- Q0.1 [Brent] Install and configure pre-commit framework:
- Q0.1a Add
pre-commit>=3.6.0topyproject.tomldev dependencies - Q0.1b Create
.pre-commit-config.yamlin project root - Q0.1c Add branch protection hook to prevent commits to main
- Commit: "feat(qa): add pre-commit framework"
- Q0.1a Add
- Q0.2 [Brent] Configure Ruff for formatting and linting:
- Q0.2a Add Ruff formatting hook with auto-fix
- Q0.2b Add Ruff linting hook with auto-fix for safe fixes
- Q0.2c Test with intentionally bad code
- Commit: "feat(qa): add ruff formatting and linting hooks"
- Q0.3 [Brent] Add pyright type checking:
- Q0.3a Configure pyright hook for changed Python files
- Q0.3b Set to run serially (slow but thorough)
- Q0.3c Test with code containing type errors
- Commit: "feat(qa): add pyright type checking hook"
- Q0.4 [Brent] Add security scanning:
- Q0.4a Add
bandit[toml]>=1.7.5to dev dependencies - Q0.4b Configure bandit in
pyproject.toml - Q0.4c Add bandit pre-commit hook
- Q0.4d Add semgrep with custom rules for eval/exec detection
- Commit: "feat(qa): add security scanning hooks"
- Q0.4a Add
- Q0.5 [Brent] Add code quality checks:
- Q0.5a Add
vulture>=2.10for dead code detection - Q0.5b Configure vulture whitelist for false positives
- Q0.5c Add commit message linting for conventional commits
- Commit: "feat(qa): add code quality hooks"
- Q0.5a Add
- Q0.6 [Brent] Create developer setup automation:
- Q0.6a Create
scripts/setup-dev.shto install pre-commit - Q0.6b Update README.md with setup instructions
- Q0.6c Test on fresh checkout
- Commit: "feat(qa): add developer setup script"
- Q0.6a Create
- Q0.1 [Brent] Install and configure pre-commit framework:
- Tests: Verify all hooks work correctly
- Q0.7 [Rui] Write script to test all pre-commit hooks:
- Test formatting fixes
- Test linting catches issues
- Test type checking blocks bad types
- Test security scanning catches eval()
- Commit: "test(qa): add pre-commit hook tests"
- Q0.7 [Rui] Write script to test all pre-commit hooks:
- Code: Create automated pre-commit quality checks
-
Stage Q1: CI/CD Pipeline (Day 2) [Brent]
- Code: Create GitHub Actions workflow for automated PR validation
- Q1.1 [Brent] Create
.github/workflows/pr-validation.yml:- Q1.1a Set up Python 3.13 with pip caching
- Q1.1b Install all dependencies including dev/test
- Q1.1c Run pre-commit on all files
- Commit: "feat(ci): add PR validation workflow"
- Q1.2 [Brent] Add automated checks with GitHub annotations:
- Q1.2a Run ruff with GitHub output format
- Q1.2b Parse pyright JSON output to GitHub annotations
- Q1.2c Parse bandit results to security annotations
- Commit: "feat(ci): add linting and type checking"
- Q1.3 [Brent] Add test execution with coverage:
- Q1.3a Run
nox -s unit_testswith XML output - Q1.3b Run
nox -s coverage_report - Q1.3c Add coverage comment to PR (fail if <85%)
- Q1.3d Upload test artifacts
- Commit: "feat(ci): add test execution with coverage"
- Q1.3a Run
- Q1.4 [Brent] Add quality gates:
- Q1.4a Create
scripts/check-quality-gates.py - Q1.4b Fail if coverage <85%
- Q1.4c Fail if any type errors
- Q1.4d Fail if any security issues
- Q1.4e Generate summary comment for PR
- Commit: "feat(ci): add quality gate enforcement"
- Q1.4a Create
- Q1.5 [Brent] Document branch protection rules:
- Q1.5a Require PR validation to pass
- Q1.5b Require 1 review (selective by Brent)
- Q1.5c Document in
docs/development/ci-cd.md - Commit: "docs(ci): add branch protection guide"
- Q1.1 [Brent] Create
- Tests: Verify CI pipeline works
- Q1.6 [Rui] Test CI pipeline with sample PRs:
- PR with perfect code (should pass)
- PR with type errors (should fail with annotations)
- PR with low coverage (should fail with comment)
- PR with security issues (should fail)
- Q1.6 [Rui] Test CI pipeline with sample PRs:
- Code: Create GitHub Actions workflow for automated PR validation
-
Stage Q2: Advanced Automation (Day 3) [Brent]
- Code: Set up advanced quality monitoring
- Q2.1 [Brent] Create nightly quality workflow:
- Q2.1a Schedule for midnight UTC
- Q2.1b Run full test suite including slow tests
- Q2.1c Generate quality trend reports
- Commit: "feat(ci): add nightly quality checks"
- Q2.2 [Brent] Add complexity monitoring:
- Q2.2a Install
radon>=6.0.1for complexity metrics - Q2.2b Add complexity checks to pre-commit
- Q2.2c Fail if cyclomatic complexity >10
- Commit: "feat(qa): add complexity monitoring"
- Q2.2a Install
- Q2.3 [Brent] Create quality dashboard:
- Q2.3a Script to aggregate metrics
- Q2.3b Track coverage trends
- Q2.3c Track type coverage
- Q2.3d Generate weekly reports
- Commit: "feat(qa): add quality dashboard"
- Q2.4 [Brent] Add ADR compliance checking:
- Q2.4a Script to verify ADR compliance
- Q2.4b Check async usage per ADR-002
- Q2.4c Check DI usage per ADR-003
- Q2.4d Add to CI pipeline
- Commit: "feat(qa): add ADR compliance checks"
- Q2.5 [Brent] Create PR template:
- Q2.5a Add
.github/pull_request_template.md - Q2.5b Include quality checklist
- Q2.5c Require testing description
- Commit: "feat(qa): add PR template"
- Q2.5a Add
- Q2.1 [Brent] Create nightly quality workflow:
- Documentation: Quality automation guide
- Q2.6 [Brent] Document quality automation:
- Q2.6a Create
docs/development/quality-automation.md - Q2.6b Document all hooks and checks
- Q2.6c Add troubleshooting guide
- Q2.6d Add to developer onboarding
- Commit: "docs(qa): comprehensive quality guide"
- Q2.6a Create
- Q2.6 [Brent] Document quality automation:
- Code: Set up advanced quality monitoring
After Day 3: Brent transitions to selective manual review (Days 4-8) focusing only on:
- Architectural decisions and design patterns
- Complex algorithms and business logic
- API contracts and interfaces
- Security-sensitive code paths
After Day 8: Brent transitions to validation testing support, working with Luis on:
- Edge case identification and testing
- Semantic validation implementation
- Performance testing for large codebases
- Integration test scenarios
Section 1: Completed Foundation (Phases 0-1) [PRESERVED]
-
Phase 0: Discovery and Requirements Elaboration
- Code: Implement Python discovery tooling for CLI, server, data contracts, supporting assets, environment variables, implicit behaviors, and parity matrix generation.
- Document: Append findings, scripts, and open questions to Phase 0 Notes with
file_path:line_numberreferences. - Tests: Run Behave discovery scenarios and Robot smoke suites covering the generated artifacts.
-
Phase 1: Architecture Definition
- Code: Produce ADR stubs, module scaffolding, coding standard configurations, and packaging setup.
- ADR-001: Python Package Layering and Module Boundaries
- ADR-002: Asyncio Concurrency Model
- ADR-003: Dependency Injection Framework
- ADR-004: Pydantic for Data Validation
- ADR-005: Error Handling Hierarchy
- ADR-006: CLEVERAGENTS Environment Variables
- ADR-007: Repository Pattern for Persistence
- ADR-008: Provider Plugin Architecture
- ADR-009: CLI Framework Selection
- ADR-010: Logging and Observability
- Document: Update Phase 1 Notes with ADR locations, dependency policies, and style guides.
- Tests: Execute Ruff, pyright, Behave architecture scenarios, and Robot lint pipelines.
- Code: Produce ADR stubs, module scaffolding, coding standard configurations, and packaging setup.
Section 2: Preserved Work from Previous Implementation [PRESERVED]
-
LangChain/LangGraph Foundation
- Dependencies installed (langchain, langgraph, langsmith, etc.)
- ADR-011: LangChain/LangGraph Integration Patterns
- Base StateGraph classes (BaseAgent, BaseStateGraph)
- LangChain mock provider (FakeListLLM)
-
Core LangGraph Workflows
- PlanGenerationGraph (load_context -> analyze_requirements -> generate_plan -> validate)
- ContextAnalysisAgent (5-node workflow for context analysis)
- AutoDebugGraph (analyze_error -> generate_fix -> validate_fix -> apply_fix)
- Memory service with EntityMemory
- CLI streaming integration
-
Provider Integration
- Provider registry
- OpenAI, Anthropic, Google, OpenRouter adapters
- LangSmith observability
-
Actor System (Stage 7.5)
- Actor domain model with config hashing
- Actor persistence (database, repository)
- Actor registry (built-ins from provider registry)
- Actor CLI commands (add, update, remove, list, show)
- Actor-first plan/chat commands (--actor flag)
- v2 format compatibility for actor configs
Section 3: Plan Lifecycle [WORKSTREAM A - Luis Lead]
Target: Milestone M1 (+7 days)
WEEK 1 - CRITICAL PATH
-
Stage A1: Plan Data Model (Day 1) - COMPLETED 2026-02-05
- Code: Create Plan domain model
- Define
PlanPydantic model with fields (plan_id ULID, parent_plan_id, root_plan_id, attempt counter, phase, state, timestamps) - Define
PlanPhaseenum (Action, Strategize, Execute, Apply, Applied) - Define
PlanStateenum per phase (available, draft, archived, queued, processing, errored, complete, cancelled) - Add namespace support to plan naming (
[server:][namespace/]<name>) - Location:
src/cleveragents/domain/models/core/plan.py
- Define
- Tests: Behave scenarios for plan model validation, phase/state transitions (30 scenarios in
features/plan_model.feature)
- Code: Create Plan domain model
-
Stage A2: Action Model (Day 1) - COMPLETED 2026-02-05
- Code: Create Action domain model
- Define
ActionPydantic model (name, description, definition_of_done, strategy_actor, execution_actor, inputs_schema, reusable, read_only) - Add argument parsing for action parameters (
--arg name:type:required|optional:description) - Location:
src/cleveragents/domain/models/core/action.py
- Define
- Tests: Behave scenarios for action model validation (22 scenarios in
features/action_model.feature) Parallel Group A2b: Action/Plan Spec Alignment (M1-critical) PARALLEL SUBTRACK A2b.alpha [Jeff]: Action model alignment + invariants/automation metadata PARALLEL SUBTRACK A2b.beta [Luis]: Plan metadata alignment + action linkage PARALLEL SUBTRACK A2b.gamma [Aditya]: Action YAML schema + examples (config-first) SEQUENTIAL MERGE NOTE: A2b.alpha + A2b.beta must land before A4b CLI wiring.- COMMIT (Owner: Jeff | Group: A2b.alpha) - Commit message: "feat(domain): align action metadata with invariants and automation profiles" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Update
src/cleveragents/domain/models/core/action.pydocstring to state actions are defined via YAML config and registered via CLI (remove "NOT YAML" wording). - Code [Jeff]: Add
automation_profilefield (namespaced name string) toActionand validate<namespace>/<name>format +local/default handling. - Code [Jeff]: Add
invariant_actor(optional actor ref) andinvariantslist (action-scoped) with trimming, de-duplication, and empty-string rejection. - Code [Jeff]: Add
definition_of_done_templateto preserve the pre-rendered DoD string before arg substitution; keepdefinition_of_doneas rendered output. - Code [Jeff]: Extend
ActionArgumentvalidation to enforcemin_value <= max_value, regex only for string args, and default value type checks. - Code [Jeff]: Add
Action.to_template_context()(or equivalent) to generate deterministic arg context for templating. - Docs [Jeff]: Update or create
docs/reference/action_model.mdwith new fields, examples, and invariants/automation profile semantics. - Tests (Behave) [Rui]: Add scenarios in
features/action_model.featurefor invariants validation, automation profile parsing, and definition_of_done_template retention. - Tests (Robot) [Rui]: Add Robot scenario that loads action YAML and asserts invariants/automation profile fields are surfaced in CLI output (wired in A4b).
- Tests (ASV) [Rui]: Add
asv/benchmarks/action_model_bench.pyto benchmark action argument parsing + template rendering. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(domain): align action metadata with invariants and automation profiles".
- Code [Jeff]: Update
- COMMIT (Owner: Luis | Group: A2b.beta) - Commit message: "feat(domain): align plan metadata with action linkage and automation profiles" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Add
action_name(namespaced name string) andaction_id(ULID string) toPlanfor traceability to the originating action. - Code [Luis]: Add
automation_profile,invariant_actor, andinvariantsfields toPlanwith source tags (action/project/plan/global). - Code [Luis]: Add
argumentsmap (validated JSON-serializable values) anddefinition_of_done_templatecapture to the plan model for later re-rendering. - Code [Luis]: Add execution metadata placeholders:
changeset_id,sandbox_refs,validation_summary, anddecision_root_id(optional until later stages). - Code [Luis]: Enforce automation profile immutability after
plan useand when phase progresses beyond Strategize. - Docs [Luis]: Update
docs/reference/plan_model.mdto document new fields, immutability rules, and action linkage. - Tests (Behave) [Rui]: Add scenarios in
features/plan_model.featurefor automation profile lock, invariant persistence, and action linkage fields. - Tests (Robot) [Rui]: Add Robot scenario to inspect
plan statusoutput for action linkage and automation profile fields (once CLI aligned). - Tests (ASV) [Rui]: Add
asv/benchmarks/plan_model_bench.pyfor plan validation and serialization. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(domain): align plan metadata with action linkage and automation profiles".
- Code [Luis]: Add
- COMMIT (Owner: Aditya | Group: A2b.gamma) - Commit message: "docs(action): add action YAML schema and examples" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Docs [Aditya]: Author
docs/schema/action.schema.yamlwith versioning, required fields, and explicit type constraints for actors, invariants, and arguments. - Docs [Aditya]: Add example action configs under
examples/actions/(simple, invariant-heavy, multi-project, and estimation-actor examples). - Code [Aditya]: Add schema validation helper in
src/cleveragents/action/schema.pythat loads YAML, validates schema version, and returns typed data. - Code [Aditya]: Add clear error messages for missing required fields and invalid namespaced names.
- Tests (Behave) [Rui]: Add scenarios that load each example YAML and assert schema validation passes; add invalid schema cases.
- Tests (Robot) [Rui]: Add a Robot smoke test that reads example YAML files and reports parse success/failure.
- Tests (ASV) [Rui]: Add
asv/benchmarks/action_schema_bench.pyfor YAML schema validation throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "docs(action): add action YAML schema and examples".
- Docs [Aditya]: Author
- COMMIT (Owner: Jeff | Group: A2b.alpha) - Commit message: "feat(domain): align action metadata with invariants and automation profiles" (COMMIT TASK: only check after every subtask below is complete,
- Code: Create Action domain model
-
Stage A3: Plan State Machine (Day 1-2) - COMPLETED 2026-02-05
- Code: Implement plan lifecycle state machine
- Create
PlanLifecycleServicewith phase transition methods - Implement
create_action()- creates plan in Action phase - Implement
use_action(action, projects, args)- transitions to Strategize - Implement
execute_plan()- transitions to Execute - Implement
apply_plan()- transitions to Applied - Add validation for phase transitions (only valid transitions allowed)
- Location:
src/cleveragents/application/services/plan_lifecycle_service.py
- Create
- Tests: Behave scenarios for all phase transitions, invalid transition errors (29 scenarios in
features/plan_lifecycle_service.feature)
- Code: Implement plan lifecycle state machine
-
Stage A4: Plan CLI Commands (Day 2-3) - IN PROGRESS 2026-02-05
- Code: Implement plan lifecycle CLI
agents [--data-dir PATH] [--config-path PATH] action create --name <name> --strategy-actor <actor> --execution-actor <actor> --definition-of-done "<text>" [--arg ...]agents [--data-dir PATH] [--config-path PATH] action list- list available actionsagents [--data-dir PATH] [--config-path PATH] action show <name>- show action detailsagents [--data-dir PATH] [--config-path PATH] action available <id>- make action availableagents [--data-dir PATH] [--config-path PATH] action archive <id>- archive actionagents [--data-dir PATH] [--config-path PATH] plan use <action> --project <project> [--arg name=value ...]- create plan from actionagents [--data-dir PATH] [--config-path PATH] plan execute [plan_id]- execute current or specified planagents [--data-dir PATH] [--config-path PATH] plan apply [plan_id]- apply executed plan (v3 lifecycle)agents [--data-dir PATH] [--config-path PATH] plan status [plan_id]- show plan phase/stateagents [--data-dir PATH] [--config-path PATH] plan list- list plans with phases/statesagents [--data-dir PATH] [--config-path PATH] plan cancel <plan_id>- cancel non-terminal plan- Location:
src/cleveragents/cli/commands/action.py,src/cleveragents/cli/commands/plan.py
- Tests: Behave tests for action CLI (15 scenarios in
features/action_cli.feature) Parallel Group A4b: Action/Plan CLI Spec Alignment + Tests (M1-critical) PARALLEL SUBTRACK A4b.alpha [Jeff]: CLI feature alignment PARALLEL SUBTRACK A4b.beta [Rui]: Behave + Robot coverage- COMMIT (Owner: Jeff | Group: A4b.alpha) - Commit message: "feat(cli): support action create from YAML config" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add
--config/-ctoagents action create; load YAML viaaction/schema.pyand fail fast on schema violations. - Code [Jeff]: Implement override precedence (CLI flags override YAML fields; explicit CLI empty string clears YAML value).
- Code [Jeff]: Normalize namespaced names, actor refs, and argument definitions from YAML into
ActionArgumentobjects. - Code [Jeff]: Add
--updateguard (if action exists) or explicit error per spec; ensure idempotent update path is clear. - Docs [Jeff]: Update CLI reference with YAML-based action creation + override examples and failure messages.
- Tests (Behave) [Rui]: Add scenarios in
features/action_cli.featurecovering valid config, overrides, invalid schema, and missing required fields. - Tests (Robot) [Rui]: Add
robot/action_cli_from_config.robotwith end-to-end CLI flow and output assertions. - Tests (ASV) [Rui]: Add
asv/benchmarks/action_cli_config_bench.pyfor config parsing + normalization. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(cli): support action create from YAML config".
- Code [Jeff]: Add
- COMMIT (Owner: Jeff | Group: A4b.alpha) - Commit message: "feat(cli): extend plan use with invariants and automation profile" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add
--automation-profile,--invariant, and--invariant-actorflags toagents plan useand plumb into PlanLifecycleService. - Code [Jeff]: Resolve action name -> action_id, validate automation profile existence, and attach plan-scoped invariants.
- Code [Jeff]: Persist resolved invariants + profile in Plan metadata for later Strategize/Execute steps.
- Docs [Jeff]: Update
docs/reference/plan_cli.mdwith examples for profile + invariants and error cases. - Tests (Behave) [Rui]: Add scenarios in
features/plan_lifecycle_cli.featurecovering profile selection, invariant validation, and multiple projects. - Tests (Robot) [Rui]: Add Robot tests for plan use with invariants and automation profiles (positive + negative cases).
- Tests (ASV) [Rui]: Add
asv/benchmarks/plan_use_cli_bench.pyfor argument parsing and validation. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(cli): extend plan use with invariants and automation profile".
- Code [Jeff]: Add
- COMMIT (Owner: Rui | Group: A4b.beta) - Commit message: "test(cli): add plan lifecycle Behave and Robot coverage" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Tests (Behave) [Rui]: Add full coverage for
plan execute,plan apply,plan status,plan list,plan cancel(success + error paths). - Tests (Robot) [Rui]: Add
robot/plan_lifecycle_cli.robotcovering end-to-end lifecycle transitions. - Docs [Rui]: Update
docs/development/testing.mdwith new CLI suites and command mappings. - Tests (ASV) [Rui]: Add
asv/benchmarks/plan_cli_smoke_bench.pyfor CLI argument parsing overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "test(cli): add plan lifecycle Behave and Robot coverage".
- Tests (Behave) [Rui]: Add full coverage for
- COMMIT (Owner: Jeff | Group: A4b.alpha) - Commit message: "feat(cli): support action create from YAML config" (COMMIT TASK: only check after every subtask below is complete,
- Code: Implement plan lifecycle CLI
Parallel Group A5: Plan Persistence (M1-critical) PARALLEL SUBTRACK A5.alpha [Jeff]: Alembic migrations for action/plan tables PARALLEL SUBTRACK A5.beta [Luis]: SQLAlchemy models for new tables SEQUENTIAL AFTER alpha+beta [Jeff + Luis]: Repositories + service integration PARALLEL CONTINUOUS [Rui]: Persistence tests added inside each commit
-
COMMIT (Owner: Jeff | Group: A5.alpha) - Commit message: "feat(db): add actions and action_invariants tables" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add Alembic migration for
actionstable with ULID PK, namespaced_name, actor refs, DoD fields, automation_profile, invariant_actor, timestamps. - Code [Jeff]: Add
action_invariantstable with FK to actions,scopecolumn, and created_at timestamp. - Code [Jeff]: Add unique index on actions.namespaced_name and search index on namespace for list filtering.
- Code [Jeff]: Ensure downgrade path drops indexes and tables in reverse order.
- Docs [Jeff]: Update
docs/reference/database_schema.mdwith column-level details and constraints. - Tests (Behave) [Rui]: Add migration scenario that runs upgrade and asserts tables + indexes exist.
- Tests (Robot) [Rui]: Add Robot migration smoke test using
nox -s db_migrate(create session if missing). - Tests (ASV) [Rui]: Add
asv/benchmarks/db_migration_actions_bench.pyfor migration runtime baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(db): add actions and action_invariants tables".
- Code [Jeff]: Add Alembic migration for
-
COMMIT (Owner: Jeff | Group: A5.alpha) - Commit message: "feat(db): add lifecycle_plans and plan_projects tables" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add Alembic migration for
lifecycle_planswith ULID PK, phase/state enums, action linkage, automation_profile, invariant_actor, and timestamps. - Code [Jeff]: Add
plan_projectstable with plan_id, project_name (namespaced), read_only flag, and alias. - Code [Jeff]: Add indexes on plan phase/state for filtering and plan_projects.project_name for lookups.
- Docs [Jeff]: Update schema docs with plan/project link rules and uniqueness constraints.
- Tests (Behave) [Rui]: Add migration scenario verifying plan/project link table + indexes.
- Tests (Robot) [Rui]: Add Robot test that inserts a plan/project link row and queries it.
- Tests (ASV) [Rui]: Add
asv/benchmarks/db_migration_plans_bench.pyfor migration runtime baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(db): add lifecycle_plans and plan_projects tables".
- Code [Jeff]: Add Alembic migration for
-
COMMIT (Owner: Jeff | Group: A5.alpha) - Commit message: "feat(db): add plan arguments and plan invariants tables" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add
plan_argumentstable (plan_id, name, value_json, value_type) andplan_invariantstable (plan_id, invariant_text, source_scope). - Code [Jeff]: Add uniqueness constraint on (plan_id, name) for arguments and (plan_id, invariant_text) for invariants.
- Docs [Jeff]: Document argument storage, JSON serialization rules, and invariant source scopes.
- Tests (Behave) [Rui]: Add migration scenario verifying both tables and constraints.
- Tests (Robot) [Rui]: Add Robot test that inserts a plan invariant and asserts retrieval.
- Tests (ASV) [Rui]: Add
asv/benchmarks/db_migration_plan_args_bench.pyfor migration runtime baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(db): add plan arguments and plan invariants tables".
- Code [Jeff]: Add
-
COMMIT (Owner: Luis | Group: A5.beta) - Commit message: "feat(models): add action and lifecycle plan ORM models" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Add SQLAlchemy models for Action, ActionInvariant, LifecyclePlan, PlanProjectLink, PlanArgument, PlanInvariant.
- Code [Luis]: Implement
to_domain()andfrom_domain()mappings with ULID validation, enum conversion, and timestamp normalization. - Code [Luis]: Add repository-facing helpers for filtering by namespace/phase/state.
- Docs [Luis]: Update ORM mapping notes in
docs/reference/database_schema.mdwith model field mapping table. - Tests (Behave) [Rui]: Add scenarios for ORM round-trip serialization and enum conversions.
- Tests (Robot) [Rui]: Add Robot test that loads a plan and asserts field mapping correctness.
- Tests (ASV) [Rui]: Add
asv/benchmarks/orm_mapping_bench.pyfor Action/Plan mapping throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(models): add action and lifecycle plan ORM models".
-
COMMIT (Owner: Jeff | Group: A5.gamma) - Commit message: "feat(repo): add action and lifecycle plan repositories" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Implement ActionRepository CRUD + list filters by namespace/state/automation profile.
- Code [Jeff]: Implement PlanRepository CRUD + list filters by phase/state/project; add plan lookup by namespaced name.
- Code [Jeff]: Add retry decorator to repositories; retry only on
OperationalError, never onIntegrityError. - Docs [Jeff]: Document repository interfaces, error types, and pagination guidance.
- Tests (Behave) [Rui]: Add scenarios for repository create/get/list/update/delete guardrails.
- Tests (Robot) [Rui]: Add Robot test that exercises repository through service layer.
- Tests (ASV) [Rui]: Add
asv/benchmarks/repository_query_bench.pyfor list + filter performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(repo): add action and lifecycle plan repositories".
-
COMMIT (Owner: Luis | Group: A5.gamma) - Commit message: "feat(service): persist plan lifecycle via repositories" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Update
PlanLifecycleServiceto use repositories instead of in-memory dicts. - Code [Luis]: Ensure plan creation persists arguments, invariants, automation profile, and project links in a single transaction.
- Code [Luis]: Add transactional safeguards for multi-step updates (create action + plan, correction updates).
- Docs [Luis]: Update service docs to reflect persistence and remove in-memory notes.
- Tests (Behave) [Rui]: Add scenarios for persisted lifecycle transitions and error handling.
- Tests (Robot) [Rui]: Add end-to-end test that restarts the app and re-reads plan state.
- Tests (ASV) [Rui]: Add
asv/benchmarks/plan_lifecycle_service_bench.pyfor persistence operations. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(service): persist plan lifecycle via repositories".
- Code [Luis]: Update
-
COMMIT (Owner: Luis | Group: A5.gamma) - Commit message: "feat(di): wire lifecycle repos and services" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Register ActionRepository + PlanRepository in
application/container.pyand UnitOfWork. - Code [Luis]: Inject repositories into PlanLifecycleService and CLI commands.
- Code [Luis]: Add container wiring tests to ensure singleton lifetimes are correct.
- Docs [Luis]: Update DI wiring notes in
docs/architecture/decisions/adr-003.md. - Tests (Behave) [Rui]: Add scenarios that use container wiring for lifecycle commands.
- Tests (Robot) [Rui]: Add Robot smoke test verifying CLI uses persisted service.
- Tests (ASV) [Rui]: Add
asv/benchmarks/di_container_bench.pyfor container resolution overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(di): wire lifecycle repos and services".
- Code [Luis]: Register ActionRepository + PlanRepository in
-
COMMIT (Owner: Rui | Group: A5.tests) - Commit message: "test(persistence): add plan/action persistence suites" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Tests (Behave) [Rui]: Add plan persistence scenarios (create, update phase/state, list filters, plan tree, concurrency).
- Tests (Behave) [Rui]: Add action persistence scenarios (create, list available, archive guard).
- Tests (Robot) [Rui]: Add plan persistence E2E (full lifecycle, restart persistence, concurrent CLI access).
- Docs [Rui]: Update
docs/development/testing.mdwith persistence suites andnoxcommands. - Tests (ASV) [Rui]: Add
asv/benchmarks/persistence_suites_bench.pyfor DB read/write baselines. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "test(persistence): add plan/action persistence suites".
Parallel Group A5.legacy: Remove legacy plan build/apply path (M1-critical)
- COMMIT (Owner: Jeff | Group: A5.legacy) - Commit message: "refactor(plan): remove legacy plan service and CLI" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Remove
PlanServiceusage from CLI (plan tell/build/apply/new/current/list/cd/continue). - Code [Jeff]: Remove or quarantine legacy
plan_service.py,plan_legacy.py, and legacy CLI helpers; add explicit NotImplementedError where needed. - Code [Jeff]: Remove or archive legacy
PlanModel/PlanStatusDB tables if unused by v3; document migration path. - Docs [Jeff]: Update CLI docs to list only v3 lifecycle commands and new
plan use/execute/applyflows. - Tests (Behave) [Rui]: Remove/replace legacy scenarios with v3 equivalents and adjust coverage expectations.
- Tests (Robot) [Rui]: Remove legacy robot suites and add v3 replacements where needed.
- Tests (ASV) [Rui]: Update asv suite to remove legacy plan benchmarks and add v3 lifecycle baseline benchmark.
- Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "refactor(plan): remove legacy plan service and CLI".
- Code [Jeff]: Remove
Parallel Group A6: Automation Profiles Foundation [Jeff + Luis] (M1-critical; depends on A5 persistence) PARALLEL SUBTRACK A6.core [Jeff]: Profile model + built-ins + schema PARALLEL SUBTRACK A6.service [Luis]: Profile resolution + precedence PARALLEL SUBTRACK A6.cli [Rui]: CLI commands for profiles SEQUENTIAL MERGE NOTE: A6.core must land before A6.service/cli; A6.service must land before gating integration in Section 6.
- COMMIT (Owner: Jeff | Group: A6.core) - Commit message: "feat(domain): add automation profile model and built-ins" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add
AutomationProfilemodel with threshold fields (phase transitions, decision autonomy, child plan spawn, self-repair, apply gating). - Code [Jeff]: Add built-in profiles (
manual,review,supervised,full-auto, etc.) per spec with constant definitions. - Code [Jeff]: Add YAML schema for automation profiles under
docs/schema/automation_profile.schema.yamland loader helper. - Docs [Jeff]: Add
docs/reference/automation_profiles.mddescribing built-ins and threshold semantics. - Tests (Behave) [Rui]: Add scenarios for profile validation and built-in defaults.
- Tests (Robot) [Rui]: Add Robot test that loads each built-in profile and prints summary.
- Tests (ASV) [Rui]: Add
asv/benchmarks/automation_profile_bench.pyfor profile validation. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(domain): add automation profile model and built-ins".
- Code [Jeff]: Add
- COMMIT (Owner: Luis | Group: A6.service) - Commit message: "feat(service): resolve automation profiles with precedence" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Add
AutomationProfileServiceto resolve profiles with precedence (plan > action > project > global). - Code [Luis]: Add persistence table
automation_profiles(namespaced name PK) and repository with list/show. - Code [Luis]: Add config key
core.automation_profileand env var override for global default. - Docs [Luis]: Update
docs/reference/config.mdwith automation profile defaults and override behavior. - Tests (Behave) [Rui]: Add scenarios for precedence resolution and missing profile errors.
- Tests (Robot) [Rui]: Add Robot config smoke test for global profile override.
- Tests (ASV) [Rui]: Add
asv/benchmarks/automation_profile_resolution_bench.pyfor resolution latency. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(service): resolve automation profiles with precedence".
- Code [Luis]: Add
- COMMIT (Owner: Rui | Group: A6.cli) - Commit message: "feat(cli): add automation-profile commands" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Rui]: Implement
agents automation-profile add/remove/list/showcommands with YAML config input. - Code [Rui]: Add
--automation-profiletoplan useand output profile inplan status. - Docs [Rui]: Update CLI reference with automation-profile command examples.
- Tests (Behave) [Rui]: Add CLI scenarios for profile add/list/show/remove.
- Tests (Robot) [Rui]: Add Robot CLI tests for automation-profile commands.
- Tests (ASV) [Rui]: Add
asv/benchmarks/automation_profile_cli_bench.pyfor CLI parsing. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "feat(cli): add automation-profile commands".
- Code [Rui]: Implement
M1 SUCCESS CRITERIA (Day 7 MVP - source code only):
- Action created from YAML config and persisted (namespaced name, invariants, automation profile).
- Project created and linked to a local git-checkout resource.
- Plan use -> strategize -> execute -> apply completes with sandbox isolation and diff review.
- Tool-based change tracking produces a ChangeSet and applies to the repo after approval.
noxpasses with coverage >=97% on the MVP end-to-end path.
Section 4: Projects & Resources [WORKSTREAM B - Hamza Lead]
Target: Milestone M2 (+10 days)
Parallel Group B1: Resource Registry Core [Hamza + Jeff] (can start after A5.alpha migrations are available)
- COMMIT (Owner: Hamza | Group: B1.core) - Commit message: "feat(domain): add resource type spec and resource model" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Create
src/cleveragents/domain/models/core/resource_type.pywithResourceTypeSpec,ResourceTypeArgument,ResourceKind(physical/virtual), andSandboxStrategyenum. - Code [Hamza]: Add resource type fields:
user_addable,allowed_parents,allowed_children,auto_discover,handlerreference, andsandbox_strategydefault. - Code [Hamza]: Add
ResourceandResourceRefmodels with ULID, optional namespaced name, type name, location, description, sandbox strategy, read_only, and metadata. - Code [Hamza]: Add validators for namespaced naming, ULID format, and parent/child DAG sanity (no self loops, no duplicate edges, type compatibility).
- Docs [Hamza]: Add
docs/reference/resource_model.mdwith examples for git-checkout and fs-directory resources plus physical/virtual notes. - Tests (Behave) [Rui]: Add scenarios validating ULID format, namespace rules, allowed parent/child type checks, and sandbox strategy defaults.
- Tests (Robot) [Rui]: Add Robot test that loads a ResourceTypeSpec YAML fixture and validates it.
- Tests (ASV) [Rui]: Add
asv/benchmarks/resource_model_bench.pyfor resource validation + DAG checks. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(domain): add resource type spec and resource model".
- Code [Hamza]: Create
- COMMIT (Owner: Hamza | Group: B1.core) - Commit message: "feat(domain): add project model v3 with linked resources" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Add
Project,ProjectResourceLink,ProjectValidation, andProjectContextPolicymodels using namespaced name as the unique identifier (no ULID per spec). - Code [Hamza]: Add fields for
invariants,invariant_actor,automation_profile, andcontext_views(strategize/execute/apply/default). - Code [Hamza]: Add validation for resource link overrides (read_only flags, alias uniqueness, resource existence).
- Docs [Hamza]: Add
docs/reference/project_model.mddescribing resource linking, validation attachments, and context view policies. - Tests (Behave) [Rui]: Add scenarios for project model validation, link overrides, and context view inheritance.
- Tests (Robot) [Rui]: Add Robot test that creates a Project object and prints serialized output.
- Tests (ASV) [Rui]: Add
asv/benchmarks/project_model_bench.pyfor serialization/validation performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(domain): add project model v3 with linked resources".
- Code [Hamza]: Add
- COMMIT (Owner: Jeff | Group: B1.core) - Commit message: "feat(db): add resource registry tables" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Add Alembic migration for
resource_types,resources, andresource_edgestables with indexes on type/name/namespace. - Code [Jeff]: Store
resource_kind(physical/virtual),sandbox_strategy, and optionalnamespaced_nameinresources. - Code [Jeff]: Add foreign keys and cascade rules for resource_edges (parent/child) with uniqueness constraint.
- Docs [Jeff]: Update
docs/reference/database_schema.mdwith resource registry tables and constraints. - Tests (Behave) [Rui]: Add migration scenarios verifying tables, indices, and edge uniqueness.
- Tests (Robot) [Rui]: Add Robot migration smoke test using
nox -s db_migrate. - Tests (ASV) [Rui]: Add
asv/benchmarks/resource_registry_migration_bench.pyfor migration baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(db): add resource registry tables".
- Code [Jeff]: Add Alembic migration for
Parallel Group B2: Project Persistence + Services [Hamza + Luis] (depends on B1 domain models)
- COMMIT (Owner: Jeff | Group: B2.persistence) - Commit message: "feat(db): add projects and project links tables" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Add Alembic migration for
projects,project_resource_links, andproject_validationstables. - Code [Jeff]: Use namespaced name as project primary key; enforce unique constraint on
projects.namespaced_name. - Code [Jeff]: Add indexes for
project_resource_links.project_nameandresource_idfor fast joins. - Docs [Jeff]: Document project table schema and link semantics in
docs/reference/database_schema.md. - Tests (Behave) [Rui]: Add migration scenarios verifying project tables and constraints.
- Tests (Robot) [Rui]: Add Robot test that inserts a project and link row.
- Tests (ASV) [Rui]: Add
asv/benchmarks/project_migration_bench.pyfor migration baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(db): add projects and project links tables".
- Code [Jeff]: Add Alembic migration for
- COMMIT (Owner: Hamza | Group: B2.persistence) - Commit message: "feat(repo): add resource repositories" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement
ResourceTypeRepositoryCRUD andResourceRepositoryCRUD with DAG edge helpers. - Code [Hamza]: Add methods for tree traversal, child discovery queries, and name/ULID resolution.
- Code [Hamza]: Add repository guardrails for preventing cycles and duplicate edges.
- Docs [Hamza]: Document repository interfaces in
docs/reference/repositories.md. - Tests (Behave) [Rui]: Add repository scenarios for create/get/list/tree and cycle rejection.
- Tests (Robot) [Rui]: Add Robot test exercising tree output ordering.
- Tests (ASV) [Rui]: Add
asv/benchmarks/resource_repository_bench.pyfor tree query performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(repo): add resource repositories".
- Code [Hamza]: Implement
- COMMIT (Owner: Hamza | Group: B2.persistence) - Commit message: "feat(repo): add project repositories" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement
ProjectRepositoryandProjectResourceLinkRepositorywith namespace filtering and name-based lookup. - Code [Hamza]: Add methods to list project validations and context policies.
- Docs [Hamza]: Update repository docs with project link examples and validation attachment notes.
- Tests (Behave) [Rui]: Add scenarios for project create/link/unlink and validation list.
- Tests (Robot) [Rui]: Add Robot test that links two resources to one project.
- Tests (ASV) [Rui]: Add
asv/benchmarks/project_repository_bench.pyfor link/unlink performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(repo): add project repositories".
- Code [Hamza]: Implement
- COMMIT (Owner: Hamza | Group: B2.service) - Commit message: "feat(service): add resource registry service" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement
ResourceRegistryServicefor register/remove/show/tree operations with name/ULID resolution. - Code [Hamza]: Add auto-discovery hook that delegates to resource handlers (git-checkout for MVP).
- Code [Hamza]: Add validation that resource type supports parent/child linkage before linking.
- Docs [Hamza]: Add
docs/reference/resource_registry.mddescribing API behavior and error cases. - Tests (Behave) [Rui]: Add scenarios for register/remove/show/tree behavior and auto-discovery.
- Tests (Robot) [Rui]: Add Robot test that registers a git-checkout and inspects child count.
- Tests (ASV) [Rui]: Add
asv/benchmarks/resource_registry_service_bench.pyfor register/show performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(service): add resource registry service".
- Code [Hamza]: Implement
- COMMIT (Owner: Luis | Group: B2.service) - Commit message: "feat(service): add project service v3" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement
ProjectServicecreate/list/show/delete/link/unlink methods using repositories. - Code [Luis]: Add validation attachment helpers and context policy setters for project views.
- Code [Luis]: Enforce read-only resource links and project-level invariant actor defaults.
- Docs [Luis]: Update
docs/reference/project_service.mdwith usage examples and error cases. - Tests (Behave) [Rui]: Add scenarios for project create/link/unlink/validation/context policy.
- Tests (Robot) [Rui]: Add Robot test that creates project and links a resource.
- Tests (ASV) [Rui]: Add
asv/benchmarks/project_service_bench.pyfor link/unlink performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(service): add project service v3".
- Code [Luis]: Implement
Parallel Group B3: CLI Commands [Rui] (depends on B2 services)
- COMMIT (Owner: Rui | Group: B3.cli) - Commit message: "feat(cli): add resource type commands" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Rui]: Add
agents resource type add/remove/list/showcommands with YAML config input and schema validation. - Code [Rui]: Implement
--updatebehavior and error on name conflicts per spec. - Docs [Rui]: Update CLI reference with resource type examples and expected output columns.
- Tests (Behave) [Rui]: Add scenarios for resource type lifecycle and invalid schema handling.
- Tests (Robot) [Rui]: Add Robot suite
robot/resource_type_cli.robot. - Tests (ASV) [Rui]: Add
asv/benchmarks/resource_type_cli_bench.pyfor config parsing overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "feat(cli): add resource type commands".
- Code [Rui]: Add
- COMMIT (Owner: Rui | Group: B3.cli) - Commit message: "feat(cli): add resource commands" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Rui]: Add
agents resource add/remove/list/show/treecommands with type-specific flags and name/ULID resolution. - Code [Rui]: Implement
resource inspect --tree/--fileper spec for resource introspection. - Docs [Rui]: Update CLI reference with resource examples (git-checkout, fs-directory) and output columns.
- Tests (Behave) [Rui]: Add scenarios for resource registration, list filters, and tree rendering.
- Tests (Robot) [Rui]: Add Robot suite
robot/resource_cli.robot. - Tests (ASV) [Rui]: Add
asv/benchmarks/resource_cli_bench.pyfor command parsing and list output. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "feat(cli): add resource commands".
- Code [Rui]: Add
- COMMIT (Owner: Rui | Group: B3.cli) - Commit message: "feat(cli): add project commands" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Rui]: Add
agents project create/show/list/delete/link-resource/unlink-resourcecommands using namespaced project names. - Code [Rui]: Add
agents project validation add/remove/listandproject context set/showcommands (context views per phase). - Docs [Rui]: Update CLI reference with project examples and validation output.
- Tests (Behave) [Rui]: Add scenarios for project create/link/validation/context policies.
- Tests (Robot) [Rui]: Add Robot suite
robot/project_cli.robot. - Tests (ASV) [Rui]: Add
asv/benchmarks/project_cli_bench.pyfor command parsing and list output. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "feat(cli): add project commands".
- Code [Rui]: Add
Parallel Group B4: Sandboxing [Luis + Jeff] (depends on resource registry + project links)
-
COMMIT (Owner: Luis | Group: B4.sandbox) - Commit message: "feat(sandbox): add sandbox strategy interface and manager" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add
SandboxStrategyprotocol,SandboxRef,SandboxManager, andSandboxRegistrywith per-resource sandboxes. - Code [Luis]: Implement lazy sandbox creation, cleanup hooks, and plan-scoped retention policy stubs.
- Code [Luis]: Add sandbox path rewriting helper for tool execution and MCP adapters.
- Docs [Luis]: Add
docs/reference/sandbox.mddescribing lifecycle, APIs, and path rewriting rules. - Tests (Behave) [Rui]: Add scenarios for sandbox manager creation, cleanup, and path rewrite behavior.
- Tests (Robot) [Rui]: Add Robot test that creates a sandbox and verifies filesystem isolation.
- Tests (ASV) [Rui]: Add
asv/benchmarks/sandbox_manager_bench.pyfor sandbox creation overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(sandbox): add sandbox strategy interface and manager".
- Code [Luis]: Add
-
COMMIT (Owner: Luis | Group: B4.sandbox) - Commit message: "feat(sandbox): implement git_worktree strategy" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement git worktree creation, checkout, and cleanup for git-checkout resources.
- Code [Luis]: Add safe fallback for repositories without clean worktrees and clear error messages.
- Code [Luis]: Record sandbox metadata (worktree path, branch, base commit) for rollback.
- Docs [Luis]: Update sandbox doc with git_worktree usage and rollback behavior.
- Tests (Behave) [Rui]: Add scenarios for git worktree sandbox creation and rollback.
- Tests (Robot) [Rui]: Add Robot test that modifies sandbox and verifies original repo unchanged.
- Tests (ASV) [Rui]: Add
asv/benchmarks/git_worktree_bench.pyfor sandbox creation time. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(sandbox): implement git_worktree strategy".
-
COMMIT (Owner: Hamza | Group: B4.sandbox) - Commit message: "feat(resource): add git-checkout handler and discovery" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Add git-checkout handler that validates repo path, branch, and read_only flags.
- Code [Hamza]: Implement child resource discovery for fs-directory children (schema-only for now) and record ULID-only children.
- Code [Hamza]: Add sandbox strategy mapping for git-checkout and path normalization helpers.
- Docs [Hamza]: Document git-checkout handler behavior in
docs/reference/resources_git.md. - Tests (Behave) [Rui]: Add scenarios for handler validation and discovery counts.
- Tests (Robot) [Rui]: Add Robot test registering a git repo and asserting discovered children.
- Tests (ASV) [Rui]: Add
asv/benchmarks/git_discovery_bench.pyfor discovery cost. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(resource): add git-checkout handler and discovery".
-
COMMIT (Owner: Luis | Group: B4.sandbox) - Commit message: "feat(sandbox): add copy_on_write strategy stub" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add copy_on_write strategy skeleton with TODOs for large-project optimization.
- Code [Luis]: Raise explicit NotImplementedError with guidance on when it will be available.
- Docs [Luis]: Document that copy_on_write is stubbed for post-M1 work.
- Tests (Behave) [Rui]: Add scenario that selecting copy_on_write raises NotImplementedError with clear message.
- Tests (Robot) [Rui]: Add Robot test verifying stub error output.
- Tests (ASV) [Rui]: Add
asv/benchmarks/sandbox_stub_bench.py(baseline no-op). - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(sandbox): add copy_on_write strategy stub".
-
Stage B1: Project Data Model (Day 1-2) [Hamza - Python Expert, RDF Background]
SEQUENTIAL ORDER: B1.3 (ResourceType) → B1.4 (SandboxStrategy) → B1.2 (Resource) → B1.5 (ValidationConfig) → B1.6 (ContextConfig) → B1.1 (Project) The order matters because Project depends on Resource, which depends on enums.
- Code: Create Project domain model
- B1.3 [Hamza] Define
ResourceTypeenum insrc/cleveragents/domain/models/core/resource.py:- B1.3a [Hamza] Create the file with proper imports:
- Import
Enumfrom enum module - Import
strfor string mixin:class ResourceType(str, Enum): - Add module docstring explaining resource types
- Commit: "feat(domain): create resource.py with ResourceType enum scaffold"
- Import
- B1.3b [Hamza] Define enum values with descriptive docstrings:
GIT_REPOSITORY = "git_repository"- Git repo (local path or remote URL), supports worktree sandboxingFILESYSTEM = "filesystem"- Local directory or file tree, supports copy-on-write sandboxingDATABASE = "database"- SQL/NoSQL database endpoint, supports transaction-based sandboxingAPI_ENDPOINT = "api_endpoint"- REST/GraphQL API, typically cannot be sandboxedDOCUMENT_CORPUS = "document_corpus"- Collection of documents (PDFs, markdown, wikis)CLOUD_INFRASTRUCTURE = "cloud_infrastructure"- Cloud resources (AWS, GCP, Azure)- Commit: "feat(domain): define ResourceType enum values"
- B1.3a [Hamza] Create the file with proper imports:
- B1.4 [Hamza] Define
SandboxStrategyenum in same file:- B1.4a [Hamza] Define enum with string values:
GIT_WORKTREE = "git_worktree"- Usegit worktree addfor isolation, efficient for git reposCOPY_ON_WRITE = "copy_on_write"- Copy directory to temp location, universal but can be slow for large dirsOVERLAY = "overlay"- Use overlayfs (Linux only), efficient copy-on-write for large directoriesTRANSACTION_ROLLBACK = "transaction_rollback"- Database transaction that can be rolled backVERSIONING = "versioning"- Use versioning features (e.g., S3 versioning)NONE = "none"- No sandboxing possible, modifications are immediate and irreversible- Commit: "feat(domain): define SandboxStrategy enum values"
- B1.4b [Hamza] Add helper method to check sandbox capabilities:
@classmethod def supports_rollback(cls, strategy: 'SandboxStrategy') -> bool:- Returns True for all except NONE@classmethod def is_copy_based(cls, strategy: 'SandboxStrategy') -> bool:- Returns True for COPY_ON_WRITE, OVERLAY- Commit: "feat(domain): add SandboxStrategy helper methods"
- B1.4a [Hamza] Define enum with string values:
- B1.2 [Hamza] Define
ResourcePydantic model insrc/cleveragents/domain/models/core/resource.py:- B1.2a [Hamza] Create basic model structure:
- Import
BaseModel, Field, field_validatorfrom pydantic - Import
datetimefor timestamps - Import
Anyfrom typing for metadata dict - Create
class Resource(BaseModel):withmodel_config = ConfigDict(frozen=True) - Commit: "feat(domain): add Resource model scaffold"
- Import
- B1.2b [Hamza] Define all fields with proper types and descriptions:
resource_id: str = Field(..., description="ULID primary identifier")- Required, no defaultname: str = Field(..., min_length=1, max_length=100, description="Human-readable resource name")type: ResourceType = Field(..., description="Type of resource determining available operations")location: str = Field(..., description="Path, URL, or connection string")is_remote: bool = Field(default=False, description="Whether resource is network-accessible")sandbox_strategy: SandboxStrategy = Field(..., description="How to sandbox this resource during execution")read_only: bool = Field(default=False, description="If True, write operations are blocked")metadata: dict[str, Any] = Field(default_factory=dict, description="Additional type-specific metadata")created_at: datetime = Field(default_factory=datetime.utcnow, description="Creation timestamp")- Commit: "feat(domain): define Resource model fields"
- B1.2c [Hamza] Add validators:
@field_validator('resource_id')- Validate ULID format (26 alphanumeric chars)@field_validator('location')- Validate based on type (path for filesystem, URL for git remote, etc.)@field_validator('sandbox_strategy')- Warn if incompatible with resource type (e.g., GIT_WORKTREE on FILESYSTEM)- Add
@model_validator(mode='after')to check sandbox_strategy is compatible with type - Commit: "feat(domain): add Resource model validators"
- B1.2d [Hamza] Add computed properties and helper methods:
@property def supports_sandbox(self) -> bool:- Returns True if sandbox_strategy != NONE@property def can_write(self) -> bool:- Returns True if not read_onlydef get_sandbox_path(self, base_dir: str) -> str:- Generate sandbox path for this resource- Commit: "feat(domain): add Resource helper methods"
- B1.2a [Hamza] Create basic model structure:
- B1.5 [Hamza] Define
ValidationConfigPydantic model insrc/cleveragents/domain/models/core/project.py:- B1.5a [Hamza] Create file with ValidationConfig model:
- Import necessary Pydantic types
- Create
class ValidationConfig(BaseModel): - Commit: "feat(domain): create project.py with ValidationConfig scaffold"
- B1.5b [Hamza] Define all fields:
test_command: str | None = Field(default=None, description="Shell command to run tests (e.g., 'pytest')")lint_command: str | None = Field(default=None, description="Shell command to run linter (e.g., 'ruff check .')")type_check_command: str | None = Field(default=None, description="Shell command for type checking (e.g., 'pyright')")build_command: str | None = Field(default=None, description="Shell command to build project (e.g., 'npm run build')")custom_commands: dict[str, str] = Field(default_factory=dict, description="Named custom validation commands")timeout_seconds: int = Field(default=300, description="Maximum time for each validation command")fail_on_lint_error: bool = Field(default=True, description="Whether lint errors should block apply")- Commit: "feat(domain): define ValidationConfig fields"
- B1.5c [Hamza] Add helper methods:
def get_all_commands(self) -> dict[str, str]:- Returns all non-None commands as dictdef has_any_validation(self) -> bool:- Returns True if any command is configured- Commit: "feat(domain): add ValidationConfig helper methods"
- B1.5a [Hamza] Create file with ValidationConfig model:
- B1.6 [Hamza] Define
ContextConfigPydantic model:- B1.6a [Hamza] Define all fields:
ignore_patterns: list[str] = Field(default_factory=list, description="Gitignore-style patterns to exclude from indexing")include_patterns: list[str] | None = Field(default=None, description="If set, only files matching these patterns are included")max_file_size: int = Field(default=1_000_000, description="Maximum file size in bytes to index (default 1MB)")max_files: int = Field(default=100_000, description="Maximum number of files to index")indexing_strategy: str = Field(default="full_text", description="How to index: full_text, embeddings, or both")chunking_policy: str = Field(default="smart", description="How to chunk large files: fixed, semantic, or smart")chunk_size: int = Field(default=1000, description="Target chunk size in tokens for chunking")- Commit: "feat(domain): define ContextConfig fields"
- B1.6b [Hamza] Add default ignore patterns:
@field_validator('ignore_patterns', mode='before')- Merge with defaults if not explicitly empty- Default patterns:
[".git/", "node_modules/", "__pycache__/", ".venv/", "*.pyc", ".DS_Store"] - Commit: "feat(domain): add ContextConfig default ignore patterns"
- B1.6a [Hamza] Define all fields:
- B1.1 [Hamza] Define
ProjectPydantic model insrc/cleveragents/domain/models/core/project.py:- B1.1a [Hamza] Import Resource model and create Project class:
- Import
Resourcefrom resource module - Import
ValidationConfig,ContextConfigfrom same file - Create
class Project(BaseModel):with proper config - Commit: "feat(domain): add Project model scaffold"
- Import
- B1.1b [Hamza] Define identity fields:
project_id: str = Field(..., description="ULID primary identifier")name: str = Field(..., min_length=1, max_length=100, description="Project display name")namespace: str = Field(default="local", description="Namespace: local/, username/, orgname/")description: str | None = Field(default=None, max_length=500, description="Optional project description")- Commit: "feat(domain): define Project identity fields"
- B1.1c [Hamza] Define categorization and resource fields:
tags: list[str] = Field(default_factory=list, description="Categorization tags (e.g., 'python', 'backend')")resources: list[Resource] = Field(default_factory=list, description="Resources associated with this project")validation_config: ValidationConfig | None = Field(default=None, description="Project-level validation commands")context_config: ContextConfig = Field(default_factory=ContextConfig, description="Context indexing configuration")- Commit: "feat(domain): define Project categorization and resource fields"
- B1.1d [Hamza] Define timestamp fields:
created_at: datetime = Field(default_factory=datetime.utcnow)updated_at: datetime = Field(default_factory=datetime.utcnow)- Commit: "feat(domain): define Project timestamp fields"
- B1.1e [Hamza] Add computed property for is_remote:
@property def is_remote(self) -> bool:- Returns True only if ALL resources have is_remote=True- Empty resources list: return False (local by default)
- Mixed local/remote: return False (has local resources, so project is local)
- All remote: return True (can execute on server)
- Commit: "feat(domain): add Project.is_remote computed property"
- B1.1f [Hamza] Add namespace validator:
@field_validator('namespace')- Validate namespace format- Must match pattern:
^(local|[a-z][a-z0-9_]{0,49})$(local or valid identifier) - Reserved namespaces:
["openai", "anthropic", "google", "cleveragents"]- reject these - Commit: "feat(domain): add Project namespace validator"
- B1.1g [Hamza] Add namespaced_name property and helpers:
@property def namespaced_name(self) -> str:- Returns f"{self.namespace}/{self.name}"@classmethod def parse_namespaced_name(cls, full_name: str) -> tuple[str, str]:- Split into (namespace, name)def add_resource(self, resource: Resource) -> 'Project':- Returns new project with resource added (immutable pattern)def remove_resource(self, resource_id: str) -> 'Project':- Returns new project without resourcedef get_resource(self, name: str) -> Resource | None:- Find resource by name- Commit: "feat(domain): add Project helper methods"
- B1.1a [Hamza] Import Resource model and create Project class:
- B1.3 [Hamza] Define
- Tests: Behave scenarios for model validation
- B1.7 [Rui] Write 25 Behave scenarios in
features/project_model.feature:- B1.7a [Rui] Project creation scenarios:
- Scenario: Create valid project with all required fields
- Scenario: Create project with optional description
- Scenario: Create project with multiple tags
- Scenario: Project creation fails with empty name
- Scenario: Project creation fails with name > 100 chars
- Commit: "test(behave): add project creation scenarios"
- B1.7b [Rui] Namespace validation scenarios:
- Scenario: Project namespace "local" is valid
- Scenario: Project namespace "myuser" is valid
- Scenario: Project namespace "my_org_name" is valid
- Scenario: Project namespace starting with number is invalid
- Scenario: Project namespace "openai" (reserved) is rejected
- Scenario: Project namespaced_name returns "namespace/name" format
- Commit: "test(behave): add namespace validation scenarios"
- B1.7c [Rui] is_remote derivation scenarios:
- Scenario: Project with no resources has is_remote=False
- Scenario: Project with one local resource has is_remote=False
- Scenario: Project with one remote resource has is_remote=True
- Scenario: Project with mixed local/remote resources has is_remote=False
- Scenario: Project with all remote resources has is_remote=True
- Commit: "test(behave): add is_remote derivation scenarios"
- B1.7d [Rui] Resource model scenarios:
- Scenario: Resource with each ResourceType value validates correctly
- Scenario: Resource with GIT_WORKTREE strategy on GIT_REPOSITORY is valid
- Scenario: Resource with COPY_ON_WRITE strategy on FILESYSTEM is valid
- Scenario: Resource with TRANSACTION_ROLLBACK on DATABASE is valid
- Scenario: Resource with read_only=True rejects write operations
- Scenario: Resource location validated based on type
- Commit: "test(behave): add resource model scenarios"
- B1.7e [Rui] ValidationConfig scenarios:
- Scenario: ValidationConfig with all commands validates
- Scenario: ValidationConfig with only test_command validates
- Scenario: ValidationConfig get_all_commands returns non-None commands
- Scenario: ValidationConfig custom_commands are included
- Commit: "test(behave): add ValidationConfig scenarios"
- B1.7f [Rui] ContextConfig scenarios:
- Scenario: ContextConfig ignore patterns accept glob syntax
- Scenario: ContextConfig default ignore patterns applied
- Scenario: ContextConfig max_file_size enforced
- Commit: "test(behave): add ContextConfig scenarios"
- B1.7g [Rui] Serialization scenarios:
- Scenario: Project JSON serialization round-trips correctly
- Scenario: Resource JSON serialization preserves enum values
- Scenario: Project with nested resources serializes completely
- Commit: "test(behave): add serialization round-trip scenarios"
- B1.7a [Rui] Project creation scenarios:
- B1.7 [Rui] Write 25 Behave scenarios in
- Code: Create Project domain model
-
Stage B2: Project CLI Commands (Day 3-4) [Hamza]
SEQUENTIAL ORDER: B2.1 (File scaffold) → B2.2 (Create) → B2.3 (Add resource) → B2.4 (Remove resource) → B2.5 (List) → B2.6 (Show) → B2.7 (Validation) → B2.8 (Delete) → B2.9 (Register)
- Code: Implement project CLI
- B2.1 [Hamza] Create
src/cleveragents/cli/commands/project.pyscaffold:- B2.1a [Hamza] Create file with imports and Click group:
- Import
clickfor CLI framework - Import
rich.console.Console,rich.table.Tablefor output - Import Project, Resource models from domain
- Import ProjectService from application.services
- Create
@click.group(name="project")decorator - Add docstring: "Manage projects and their resources"
- Commit: "feat(cli): create project.py with Click group scaffold"
- Import
- B2.1b [Hamza] Create ProjectService in
src/cleveragents/application/services/project_service.py:- Import ProjectRepository, ResourceRepository
- Define
class ProjectService: - Add
__init__(self, project_repo: ProjectRepository, resource_repo: ResourceRepository) - Add stub methods:
create_project(),get_project(),list_projects(),delete_project() - Commit: "feat(service): add ProjectService scaffold"
- B2.1a [Hamza] Create file with imports and Click group:
- B2.2 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project createcommand:- B2.2a [Hamza] Define command signature:
@project.command("create") @click.option("--name", "-n", required=True, help="Project name (namespace/name format)") @click.option("--description", "-d", default=None, help="Project description") @click.option("--tag", "-t", multiple=True, help="Project tags (can specify multiple)") def create_project(name: str, description: str | None, tag: tuple[str, ...]):- Commit: "feat(cli): add project create command signature"
- B2.2b [Hamza] Implement namespace parsing:
- Split name on "/" to get (namespace, short_name)
- If no "/" present, default namespace to "local"
- Validate namespace: must match
^(local|[a-z][a-z0-9_]{0,49})$ - Validate short_name: 1-100 chars, alphanumeric + hyphens
- Raise
click.BadParameteron validation failure - Commit: "feat(cli): implement namespace parsing in project create"
- B2.2c [Hamza] Implement project creation:
- Generate ULID for project_id:
ulid.new().str - Create
Projectdomain model with all fields - Call
project_service.create_project(project) - Handle
DuplicateProjectError- display user-friendly message - Commit: "feat(cli): implement project creation logic"
- Generate ULID for project_id:
- B2.2d [Hamza] Implement success output:
- Display: "Created project: {namespace}/{short_name}"
- Display: "Project ID: {project_id}"
- Display: "Tags: {tags}" if any
- Use Rich console for colored output (green for success)
- Commit: "feat(cli): add project create success output"
- B2.2e [Hamza] Add ProjectService.create_project() implementation:
- Validate project.name is unique via repository
- If duplicate, raise
DuplicateProjectError(name=project.name) - Persist via
self._project_repo.create(project) - Return created project
- Commit: "feat(service): implement ProjectService.create_project()"
- B2.2a [Hamza] Define command signature:
- B2.3 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project add-resourcecommand:- B2.3a [Hamza] Define command signature:
@project.command("add-resource") @click.option("--project", "-p", required=True, help="Project name (namespace/name)") @click.option("--name", "-n", required=True, help="Resource name") @click.option("--type", "-t", "resource_type", required=True, type=click.Choice(["git_repository", "filesystem", "database", "api_endpoint"])) @click.option("--location", "-l", required=True, help="Path, URL, or connection string") @click.option("--sandbox-strategy", "-s", required=True, type=click.Choice(["git_worktree", "copy_on_write", "transaction_rollback", "none"])) @click.option("--read-only", is_flag=True, help="Mark resource as read-only") @click.option("--metadata", "-m", multiple=True, help="Key=value metadata pairs")- Commit: "feat(cli): add project add-resource command signature"
- B2.3b [Hamza] Implement resource type validation:
- Map CLI type string to ResourceType enum
- Validate sandbox strategy is compatible with resource type:
- git_repository: allows git_worktree, copy_on_write, none
- filesystem: allows copy_on_write, overlay, none
- database: allows transaction_rollback, none
- api_endpoint: only allows none
- Raise
click.BadParameterif incompatible - Commit: "feat(cli): validate resource type and sandbox strategy compatibility"
- B2.3c [Hamza] Implement location validation:
- For git_repository: validate path exists or URL is valid git URL
- For filesystem: validate path exists and is directory
- For database: validate connection string format (basic check)
- For api_endpoint: validate URL format
- Commit: "feat(cli): validate resource location by type"
- B2.3d [Hamza] Implement metadata parsing:
- Parse each
--metadatavalue as "key=value" - Build dict from all pairs
- Handle missing "=" gracefully (error)
- Commit: "feat(cli): parse metadata key=value pairs"
- Parse each
- B2.3e [Hamza] Implement resource creation and linking:
- Fetch project by namespaced name
- Raise
ProjectNotFoundErrorif not exists - Check resource name is unique within project
- Create Resource with ULID and all fields
- Add resource to project:
project_service.add_resource(project_id, resource) - Display success: "Added resource '{name}' to project '{project_name}'"
- Commit: "feat(cli): implement add-resource creation and linking"
- B2.3f [Hamza] Add ProjectService.add_resource() implementation:
- Fetch project from repository
- Check for duplicate resource name in project
- Create new project with resource added (immutable pattern)
- Recompute project.is_remote based on all resources
- Update project in repository
- Create resource in resource repository
- Return updated project
- Commit: "feat(service): implement ProjectService.add_resource()"
- B2.3a [Hamza] Define command signature:
- B2.4 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project remove-resourcecommand:- B2.4a [Hamza] Define command signature:
@project.command("remove-resource") @click.option("--project", "-p", required=True, help="Project name") @click.option("--name", "-n", required=True, help="Resource name to remove") @click.option("--yes", is_flag=True, help="Skip confirmation")- Commit: "feat(cli): add project remove-resource command signature"
- B2.4b [Hamza] Implement removal logic:
- Fetch project and validate resource exists
- If not --yes, prompt for confirmation: "Remove resource '{name}'? [y/N]"
- Call
project_service.remove_resource(project_id, resource_name) - Display success: "Removed resource '{name}' from project"
- Commit: "feat(cli): implement remove-resource logic"
- B2.4c [Hamza] Add ProjectService.remove_resource() implementation:
- Fetch project
- Find resource by name
- Raise
ResourceNotFoundErrorif not exists - Create new project without resource (immutable pattern)
- Recompute is_remote
- Update project
- Delete resource from resource repository
- Return updated project
- Commit: "feat(service): implement ProjectService.remove_resource()"
- B2.4a [Hamza] Define command signature:
- B2.5 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project listcommand:- B2.5a [Hamza] Define command signature:
@project.command("list") @click.option("--namespace", "-n", default=None, help="Filter by namespace") @click.option("--tag", "-t", default=None, help="Filter by tag") @click.option("--format", "output_format", type=click.Choice(["table", "json"]), default="table")- Commit: "feat(cli): add project list command signature"
- B2.5b [Hamza] Implement query and filtering:
- Call
project_service.list_projects(namespace=namespace, tag=tag) - If namespace provided, filter by namespace
- If tag provided, filter projects that have this tag
- Commit: "feat(cli): implement project list filtering"
- Call
- B2.5c [Hamza] Implement table output:
- Create Rich Table with columns: ID, Name, Resources, Tags, Remote
- Add row for each project:
- ID: first 8 chars of project_id
- Name: namespaced_name
- Resources: count of resources
- Tags: comma-separated tags (truncate if >3)
- Remote: "Yes" or "No" based on is_remote
- Display table via console.print()
- If no projects found, display "No projects found"
- Commit: "feat(cli): implement project list table output"
- B2.5d [Hamza] Implement JSON output:
- If format=json, serialize projects to JSON
- Use model_dump_json() for each project
- Print to stdout (for piping to jq, etc.)
- Commit: "feat(cli): implement project list JSON output"
- B2.5e [Hamza] Add ProjectService.list_projects() implementation:
- Call
project_repo.list_all() - Apply namespace filter if provided
- Apply tag filter if provided
- Return filtered list
- Commit: "feat(service): implement ProjectService.list_projects()"
- Call
- B2.5a [Hamza] Define command signature:
- B2.6 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project showcommand:- B2.6a [Hamza] Define command signature:
@project.command("show") @click.argument("name") @click.option("--format", "output_format", type=click.Choice(["rich", "json"]), default="rich")- Commit: "feat(cli): add project show command signature"
- B2.6b [Hamza] Implement project fetch and rich display:
- Fetch project by namespaced name via service
- If not found, display error and exit(1)
- Display project details using Rich panels:
╭─ Project: local/my-project ────────────────────────╮ │ ID: 01ARZ3NDEKTSV4RRFFQ69G5FAV │ │ Description: My awesome project │ │ Tags: python, backend │ │ Remote: No │ │ Created: 2024-01-15 10:30:00 │ ╰───────────────────────────────────────────────────╯ Resources (2): ┌─────────────────┬──────────────────┬─────────────────┬──────────┐ │ Name │ Type │ Location │ Strategy │ ├─────────────────┼──────────────────┼─────────────────┼──────────┤ │ source │ git_repository │ /path/to/repo │ worktree │ │ config │ filesystem │ /path/to/config │ copy │ └─────────────────┴──────────────────┴─────────────────┴──────────┘ Validation Config: Test: pytest tests/ Lint: ruff check src/ Type Check: pyright src/ - Commit: "feat(cli): implement project show rich display"
- B2.6c [Hamza] Implement JSON output:
- If format=json, output full project as JSON
- Include all resources and validation config
- Commit: "feat(cli): implement project show JSON output"
- B2.6d [Hamza] Add ProjectService.get_project() implementation:
- Parse namespaced name to (namespace, short_name)
- Query by namespaced_name OR by project_id (support both)
- Return Project with resources loaded
- Commit: "feat(service): implement ProjectService.get_project()"
- B2.6a [Hamza] Define command signature:
- B2.7 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project set-validationcommand:- B2.7a [Hamza] Define command signature:
@project.command("set-validation") @click.option("--project", "-p", required=True, help="Project name") @click.option("--test-command", default=None, help="Command to run tests") @click.option("--lint-command", default=None, help="Command to run linter") @click.option("--type-check-command", default=None, help="Command for type checking") @click.option("--build-command", default=None, help="Command to build project") @click.option("--timeout", default=300, type=int, help="Timeout for each command (seconds)") @click.option("--clear", is_flag=True, help="Clear all validation config")- Commit: "feat(cli): add project set-validation command signature"
- B2.7b [Hamza] Implement validation config update:
- Fetch project
- If --clear, set validation_config to None
- Otherwise, create ValidationConfig with provided commands
- Only set commands that were explicitly provided (preserve existing if not specified)
- Call
project_service.update_validation(project_id, config) - Display updated config summary
- Commit: "feat(cli): implement set-validation logic"
- B2.7c [Hamza] Add ProjectService.update_validation() implementation:
- Fetch project
- Merge new config with existing (if not --clear)
- Update project with new validation_config
- Persist via repository
- Commit: "feat(service): implement ProjectService.update_validation()"
- B2.7a [Hamza] Define command signature:
- B2.8 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project deletecommand:- B2.8a [Hamza] Define command signature:
@project.command("delete") @click.argument("name") @click.option("--force", "-f", is_flag=True, help="Force delete even if plans exist") @click.option("--yes", is_flag=True, help="Skip confirmation")- Commit: "feat(cli): add project delete command signature"
- B2.8b [Hamza] Implement deletion checks:
- Fetch project
- Check for active plans using this project:
plan_repo.count(project_id=project.project_id) - If plans exist and not --force:
- Display error: "Cannot delete project with {n} active plans. Use --force to delete anyway."
- List plan IDs (first 5)
- Exit with code 1
- If --force, display warning: "Deleting project with {n} active plans"
- Commit: "feat(cli): implement project delete safety checks"
- B2.8c [Hamza] Implement deletion:
- Prompt for confirmation: "Delete project '{name}'? This cannot be undone. [y/N]"
- Support
--yesto bypass confirmation - If confirmed (or --yes), call
project_service.delete_project(project_id) - Display success: "Deleted project '{name}'"
- Commit: "feat(cli): implement project delete confirmation and execution"
- B2.8d [Hamza] Add ProjectService.delete_project() implementation:
- Delete all resources for project via resource_repo
- Delete project via project_repo
- Return True on success
- Commit: "feat(service): implement ProjectService.delete_project()"
- B2.8a [Hamza] Define command signature:
- B2.9 [Hamza] Register project commands in
src/cleveragents/cli/main.py:- B2.9a [Hamza] Import and register:
- Add
from cleveragents.cli.commands.project import project as project_group - Add
app.add_command(project_group)in main app setup - Verify
agents [--data-dir PATH] [--config-path PATH] project --helpshows all subcommands - Commit: "feat(cli): register project commands in main CLI"
- Add
- B2.9b [Hamza] Add DI wiring for ProjectService:
- Update container.py to provide ProjectService
- Inject into CLI commands via Click context or similar pattern
- Commit: "feat(di): wire ProjectService into CLI"
- B2.9a [Hamza] Import and register:
- B2.1 [Hamza] Create
- Tests: Behave + Robot for all project CLI commands
- B2.10 [Rui] Write Behave scenarios in
features/project_cli.feature:- B2.10a [Rui] Project creation scenarios:
- Scenario: Create project with valid name succeeds
- When I run
agents [--data-dir PATH] [--config-path PATH] project create --name local/test-project - Then the output contains "Created project: local/test-project"
- And the output contains "Project ID:"
- When I run
- Scenario: Create project with description and tags
- When I run
agents [--data-dir PATH] [--config-path PATH] project create --name local/test --description "My project" --tag python --tag backend - Then the project has description "My project"
- And the project has tags "python", "backend"
- When I run
- Scenario: Create project with duplicate name fails
- Given a project "local/existing" exists
- When I run
agents [--data-dir PATH] [--config-path PATH] project create --name local/existing - Then the exit code is 1
- And the output contains "already exists"
- Scenario: Create project with invalid namespace fails
- When I run
agents [--data-dir PATH] [--config-path PATH] project create --name 123invalid/test - Then the exit code is 1
- And the output contains "Invalid namespace"
- When I run
- Commit: "test(behave): add project create CLI scenarios"
- Scenario: Create project with valid name succeeds
- B2.10b [Rui] Add resource scenarios:
- Scenario: Add git repository resource to project
- Given a project "local/test" exists
- And a git repository exists at "/tmp/test-repo"
- When I run
agents [--data-dir PATH] [--config-path PATH] project add-resource --project local/test --name source --type git_repository --location /tmp/test-repo --sandbox-strategy git_worktree - Then the output contains "Added resource 'source'"
- Scenario: Add filesystem resource to project
- Given a project "local/test" exists
- When I run
agents [--data-dir PATH] [--config-path PATH] project add-resource --project local/test --name config --type filesystem --location /tmp/config --sandbox-strategy copy_on_write - Then the output contains "Added resource 'config'"
- Scenario: Add resource with incompatible sandbox strategy fails
- When I run
agents [--data-dir PATH] [--config-path PATH] project add-resource --project local/test --name api --type api_endpoint --location https://api.example.com --sandbox-strategy git_worktree - Then the exit code is 1
- And the output contains "incompatible"
- When I run
- Scenario: Add resource with metadata
- When I run
agents [--data-dir PATH] [--config-path PATH] project add-resource ... --metadata branch=main --metadata remote=origin - Then the resource has metadata key "branch" with value "main"
- When I run
- Commit: "test(behave): add resource CLI scenarios"
- Scenario: Add git repository resource to project
- B2.10c [Rui] Remove resource scenarios:
- Scenario: Remove resource from project succeeds
- Given project "local/test" has resource "source"
- When I run
agents [--data-dir PATH] [--config-path PATH] project remove-resource --project local/test --name source --yes - Then the output contains "Removed resource 'source'"
- Scenario: Remove non-existent resource fails gracefully
- When I run
agents [--data-dir PATH] [--config-path PATH] project remove-resource --project local/test --name nonexistent --yes - Then the exit code is 1
- And the output contains "not found"
- When I run
- Commit: "test(behave): add remove-resource CLI scenarios"
- Scenario: Remove resource from project succeeds
- B2.10d [Rui] List and show scenarios:
- Scenario: List projects shows all projects
- Given projects "local/proj1" and "local/proj2" exist
- When I run
agents [--data-dir PATH] [--config-path PATH] project list - Then the output contains "proj1"
- And the output contains "proj2"
- Scenario: List projects with namespace filter works
- Given projects "local/proj1" and "team/proj2" exist
- When I run
agents [--data-dir PATH] [--config-path PATH] project list --namespace local - Then the output contains "proj1"
- And the output does not contain "proj2"
- Scenario: List projects JSON format works
- When I run
agents [--data-dir PATH] [--config-path PATH] project list --format json - Then the output is valid JSON
- When I run
- Scenario: Show project displays full details
- Given project "local/test" with 2 resources exists
- When I run
agents [--data-dir PATH] [--config-path PATH] project show local/test - Then the output contains "local/test"
- And the output contains "Resources (2)"
- Commit: "test(behave): add list and show CLI scenarios"
- Scenario: List projects shows all projects
- B2.10e [Rui] Validation config scenarios:
- Scenario: Set validation commands persists correctly
- Given project "local/test" exists
- When I run
agents [--data-dir PATH] [--config-path PATH] project set-validation --project local/test --test-command "pytest" --lint-command "ruff check" - Then project "local/test" has test_command "pytest"
- And project "local/test" has lint_command "ruff check"
- Scenario: Clear validation config works
- Given project "local/test" has validation config
- When I run
agents [--data-dir PATH] [--config-path PATH] project set-validation --project local/test --clear - Then project "local/test" has no validation config
- Commit: "test(behave): add validation config CLI scenarios"
- Scenario: Set validation commands persists correctly
- B2.10f [Rui] Delete scenarios:
- Scenario: Delete project succeeds
- Given project "local/test" exists with no plans
- When I run
agents [--data-dir PATH] [--config-path PATH] project delete local/test --yes - Then the output contains "Deleted project"
- And project "local/test" no longer exists
- Scenario: Delete project with active plans blocked without --force
- Given project "local/test" exists
- And a plan uses project "local/test"
- When I run
agents [--data-dir PATH] [--config-path PATH] project delete local/test --yes - Then the exit code is 1
- And the output contains "active plans"
- Scenario: Delete project with active plans succeeds with --force
- Given project "local/test" exists with active plans
- When I run
agents [--data-dir PATH] [--config-path PATH] project delete local/test --force --yes - Then the output contains "Deleted project"
- Commit: "test(behave): add delete CLI scenarios"
- Scenario: Delete project succeeds
- B2.10a [Rui] Project creation scenarios:
- B2.11 [Rui] Write Robot integration test
robot/project_cli_integration.robot:- B2.11a [Rui] Full lifecycle test:
- Test: Full project lifecycle
- Create project with description and tags
- Add git repository resource
- Add filesystem resource
- Show project and verify all details
- Set validation commands
- List projects and verify presence
- Remove one resource
- Delete project
- Verify project no longer exists
- Commit: "test(robot): add full project lifecycle e2e test"
- Test: Full project lifecycle
- B2.11b [Rui] Multi-resource test:
- Test: Project with multiple resources of different types
- Create project
- Add git repo resource (primary code)
- Add filesystem resource (docs)
- Add database resource (read-only)
- Verify is_remote is computed correctly (should be False - has local resources)
- Show project and verify all resources listed
- Commit: "test(robot): add multi-resource project e2e test"
- Test: Project with multiple resources of different types
- B2.11a [Rui] Full lifecycle test:
- B2.10 [Rui] Write Behave scenarios in
- Code: Implement project CLI
-
Stage B3: Sandbox Framework (Day 3-5) [Luis + Hamza - Architectural, CRITICAL PATH]
PARALLEL SUBTRACKS:
-
TRACK B3.protocol [Luis - Day 3 AM]: Protocol + Status + Factory (B3.1, B3.2, B3.5, B3.6)
-
TRACK B3.git [Hamza - Day 3 PM - Day 4]: Git Worktree Implementation (B3.3)
-
TRACK B3.fs [Hamza - Day 4]: Filesystem Implementation (B3.4)
-
TRACK B3.manager [Luis - Day 4-5]: Manager + Merge (B3.7, B3.8)
-
TRACK B3.tests [Rui - Day 3-5]: Tests in parallel with implementation
-
Code: Implement sandbox abstraction
- B3.1 [Luis] Define
Sandboxprotocol insrc/cleveragents/infrastructure/sandbox/protocol.py:- B3.1a [Luis] Create file with necessary imports:
- Import
Protocol, runtime_checkablefrom typing - Import
ABC, abstractmethodfrom abc - Import
dataclassesfor result types - Add module docstring explaining sandbox abstraction purpose
- Commit: "feat(sandbox): create protocol.py with imports"
- Import
- B3.1b [Luis] Define
SandboxContextdataclass:sandbox_id: str- Unique identifier (ULID) for this sandbox instancesandbox_path: str- Root path where sandboxed files liveoriginal_path: str- Original resource locationresource_id: str- ID of resource being sandboxedplan_id: str- ID of plan that created this sandboxcreated_at: datetime- When sandbox was createdmetadata: dict[str, Any]- Implementation-specific data (e.g., git branch name)- Commit: "feat(sandbox): define SandboxContext dataclass"
- B3.1c [Luis] Define
CommitResultdataclass:sandbox_id: str- Which sandbox was committedsuccess: bool- Whether commit succeededcommit_ref: str | None- Git commit hash or equivalent referencechanged_files: list[str]- List of files that were changedadded_files: list[str]- List of files that were createddeleted_files: list[str]- List of files that were removederror: str | None- Error message if success=Falsetimestamp: datetime- When commit occurred- Commit: "feat(sandbox): define CommitResult dataclass"
- B3.1d [Luis] Define
Sandboxprotocol:@runtime_checkable class Sandbox(Protocol): """Protocol for resource sandboxing implementations.""" @property def sandbox_id(self) -> str: """Unique identifier for this sandbox.""" ... @property def resource(self) -> Resource: """The resource being sandboxed.""" ... @property def status(self) -> SandboxStatus: """Current status of the sandbox.""" ... @property def context(self) -> SandboxContext | None: """Context after sandbox is created, None before.""" ... def create(self, plan_id: str) -> SandboxContext: """Initialize sandbox environment. Returns context with paths.""" ... def get_path(self, resource_path: str) -> str: """Translate resource-relative path to sandbox absolute path.""" ... def commit(self, message: str | None = None) -> CommitResult: """Finalize sandbox changes. Returns result with changed files.""" ... def rollback(self) -> None: """Discard all sandbox changes. Sandbox can still be used.""" ... def cleanup(self) -> None: """Remove sandbox artifacts. Sandbox cannot be used after this.""" ...- Commit: "feat(sandbox): define Sandbox protocol"
- B3.1a [Luis] Create file with necessary imports:
- B3.2 [Luis] Define
SandboxStatusenum in same file:- B3.2a [Luis] Define status values with docstrings:
PENDING = "pending"- Sandbox created but not yet initializedCREATED = "created"- Sandbox initialized, ready for useACTIVE = "active"- Sandbox has been written toCOMMITTED = "committed"- Changes have been applied to originalROLLED_BACK = "rolled_back"- Changes have been discardedCLEANED_UP = "cleaned_up"- Sandbox artifacts removed, terminal stateERRORED = "errored"- Sandbox operation failed- Commit: "feat(sandbox): define SandboxStatus enum"
- B3.2b [Luis] Add status transition validation:
@classmethod def valid_transitions(cls) -> dict[SandboxStatus, list[SandboxStatus]]:- Define allowed transitions- PENDING → CREATED, ERRORED
- CREATED → ACTIVE, COMMITTED (no changes), CLEANED_UP
- ACTIVE → COMMITTED, ROLLED_BACK, ERRORED
- COMMITTED → CLEANED_UP
- ROLLED_BACK → ACTIVE (retry), CLEANED_UP
- ERRORED → CLEANED_UP
- CLEANED_UP → (terminal, no transitions)
- Commit: "feat(sandbox): add SandboxStatus transition validation"
- B3.2a [Luis] Define status values with docstrings:
- B3.3 [Hamza] Implement
GitWorktreeSandboxinsrc/cleveragents/infrastructure/sandbox/git_worktree.py:- B3.3a [Hamza] Create class scaffold with constructor:
- Import subprocess for git commands
- Import logging, tempfile, shutil, os
- Import protocol types from protocol.py
- Define
class GitWorktreeSandbox:implementing Sandbox protocol - Constructor:
__init__(self, resource: Resource):- Validate
resource.type == ResourceType.GIT_REPOSITORY - Validate
resource.sandbox_strategy == SandboxStrategy.GIT_WORKTREE - Store resource reference
- Initialize
_sandbox_id = ulid.new().str - Initialize
_status = SandboxStatus.PENDING - Initialize
_context: SandboxContext | None = None - Initialize
_worktree_path: str | None = None - Initialize
_branch_name: str | None = None
- Validate
- Commit: "feat(sandbox): add GitWorktreeSandbox class scaffold"
- B3.3b [Hamza] Implement
create(plan_id: str) -> SandboxContext:- Validate status is PENDING
- Generate unique branch name:
f"cleveragents-sandbox-{self._sandbox_id}" - Generate worktree path:
tempfile.mkdtemp(prefix=f"ca_git_worktree_{plan_id}_") - Determine repo root from resource.location (handle both path and URL)
- If resource is remote URL, first clone to temp location
- Run git command:
git worktree add {worktree_path} -b {branch_name} - Handle errors: if worktree fails, cleanup and raise
- Store paths in instance variables
- Create and store SandboxContext
- Update status to CREATED
- Log: "Created git worktree sandbox {sandbox_id} at {worktree_path}"
- Return context
- Commit: "feat(sandbox): implement GitWorktreeSandbox.create()"
- B3.3c [Hamza] Implement helper method for git commands:
def _run_git(self, args: list[str], cwd: str | None = None) -> subprocess.CompletedProcess:- Build full command:
["git"] + args - Run with
subprocess.run(capture_output=True, text=True, check=False) - Log command and output at DEBUG level
- If returncode != 0, log error at WARNING level
- Return CompletedProcess for caller to handle
- Build full command:
- Commit: "feat(sandbox): add GitWorktreeSandbox._run_git() helper"
- B3.3d [Hamza] Implement
get_path(resource_path: str) -> str:- Validate sandbox is CREATED or ACTIVE
- Validate resource_path does not escape sandbox (no
..traversal) - Return
os.path.join(self._worktree_path, resource_path) - Commit: "feat(sandbox): implement GitWorktreeSandbox.get_path()"
- B3.3e [Hamza] Implement
commit(message: str | None = None) -> CommitResult:- Validate status is CREATED or ACTIVE
- Default message:
f"CleverAgents sandbox commit [{self._sandbox_id}]" - Run
git status --porcelainto check for changes - If no changes, return CommitResult(success=True, changed_files=[])
- Run
git add -Ato stage all changes - Parse
git diff --cached --name-statusto get changed/added/deleted lists - Run
git commit -m "{message}"to commit - Get commit hash with
git rev-parse HEAD - Update status to COMMITTED
- Return CommitResult with all fields populated
- Commit: "feat(sandbox): implement GitWorktreeSandbox.commit()"
- B3.3f [Hamza] Implement
rollback() -> None:- Validate status is CREATED or ACTIVE
- Run
git checkout .to discard modified files - Run
git clean -fdto remove untracked files - Run
git reset HEADto unstage any staged changes - Update status to ROLLED_BACK
- Log: "Rolled back git worktree sandbox {sandbox_id}"
- Commit: "feat(sandbox): implement GitWorktreeSandbox.rollback()"
- B3.3g [Hamza] Implement
cleanup() -> None:- Can be called from any non-terminal status
- Run
git worktree remove {worktree_path} --forcefrom repo root - If worktree remove fails, try
shutil.rmtree(self._worktree_path)as fallback - Optionally delete the sandbox branch:
git branch -D {branch_name} - Update status to CLEANED_UP
- Clear context and paths
- Log: "Cleaned up git worktree sandbox {sandbox_id}"
- Commit: "feat(sandbox): implement GitWorktreeSandbox.cleanup()"
- B3.3h [Hamza] Add proper error handling:
- Define
SandboxErrorbase exception in protocol.py - Define
SandboxCreationError(SandboxError)- failed to create - Define
SandboxCommitError(SandboxError)- failed to commit - Define
SandboxRollbackError(SandboxError)- failed to rollback - All methods should catch subprocess errors and wrap in SandboxError
- On error, update status to ERRORED and include original exception
- Commit: "feat(sandbox): add GitWorktreeSandbox error handling"
- Define
- B3.3a [Hamza] Create class scaffold with constructor:
- B3.4 [Hamza] Implement
FilesystemSandboxinsrc/cleveragents/infrastructure/sandbox/filesystem.py:- B3.4a [Hamza] Create class scaffold:
- Similar structure to GitWorktreeSandbox
- Constructor validates
resource.type == ResourceType.FILESYSTEM - Constructor validates
resource.sandbox_strategy == SandboxStrategy.COPY_ON_WRITE - Commit: "feat(sandbox): add FilesystemSandbox class scaffold"
- B3.4b [Hamza] Implement
create(plan_id: str) -> SandboxContext:- Generate sandbox path:
tempfile.mkdtemp(prefix=f"ca_fs_sandbox_{plan_id}_") - Copy resource directory to sandbox:
shutil.copytree(resource.location, sandbox_path, dirs_exist_ok=True) - Use
shutil.ignore_patterns()to skip .git, node_modules, pycache - Record file hashes of original for diff detection later
- Create and store SandboxContext
- Update status to CREATED
- Commit: "feat(sandbox): implement FilesystemSandbox.create()"
- Generate sandbox path:
- B3.4c [Hamza] Implement
get_path(resource_path: str) -> str:- Same pattern as GitWorktreeSandbox
- Commit: "feat(sandbox): implement FilesystemSandbox.get_path()"
- B3.4d [Hamza] Implement
commit(message: str | None = None) -> CommitResult:- Compare sandbox files with original (using recorded hashes)
- Build lists of changed/added/deleted files
- For each changed file:
shutil.copy2(sandbox_file, original_file) - For each new file: copy and create parent dirs as needed
- For each deleted file:
os.remove(original_file) - Use atomic operations where possible (write to .tmp then rename)
- Update status to COMMITTED
- Return CommitResult with file lists
- Commit: "feat(sandbox): implement FilesystemSandbox.commit()"
- B3.4e [Hamza] Implement
rollback() -> None:- For filesystem, rollback is implicit - just don't commit
- Re-copy original to sandbox to reset:
shutil.rmtree(sandbox); shutil.copytree(original, sandbox) - Update status to ROLLED_BACK
- Commit: "feat(sandbox): implement FilesystemSandbox.rollback()"
- B3.4f [Hamza] Implement
cleanup() -> None:- Remove sandbox directory:
shutil.rmtree(self._sandbox_path, ignore_errors=True) - Update status to CLEANED_UP
- Commit: "feat(sandbox): implement FilesystemSandbox.cleanup()"
- Remove sandbox directory:
- B3.4a [Hamza] Create class scaffold:
- B3.5 [Luis] Implement
NoSandboxinsrc/cleveragents/infrastructure/sandbox/no_sandbox.py:- B3.5a [Luis] Create class for non-sandboxable resources:
- For APIs, some cloud resources, etc.
- Constructor: accept any Resource with sandbox_strategy=NONE
- Commit: "feat(sandbox): add NoSandbox class scaffold"
- B3.5b [Luis] Implement all methods as passthrough or warnings:
create(): Log WARNING "Resource {name} is not sandboxed - changes are immediate"get_path(resource_path): Return original resource path unchangedcommit(): Return CommitResult(success=True) - changes already appliedrollback(): Log ERROR "Rollback not possible for non-sandboxed resource"cleanup(): No-op, status to CLEANED_UP- Commit: "feat(sandbox): implement NoSandbox methods"
- B3.5a [Luis] Create class for non-sandboxable resources:
- B3.6 [Luis] Implement
SandboxFactoryinsrc/cleveragents/infrastructure/sandbox/factory.py:- B3.6a [Luis] Create factory class:
- Import all sandbox implementations
- Define
class SandboxFactory: - Commit: "feat(sandbox): add SandboxFactory scaffold"
- B3.6b [Luis] Implement
create_sandbox(resource: Resource) -> Sandbox:- Match on
resource.sandbox_strategy:match resource.sandbox_strategy: case SandboxStrategy.GIT_WORKTREE: return GitWorktreeSandbox(resource) case SandboxStrategy.COPY_ON_WRITE: return FilesystemSandbox(resource) case SandboxStrategy.OVERLAY: # Overlay not implemented yet, fall back to copy logger.warning("Overlay not implemented, using copy-on-write") return FilesystemSandbox(resource) case SandboxStrategy.TRANSACTION_ROLLBACK: raise NotImplementedError("Database sandboxing not yet implemented") case SandboxStrategy.NONE: return NoSandbox(resource) case _: raise ValueError(f"Unknown sandbox strategy: {resource.sandbox_strategy}") - Commit: "feat(sandbox): implement SandboxFactory.create_sandbox()"
- Match on
- B3.6c [Luis] Add validation helper:
@staticmethod def is_supported(resource: Resource) -> bool:- Check if sandboxing is supported@staticmethod def get_supported_strategies(resource_type: ResourceType) -> list[SandboxStrategy]:- Valid combos- Commit: "feat(sandbox): add SandboxFactory validation helpers"
- B3.6a [Luis] Create factory class:
- B3.7 [Luis] Implement sandbox lifecycle management:
- B3.7a [Luis] Create
SandboxManagerinsrc/cleveragents/infrastructure/sandbox/manager.py:- Import threading for lock management
- Import factory and protocol types
- Define
class SandboxManager: - Instance variables:
_factory: SandboxFactory- injected via constructor_active_sandboxes: dict[str, dict[str, Sandbox]]- plan_id -> resource_id -> Sandbox_lock: threading.RLock- thread safety for sandbox tracking_cleanup_on_exit: bool- whether to cleanup on process exit (default True)
- Commit: "feat(sandbox): add SandboxManager scaffold"
- B3.7b [Luis] Implement
get_or_create_sandbox(plan_id: str, resource: Resource) -> Sandbox:- Acquire lock
- Check if sandbox already exists for this plan+resource
- If exists and status is usable (CREATED, ACTIVE, ROLLED_BACK), return it
- If exists but cleaned up, remove from tracking
- Create new sandbox via factory
- Call sandbox.create(plan_id) to initialize
- Store in _active_sandboxes
- Release lock
- Return sandbox
- This is the LAZY sandboxing pattern - only create when needed
- Commit: "feat(sandbox): implement SandboxManager.get_or_create_sandbox()"
- B3.7c [Luis] Implement
commit_all(plan_id: str) -> list[CommitResult]:- Get all sandboxes for plan_id
- For each sandbox with status ACTIVE:
- Call sandbox.commit()
- Collect CommitResult
- Return list of all results
- If any commit fails, don't rollback others (partial commit possible, caller decides)
- Commit: "feat(sandbox): implement SandboxManager.commit_all()"
- B3.7d [Luis] Implement
rollback_all(plan_id: str) -> None:- Get all sandboxes for plan_id
- For each sandbox with status ACTIVE:
- Call sandbox.rollback()
- Log any rollback failures but continue with others
- Commit: "feat(sandbox): implement SandboxManager.rollback_all()"
- B3.7e [Luis] Implement
cleanup_all(plan_id: str) -> None:- Get all sandboxes for plan_id
- For each sandbox:
- Call sandbox.cleanup()
- Remove plan_id entry from _active_sandboxes
- Commit: "feat(sandbox): implement SandboxManager.cleanup_all()"
- B3.7f [Luis] Implement
cleanup_abandoned() -> int:- Find sandbox directories matching pattern that aren't tracked
- Check if creating process is still alive (via PID file or lock)
- If process dead, clean up the directory
- Return count of cleaned sandboxes
- This is called on application startup
- Commit: "feat(sandbox): implement SandboxManager.cleanup_abandoned()"
- B3.7g [Luis] Add atexit handler for graceful cleanup:
- Register
atexit.register(self._cleanup_on_exit_handler) - Handler calls cleanup_all for all tracked plans
- Commit: "feat(sandbox): add SandboxManager atexit cleanup"
- Register
- B3.7a [Luis] Create
- B3.8 [Luis] Implement merge strategies in
src/cleveragents/infrastructure/sandbox/merge.py:- B3.8a [Luis] Define merge types and protocol:
- Define
MergeResultdataclass:success: boolcontent: str | bytes- merged contenthas_conflicts: boolconflict_markers: list[tuple[int, int]]- line ranges with conflicts
- Define
MergeStrategy(Protocol):- Method
merge(base: str, ours: str, theirs: str) -> MergeResult
- Method
- Commit: "feat(sandbox): define merge types and protocol"
- Define
- B3.8b [Luis] Implement
GitMergeStrategy:- Use
git merge-filefor three-way merge - Write base, ours, theirs to temp files
- Run
git merge-file -p ours base theirs - Parse output for conflict markers (
<<<<<<<,=======,>>>>>>>) - Return MergeResult with content and conflict info
- Commit: "feat(sandbox): implement GitMergeStrategy"
- Use
- B3.8c [Luis] Implement
SequentialMergeStrategy:- For non-mergeable resources, apply changes in order
- "Theirs" (second change) always wins
- Return MergeResult(success=True, content=theirs)
- Commit: "feat(sandbox): implement SequentialMergeStrategy"
- B3.8d [Luis] Implement
JsonMergeStrategy:- Parse both as JSON
- Deep merge objects (recursive dict merge)
- Arrays: concatenate or last-wins based on config
- Return serialized merged JSON
- Commit: "feat(sandbox): implement JsonMergeStrategy"
- B3.8a [Luis] Define merge types and protocol:
- B3.1 [Luis] Define
-
Tests: Integration tests for each sandbox type
- B3.9 [Rui] Write Behave scenarios in
features/sandbox_git_worktree.feature:- B3.9a [Rui] Creation scenarios:
- Scenario: Create git worktree sandbox from local git repo
- Given a git repository at "/tmp/test-repo" with files
- When I create a GitWorktreeSandbox for that resource
- And I call sandbox.create("plan-123")
- Then a worktree exists at the sandbox path
- And the sandbox status is CREATED
- And the original repo is unchanged
- Scenario: Create sandbox from remote git URL (if applicable)
- Scenario: Create fails for non-git resource type
- Commit: "test(behave): add git worktree creation scenarios"
- Scenario: Create git worktree sandbox from local git repo
- B3.9b [Rui] Modification isolation scenarios:
- Scenario: Modify file in sandbox does not affect original
- Given a created git worktree sandbox
- When I write "modified content" to sandbox path "test.py"
- Then the original repo's "test.py" is unchanged
- And the sandbox status is ACTIVE
- Scenario: Create new file in sandbox does not appear in original
- Scenario: Delete file in sandbox does not delete original
- Commit: "test(behave): add git worktree isolation scenarios"
- Scenario: Modify file in sandbox does not affect original
- B3.9c [Rui] Commit scenarios:
- Scenario: Commit sandbox creates git commit
- Given a sandbox with modified files
- When I call sandbox.commit("Test commit")
- Then a git commit exists with message "Test commit"
- And CommitResult.changed_files contains "test.py"
- And sandbox status is COMMITTED
- Scenario: Commit with no changes succeeds with empty file list
- Scenario: Commit includes all staged and unstaged changes
- Commit: "test(behave): add git worktree commit scenarios"
- Scenario: Commit sandbox creates git commit
- B3.9d [Rui] Rollback and cleanup scenarios:
- Scenario: Rollback sandbox discards all changes
- Given a sandbox with modified files
- When I call sandbox.rollback()
- Then the sandbox files match original
- And sandbox status is ROLLED_BACK
- Scenario: Cleanup removes worktree and branch
- Scenario: Multiple sandboxes from same repo are isolated
- Commit: "test(behave): add git worktree rollback/cleanup scenarios"
- Scenario: Rollback sandbox discards all changes
- B3.9a [Rui] Creation scenarios:
- B3.10 [Rui] Write Behave scenarios in
features/sandbox_filesystem.feature:- Similar structure to B3.9 but for filesystem sandbox
- Scenario: Create filesystem sandbox copies directory
- Scenario: Large directory copy uses efficient patterns
- Scenario: Ignore patterns (node_modules, .git) are skipped during copy
- Scenario: Modify file in sandbox does not affect original
- Scenario: Commit sandbox applies changes to original atomically
- Scenario: Rollback sandbox resets to original state
- Scenario: Cleanup removes temp directory
- Commit: "test(behave): add filesystem sandbox scenarios"
- B3.11 [Rui] Write Robot integration test
robot/sandbox_integration.robot:- B3.11a [Rui] Full lifecycle test:
- Create real git repo with multiple files
- Create sandbox, modify files, commit
- Verify changes appear in repo
- Create second sandbox, rollback, verify no changes
- Cleanup, verify temp directories removed
- Commit: "test(robot): add full sandbox lifecycle e2e test"
- B3.11b [Rui] Parallel sandbox test:
- Create two sandboxes on same repo
- Modify different files in each
- Commit both
- Verify no cross-contamination
- Commit: "test(robot): add parallel sandbox isolation e2e test"
- B3.11a [Rui] Full lifecycle test:
- B3.9 [Rui] Write Behave scenarios in
-
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
- Given Plan A creates sandbox for resource R
- And Plan B creates sandbox for same resource R
- When Plan A writes "A content" to file.txt
- And Plan B writes "B content" to file.txt
- Then Plan A's sandbox shows "A content"
- And Plan B's sandbox shows "B content"
- And original file is unchanged
- Scenario: Plan A cannot see Plan B's intermediate changes
- Scenario: Commits from different plans require merge
- Commit: "test(behave): add sandbox isolation scenarios"
- Scenario: Two plans with sandboxes on same resource are isolated
- B3.12 [Rui] Write Behave scenarios in
-
Tests: Merge conflict resolution tests
- B3.13 [Rui] Write Behave scenarios in
features/sandbox_merge.feature:- Scenario: Git merge strategy handles non-conflicting changes
- Given base content "line1\nline2\nline3"
- And ours changes line1 to "modified1"
- And theirs changes line3 to "modified3"
- When I merge with GitMergeStrategy
- Then result is "modified1\nline2\nmodified3"
- And has_conflicts is False
- Scenario: Git merge strategy marks conflicts appropriately
- Given both ours and theirs change line2
- When I merge
- Then has_conflicts is True
- And content contains conflict markers
- Scenario: Sequential merge uses theirs content
- Scenario: JSON merge combines object properties
- Commit: "test(behave): add merge strategy scenarios"
- Scenario: Git merge strategy handles non-conflicting changes
- B3.13 [Rui] Write Behave scenarios in
-
-
Stage B4: Resource Integration (Day 6-7) [Hamza]
SEQUENTIAL ORDER: B4.1 (Types) → B4.2 (Service scaffold) → B4.3 (Access) → B4.4 (Lazy sandbox) → B4.5 (Commit/Rollback) → B4.6 (Cleanup hooks) → B4.7 (Lifecycle integration)
- Code: Connect resources to plan execution
- B4.1 [Hamza] Define resource access types in
src/cleveragents/domain/models/core/resource_access.py:- B4.1a [Hamza] Define
AccessModeenum:READ = "read"- Read-only access, may use original or sandboxWRITE = "write"- Write access, requires sandboxEXECUTE = "execute"- Execute commands in context- Commit: "feat(domain): define AccessMode enum"
- B4.1b [Hamza] Define
ResourceAccessdataclass:resource_id: str- Which resource is being accessedplan_id: str- Which plan is accessingmode: AccessMode- How resource is being accessedsandbox: Sandbox | None- Sandbox if write modeeffective_path: str- Resolved path (sandbox or original)accessed_at: datetime- When access was grantedis_sandboxed: bool- Whether using sandbox or original- Commit: "feat(domain): define ResourceAccess dataclass"
- B4.1c [Hamza] Define
ResourceAccessTrackerdataclass:plan_id: str- Plan being trackedaccesses: dict[str, ResourceAccess]- resource_id -> accessread_resources: set[str]- Resources accessed for readwrite_resources: set[str]- Resources accessed for writefirst_write_at: datetime | None- When first write occurred- Commit: "feat(domain): define ResourceAccessTracker"
- B4.1a [Hamza] Define
- B4.2 [Hamza] Create
ResourceServicescaffold insrc/cleveragents/application/services/resource_service.py:- B4.2a [Hamza] Define class with dependencies:
class ResourceService: def __init__( self, sandbox_manager: SandboxManager, project_repo: ProjectRepository, resource_repo: ResourceRepository, config: ResourceServiceConfig ): self._sandbox_manager = sandbox_manager self._project_repo = project_repo self._resource_repo = resource_repo self._config = config self._trackers: dict[str, ResourceAccessTracker] = {} # plan_id -> tracker self._lock = threading.RLock()- Commit: "feat(service): add ResourceService scaffold with dependencies"
- B4.2b [Hamza] Define
ResourceServiceConfiginsrc/cleveragents/config/settings.py:force_sandbox_for_reads: bool = False- Always sandbox, even for readspreserve_sandbox_on_failure: bool = True- Keep sandbox for debugging on errorauto_cleanup_abandoned: bool = True- Cleanup orphaned sandboxes on startupmax_sandboxes_per_plan: int = 10- Limit sandboxes per plan- Commit: "feat(config): add ResourceServiceConfig"
- B4.2a [Hamza] Define class with dependencies:
- B4.3 [Hamza] Implement
access_resource()method:- B4.3a [Hamza] Core method signature:
def access_resource( self, plan_id: str, resource: Resource, mode: AccessMode = AccessMode.READ ) -> ResourceAccess:- Commit: "feat(service): add access_resource() signature"
- B4.3b [Hamza] Implement tracker initialization:
- Acquire lock
- If no tracker for plan_id, create one
- Check if resource already accessed
- If already accessed with same or higher mode, return existing access
- Commit: "feat(service): implement access_resource() tracker init"
- B4.3c [Hamza] Implement read access logic:
- If mode is READ and not force_sandbox_for_reads:
- Return access with effective_path = resource.location
- Set is_sandboxed = False
- Record in tracker's read_resources
- Commit: "feat(service): implement read access without sandbox"
- If mode is READ and not force_sandbox_for_reads:
- B4.3d [Hamza] Implement write access logic:
- If mode is WRITE:
- Call
sandbox_manager.get_or_create_sandbox(plan_id, resource) - Get sandbox.context.sandbox_path
- Set effective_path = sandbox_path
- Set is_sandboxed = True
- Record in tracker's write_resources
- Set first_write_at if not set
- Call
- Commit: "feat(service): implement write access with sandbox"
- If mode is WRITE:
- B4.3e [Hamza] Implement access upgrade:
- If resource was accessed as READ but now needs WRITE:
- Create sandbox if not exists
- Update tracker to reflect write mode
- Return new ResourceAccess with sandboxed path
- Commit: "feat(service): implement access mode upgrade"
- If resource was accessed as READ but now needs WRITE:
- B4.3a [Hamza] Core method signature:
- B4.4 [Hamza] Implement lazy sandboxing pattern:
- B4.4a [Hamza] Sandbox created only when write occurs:
access_resource(plan_id, resource, READ)- no sandbox- First
access_resource(plan_id, resource, WRITE)- creates sandbox - Subsequent writes to same resource - reuses existing sandbox
- Log: "Created sandbox for resource {name} on first write"
- Commit: "feat(service): implement lazy sandbox creation"
- B4.4b [Hamza] Track sandbox lifecycle per plan:
- Method
get_plan_sandboxes(plan_id: str) -> list[Sandbox]:- Return all sandboxes associated with plan
- Method
has_pending_changes(plan_id: str) -> bool:- Check if any sandbox has uncommitted changes
- Commit: "feat(service): add sandbox tracking methods"
- Method
- B4.4a [Hamza] Sandbox created only when write occurs:
- B4.5 [Hamza] Implement commit and rollback methods:
- B4.5a [Hamza] Implement
commit_plan_resources():def commit_plan_resources(self, plan_id: str, message: str | None = None) -> list[CommitResult]: """Commit all sandbox changes for a plan.""" results = [] sandboxes = self._sandbox_manager.get_sandboxes(plan_id) for sandbox in sandboxes: if sandbox.status == SandboxStatus.ACTIVE: result = sandbox.commit(message or f"CleverAgents plan {plan_id}") results.append(result) self._log_commit_result(result) return results- Commit: "feat(service): implement commit_plan_resources()"
- B4.5b [Hamza] Implement
rollback_plan_resources():def rollback_plan_resources(self, plan_id: str) -> None: """Rollback all sandbox changes for a plan.""" sandboxes = self._sandbox_manager.get_sandboxes(plan_id) for sandbox in sandboxes: if sandbox.status in (SandboxStatus.CREATED, SandboxStatus.ACTIVE): sandbox.rollback() logger.info(f"Rolled back sandbox {sandbox.sandbox_id}")- Commit: "feat(service): implement rollback_plan_resources()"
- B4.5c [Hamza] Implement
cleanup_plan_resources():def cleanup_plan_resources(self, plan_id: str) -> None: """Clean up all sandbox artifacts for a plan.""" self._sandbox_manager.cleanup_all(plan_id) # Remove tracker with self._lock: if plan_id in self._trackers: del self._trackers[plan_id] logger.info(f"Cleaned up all resources for plan {plan_id}")- Commit: "feat(service): implement cleanup_plan_resources()"
- B4.5a [Hamza] Implement
- B4.6 [Hamza] Add sandbox cleanup hooks:
- B4.6a [Hamza] Implement plan completion hook:
- Create
PlanCompletionHandlerthat listens for plan state changes - On transition to APPLIED: commit then cleanup
- On transition to CANCELLED: rollback then cleanup
- Commit: "feat(service): add plan completion cleanup hook"
- Create
- B4.6b [Hamza] Implement failure handling hook:
- On plan transition to ERRORED:
- If preserve_sandbox_on_failure: keep sandbox for debugging
- Log: "Sandbox preserved for debugging: {sandbox_path}"
- Otherwise: rollback and cleanup
- Commit: "feat(service): add failure handling hook"
- On plan transition to ERRORED:
- B4.6c [Hamza] Implement application exit hook:
- Register
atexit.register(self._cleanup_all_on_exit) - Handler iterates all active trackers
- Cleanup all sandboxes (don't commit - exit is unexpected)
- Log warning if any uncommitted changes lost
- Commit: "feat(service): add atexit cleanup hook"
- Register
- B4.6d [Hamza] Implement startup cleanup:
- Method
cleanup_abandoned_sandboxes() -> int:- Called on application startup
- Call
sandbox_manager.cleanup_abandoned() - Return count of cleaned sandboxes
- Log: "Cleaned up {n} abandoned sandboxes from previous session"
- Commit: "feat(service): add startup cleanup for abandoned sandboxes"
- Method
- B4.6a [Hamza] Implement plan completion hook:
- B4.7 [Hamza] Integrate with plan execution lifecycle:
- B4.7a [Hamza] Update
PlanLifecycleService.apply_plan():- Before apply: verify all sandboxes have changes
- Call
resource_service.commit_plan_resources(plan_id) - If any commit fails, rollback all and raise
- On success: cleanup resources
- Commit: "feat(service): integrate ResourceService with apply_plan()"
- B4.7b [Hamza] Update
PlanLifecycleService.cancel_plan():- Call
resource_service.rollback_plan_resources(plan_id) - Call
resource_service.cleanup_plan_resources(plan_id) - Commit: "feat(service): integrate ResourceService with cancel_plan()"
- Call
- B4.7c [Hamza] Add DI wiring for ResourceService:
- Update container.py to provide ResourceService
- Inject into PlanLifecycleService
- Commit: "feat(di): wire ResourceService into container"
- B4.7a [Hamza] Update
- B4.1 [Hamza] Define resource access types in
- Tests: End-to-end tests for plan execution with sandboxed resources
- B4.8 [Rui] Write Behave scenarios in
features/resource_service.feature:- B4.8a [Rui] Access mode scenarios:
- Scenario: First write access creates sandbox
- Given a plan "plan-123" and resource "repo" with sandbox_strategy=git_worktree
- When I call
resource_service.access_resource("plan-123", repo, WRITE) - Then a sandbox is created for the resource
- And the returned ResourceAccess.is_sandboxed is True
- And the effective_path points to the sandbox location
- Scenario: Read access without write uses original
- When I call
resource_service.access_resource("plan-123", repo, READ) - Then no sandbox is created
- And ResourceAccess.is_sandboxed is False
- And effective_path points to original resource.location
- When I call
- Commit: "test(behave): add resource access mode scenarios"
- Scenario: First write access creates sandbox
- B4.8b [Rui] Sandbox reuse scenarios:
- Scenario: Multiple writes use same sandbox
- Given I accessed resource for WRITE once
- When I access the same resource for WRITE again
- Then the same sandbox is returned
- And only one sandbox exists for this plan+resource
- Scenario: Access upgrade from READ to WRITE creates sandbox
- Given I accessed resource for READ (no sandbox)
- When I access the same resource for WRITE
- Then a sandbox is created
- And the effective_path changes to sandbox path
- Commit: "test(behave): add sandbox reuse scenarios"
- Scenario: Multiple writes use same sandbox
- B4.8c [Rui] Commit and rollback scenarios:
- Scenario: Plan completion commits and cleans up sandbox
- Given a plan with sandbox containing changes
- When the plan transitions to APPLIED
- Then commit_plan_resources is called
- And all changes are committed to the original resource
- And the sandbox is cleaned up
- Scenario: Plan failure rolls back sandbox
- Given a plan with sandbox containing changes
- When the plan transitions to ERRORED
- Then rollback_plan_resources is called (if not preserve_sandbox_on_failure)
- And no changes are committed
- Scenario: Plan failure preserves sandbox for debugging
- Given preserve_sandbox_on_failure=True
- When the plan transitions to ERRORED
- Then the sandbox is NOT cleaned up
- And a log message indicates sandbox location for debugging
- Commit: "test(behave): add commit/rollback scenarios"
- Scenario: Plan completion commits and cleans up sandbox
- B4.8d [Rui] Cleanup scenarios:
- Scenario: Application exit cleans up all sandboxes
- Given multiple plans with active sandboxes
- When the application exits
- Then all sandbox directories are removed
- Scenario: Startup cleans up abandoned sandboxes
- Given orphaned sandbox directories from previous crash
- When the application starts
- Then abandoned sandboxes are cleaned up
- And a log message indicates how many were cleaned
- Commit: "test(behave): add cleanup scenarios"
- Scenario: Application exit cleans up all sandboxes
- B4.8a [Rui] Access mode scenarios:
- B4.9 [Rui] Write Robot integration test
robot/resource_service_integration.robot:- B4.9a [Rui] Full lifecycle test:
- Test: Full plan execution with sandboxed git resource
- Create a real git repository with files
- Create a project with git resource
- Create a plan targeting the project
- Access resource for write (sandbox created)
- Modify files via sandbox path
- Complete plan (commit and cleanup)
- Verify changes appear in original git repo
- Verify sandbox directory is removed
- Commit: "test(robot): add full resource service e2e test"
- Test: Full plan execution with sandboxed git resource
- B4.9b [Rui] Multi-resource test:
- Test: Plan with multiple resources
- Create project with git repo + filesystem resources
- Access both for write
- Modify files in both sandboxes
- Commit all
- Verify both original resources have changes
- Commit: "test(robot): add multi-resource plan e2e test"
- Test: Plan with multiple resources
- B4.9a [Rui] Full lifecycle test:
- B4.8 [Rui] Write Behave scenarios in
- Code: Connect resources to plan execution
-
Stage B5: Project Persistence (Day 7-8) [Hamza]
SEQUENTIAL ORDER: B5.1 (Projects migration) → B5.2 (Resources migration) → B5.3 (Project model) → B5.4 (Resource model) → B5.5 (ProjectRepository) → B5.6 (ResourceRepository) → B5.7 (Tests)
- Code: Project/Resource database schema
- B5.1 [Hamza] Create Alembic migration for
projectstable:- B5.1a [Hamza] Generate migration file:
- Run
alembic revision --autogenerate -m "create_projects_table" - Commit: "chore(db): generate projects table migration"
- Run
- B5.1b [Hamza] Define schema:
def upgrade(): op.create_table( 'projects', sa.Column('project_id', sa.Text(), nullable=False), sa.Column('name', sa.Text(), nullable=False), sa.Column('namespace', sa.Text(), nullable=False), sa.Column('short_name', sa.Text(), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('tags', sa.JSON(), nullable=False, server_default='[]'), sa.Column('is_remote', sa.Boolean(), nullable=False, server_default='false'), sa.Column('validation_config', sa.JSON(), nullable=True), sa.Column('context_config', sa.JSON(), nullable=True), sa.Column('created_at', sa.Text(), nullable=False), sa.Column('updated_at', sa.Text(), nullable=False), sa.PrimaryKeyConstraint('project_id') ) op.create_index('ix_projects_name', 'projects', ['name'], unique=True) op.create_index('ix_projects_namespace', 'projects', ['namespace']) op.create_index('ix_projects_namespace_short_name', 'projects', ['namespace', 'short_name'], unique=True)- Commit: "feat(db): add projects table schema"
- B5.1c [Hamza] Add downgrade:
def downgrade(): op.drop_index('ix_projects_namespace_short_name') op.drop_index('ix_projects_namespace') op.drop_index('ix_projects_name') op.drop_table('projects')- Commit: "feat(db): add projects table downgrade"
- B5.1a [Hamza] Generate migration file:
- B5.2 [Hamza] Create Alembic migration for
resourcestable:- B5.2a [Hamza] Generate migration file:
- Run
alembic revision --autogenerate -m "create_resources_table" - Commit: "chore(db): generate resources table migration"
- Run
- B5.2b [Hamza] Define schema:
def upgrade(): op.create_table( 'resources', sa.Column('resource_id', sa.Text(), nullable=False), sa.Column('project_id', sa.Text(), nullable=False), sa.Column('name', sa.Text(), nullable=False), sa.Column('type', sa.Text(), nullable=False), sa.Column('location', sa.Text(), nullable=False), sa.Column('is_remote', sa.Boolean(), nullable=False, server_default='false'), sa.Column('sandbox_strategy', sa.Text(), nullable=False), sa.Column('read_only', sa.Boolean(), nullable=False, server_default='false'), sa.Column('metadata', sa.JSON(), nullable=False, server_default='{}'), sa.Column('created_at', sa.Text(), nullable=False), sa.PrimaryKeyConstraint('resource_id'), sa.ForeignKeyConstraint(['project_id'], ['projects.project_id'], ondelete='CASCADE') ) op.create_index('ix_resources_project_id', 'resources', ['project_id']) op.create_unique_constraint('uq_resources_project_name', 'resources', ['project_id', 'name'])- Commit: "feat(db): add resources table schema with FK to projects"
- B5.2c [Hamza] Add downgrade:
- Drop constraint, index, and table
- Commit: "feat(db): add resources table downgrade"
- B5.2a [Hamza] Generate migration file:
- B5.3 [Hamza] Create
ProjectModelinsrc/cleveragents/infrastructure/database/models.py:- B5.3a [Hamza] Define SQLAlchemy model:
class ProjectModel(Base): __tablename__ = 'projects' project_id = Column(Text, primary_key=True) name = Column(Text, nullable=False, unique=True) namespace = Column(Text, nullable=False, index=True) short_name = Column(Text, nullable=False) description = Column(Text, nullable=True) tags = Column(JSON, nullable=False, default=list) is_remote = Column(Boolean, nullable=False, default=False) validation_config = Column(JSON, nullable=True) context_config = Column(JSON, nullable=True) created_at = Column(Text, nullable=False) updated_at = Column(Text, nullable=False) # Relationship to resources resources = relationship("ResourceModel", back_populates="project", cascade="all, delete-orphan")- Commit: "feat(db): add ProjectModel SQLAlchemy class"
- B5.3b [Hamza] Add domain conversion methods:
def to_domain(self) -> Project: return Project( project_id=self.project_id, name=self.name, namespace=self.namespace, description=self.description, tags=self.tags or [], resources=[r.to_domain() for r in self.resources], validation_config=ValidationConfig(**self.validation_config) if self.validation_config else None, context_config=ContextConfig(**self.context_config) if self.context_config else ContextConfig(), created_at=datetime.fromisoformat(self.created_at), updated_at=datetime.fromisoformat(self.updated_at), ) @classmethod def from_domain(cls, project: Project) -> "ProjectModel": return cls( project_id=project.project_id, name=project.namespaced_name, namespace=project.namespace, short_name=project.name, description=project.description, tags=project.tags, is_remote=project.is_remote, validation_config=project.validation_config.model_dump() if project.validation_config else None, context_config=project.context_config.model_dump(), created_at=project.created_at.isoformat(), updated_at=project.updated_at.isoformat(), )- Commit: "feat(db): add ProjectModel domain conversion methods"
- B5.3a [Hamza] Define SQLAlchemy model:
- B5.4 [Hamza] Create
ResourceModelin same file:- B5.4a [Hamza] Define SQLAlchemy model:
class ResourceModel(Base): __tablename__ = 'resources' resource_id = Column(Text, primary_key=True) project_id = Column(Text, ForeignKey('projects.project_id', ondelete='CASCADE'), nullable=False) name = Column(Text, nullable=False) type = Column(Text, nullable=False) location = Column(Text, nullable=False) is_remote = Column(Boolean, nullable=False, default=False) sandbox_strategy = Column(Text, nullable=False) read_only = Column(Boolean, nullable=False, default=False) metadata = Column(JSON, nullable=False, default=dict) created_at = Column(Text, nullable=False) # Relationship back to project project = relationship("ProjectModel", back_populates="resources") __table_args__ = ( UniqueConstraint('project_id', 'name', name='uq_resources_project_name'), )- Commit: "feat(db): add ResourceModel SQLAlchemy class"
- B5.4b [Hamza] Add domain conversion methods:
to_domain()- Convert to Resource domain modelfrom_domain()- Create from Resource domain model- Handle enum conversions (ResourceType, SandboxStrategy)
- Commit: "feat(db): add ResourceModel domain conversion methods"
- B5.4a [Hamza] Define SQLAlchemy model:
- B5.5 [Hamza] Implement
ProjectRepositoryinsrc/cleveragents/infrastructure/database/repositories.py:- B5.5a [Hamza] Define class with session factory:
class ProjectRepository: def __init__(self, session_factory: Callable[[], Session]): self._session_factory = session_factory- Commit: "feat(repo): add ProjectRepository scaffold"
- B5.5b [Hamza] Implement
create(project: Project) -> Project:- Create ProjectModel from domain
- Add to session
- Handle duplicate name: raise
DuplicateProjectError - Commit transaction
- Return created project
- Commit: "feat(repo): implement ProjectRepository.create()"
- B5.5c [Hamza] Implement
get_by_id(project_id: str) -> Project | None:- Query by primary key with eager load of resources
- Convert to domain or return None
- Commit: "feat(repo): implement ProjectRepository.get_by_id()"
- B5.5d [Hamza] Implement
get_by_name(name: str) -> Project | None:- Query by namespaced name (unique index)
- Eager load resources
- Convert to domain
- Commit: "feat(repo): implement ProjectRepository.get_by_name()"
- B5.5e [Hamza] Implement
get_with_resources(project_id: str) -> Project | None:- Same as get_by_id but ensures resources are loaded
- Use
options(joinedload(ProjectModel.resources)) - Commit: "feat(repo): implement ProjectRepository.get_with_resources()"
- B5.5f [Hamza] Implement
list_all(namespace: str | None = None) -> list[Project]:- Query all projects
- Filter by namespace if provided
- Order by namespace ASC, short_name ASC
- Convert all to domain
- Commit: "feat(repo): implement ProjectRepository.list_all()"
- B5.5g [Hamza] Implement
update(project: Project) -> Project:- Fetch existing by project_id
- Update all fields from domain
- Update
updated_atto now - Commit and return
- Commit: "feat(repo): implement ProjectRepository.update()"
- B5.5h [Hamza] Implement
delete(project_id: str) -> bool:- Delete project (cascade deletes resources via FK)
- Return True if deleted
- Commit: "feat(repo): implement ProjectRepository.delete()"
- B5.5a [Hamza] Define class with session factory:
- B5.6 [Hamza] Implement
ResourceRepositoryin same file:- B5.6a [Hamza] Define class:
- Same pattern as ProjectRepository
- Commit: "feat(repo): add ResourceRepository scaffold"
- B5.6b [Hamza] Implement
create(resource: Resource, project_id: str) -> Resource:- Create ResourceModel with project_id link
- Handle duplicate name within project: raise
DuplicateResourceError - Commit: "feat(repo): implement ResourceRepository.create()"
- B5.6c [Hamza] Implement
get_by_project(project_id: str) -> list[Resource]:- Query all resources with given project_id
- Order by name ASC
- Commit: "feat(repo): implement ResourceRepository.get_by_project()"
- B5.6d [Hamza] Implement
get_by_name(project_id: str, name: str) -> Resource | None:- Query by unique (project_id, name) pair
- Commit: "feat(repo): implement ResourceRepository.get_by_name()"
- B5.6e [Hamza] Implement
delete(resource_id: str) -> bool:- Delete resource by ID
- Commit: "feat(repo): implement ResourceRepository.delete()"
- B5.6a [Hamza] Define class:
- B5.1 [Hamza] Create Alembic migration for
- Tests: Integration tests for persistence
- B5.7 [Rui] Write Behave scenarios in
features/project_persistence.feature:- B5.7a [Rui] Project persistence scenarios:
- Scenario: Create project persists to database
- Given no project "local/test" exists
- When I create project "local/test" via ProjectRepository
- Then querying by name returns the project
- And project_id is a valid ULID
- Scenario: Update project persists changes
- Given project "local/test" exists
- When I update description to "New description"
- Then re-querying shows updated description
- And updated_at has changed
- Commit: "test(behave): add project persistence scenarios"
- Scenario: Create project persists to database
- B5.7b [Rui] Resource persistence scenarios:
- Scenario: Add resource persists and links to project
- Given project "local/test" exists
- When I add resource "source" to project
- Then ResourceRepository.get_by_project() returns the resource
- And resource.project_id matches the project
- Scenario: Get project includes all resources
- Given project "local/test" with 3 resources
- When I call ProjectRepository.get_with_resources()
- Then project.resources has 3 items
- And each resource has correct fields
- Commit: "test(behave): add resource persistence scenarios"
- Scenario: Add resource persists and links to project
- B5.7c [Rui] Cascade scenarios:
- Scenario: Delete project cascades to resources
- Given project "local/test" with 2 resources
- When I delete the project
- Then ResourceRepository.get_by_project() returns empty list
- And the resource records no longer exist in database
- Commit: "test(behave): add cascade delete scenarios"
- Scenario: Delete project cascades to resources
- B5.7d [Rui] Uniqueness scenarios:
- Scenario: Duplicate project name raises error
- Given project "local/test" exists
- When I try to create another "local/test"
- Then DuplicateProjectError is raised
- Scenario: Duplicate resource name within project raises error
- Given project "local/test" has resource "source"
- When I try to add another resource named "source"
- Then DuplicateResourceError is raised
- Scenario: Same resource name in different projects is allowed
- Given project "local/proj1" has resource "source"
- When I add resource "source" to project "local/proj2"
- Then it succeeds without error
- Commit: "test(behave): add uniqueness constraint scenarios"
- Scenario: Duplicate project name raises error
- Method
get_by_project(project_id: str) -> list[Resource]
- B5.7a [Rui] Project persistence scenarios:
- B5.5 [Hamza] Create database model classes:
ProjectModel(Base)withto_domain()andfrom_domain()ResourceModel(Base)withto_domain()andfrom_domain()
- B5.7 [Rui] Write Behave scenarios in
- 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
- B5.6 [Rui] Write Behave scenarios in
- Code: Project/Resource database schema
M2 SUCCESS CRITERIA:
- Can create a project with resources via CLI
- Git repository resources can be sandboxed with worktrees
- Filesystem resources can be sandboxed with copy-on-write
- Plan execution uses sandboxed resources
- Sandbox cleanup works on success and failure
Section 5: Actors, Skills & Tool Execution [WORKSTREAM C - Aditya Lead]
Target: Milestone M3 (+14 days)
WEEK 2 - CRITICAL FOR MVP
Parallel Group C0: Tool Registry + Validation System [Jeff + Luis] (start Day 5; precedes C1/C3) PARALLEL SUBTRACK C0.domain [Jeff]: Tool + Validation domain models + schemas PARALLEL SUBTRACK C0.registry [Luis]: Tool registry persistence + repositories PARALLEL SUBTRACK C0.cli [Rui]: CLI commands for tools/validations SEQUENTIAL MERGE NOTE: C0.domain must land before C0.registry/cli; C0.registry before C3 context wiring.
- COMMIT (Owner: Jeff | Group: C0.domain) - Commit message: "feat(tool): add tool and validation domain models" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Add
Toolmodel with namespaced name, description, source type, input/output JSON schema, and capability metadata (read/write/checkpointable). - Code [Jeff]: Add
ResourceBindingmodel with slot definitions and binding modes (context, static, parameter). - Code [Jeff]: Add
Validationmodel as Tool subtype withmode,wraps, andtransformfields; enforce read-only constraints. - Code [Jeff]: Add enums for ToolSource, ToolType (tool/validation), and ValidationMode.
- Docs [Jeff]: Add
docs/reference/tool_model.mdanddocs/reference/validation_model.mdwith examples. - Tests (Behave) [Rui]: Add
features/tool_model.featurefor schema validation, resource binding rules, and validation constraints. - Tests (Robot) [Rui]: Add
robot/tool_model.robotsmoke tests for model creation. - Tests (ASV) [Rui]: Add
asv/benchmarks/tool_model_bench.pyfor schema validation throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(tool): add tool and validation domain models".
- Code [Jeff]: Add
- COMMIT (Owner: Luis | Group: C0.registry) - Commit message: "feat(tool): add tool registry persistence" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Luis]: Add DB tables for
tools,tool_bindings, andvalidation_attachmentswith indexes on namespaced name and type. - Code [Luis]: Implement ToolRepository + ValidationAttachmentRepository with list/show filters.
- Code [Luis]: Add ToolRegistryService for register/update/remove/list/show with name conflict checks.
- Docs [Luis]: Update
docs/reference/database_schema.mdwith tool/validation tables. - Tests (Behave) [Rui]: Add
features/tool_registry.featurefor register/update/remove and validation-only constraints. - Tests (Robot) [Rui]: Add
robot/tool_registry.robotfor list/show smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/tool_registry_bench.pyfor registry list performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(tool): add tool registry persistence".
- Code [Luis]: Add DB tables for
- COMMIT (Owner: Jeff | Group: C0.binding) - Commit message: "feat(tool): add resource binding resolution" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Jeff]: Implement binding resolution for contextual, static, and parameter bindings with type compatibility checks.
- Code [Jeff]: Add resolution helpers for resource name/ULID lookup and project-scoped filtering.
- Docs [Jeff]: Add
docs/reference/tool_bindings.mdwith resolution order and examples. - Tests (Behave) [Rui]: Add binding resolution scenarios (context vs static vs parameter).
- Tests (Robot) [Rui]: Add Robot test resolving a bound resource by name.
- Tests (ASV) [Rui]: Add
asv/benchmarks/binding_resolution_bench.pyfor resolution latency. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(tool): add resource binding resolution".
- COMMIT (Owner: Rui | Group: C0.cli) - Commit message: "feat(cli): add tool and validation commands" (COMMIT TASK: only check after every subtask below is complete,
noxand coverage succeed, and the commit is created)- Code [Rui]: Implement
agents tool add/remove/list/showwith YAML config input and--typefilter. - Code [Rui]: Implement
agents validation add/attach/detachcommands and enforce validation-only name use. - Docs [Rui]: Update CLI reference with tool/validation commands and output format.
- Tests (Behave) [Rui]: Add CLI scenarios for tool/validation registration and attachment.
- Tests (Robot) [Rui]: Add Robot CLI suites for tool and validation commands.
- Tests (ASV) [Rui]: Add
asv/benchmarks/tool_cli_bench.pyfor CLI parsing overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "feat(cli): add tool and validation commands".
- Code [Rui]: Implement
Parallel Group C1: Actor Schema & Examples [Aditya + Jeff] (start Day 5; C2 depends on this)
- COMMIT (Owner: Aditya | Group: C1.schema) - Commit message: "feat(actor): add actor yaml schema models" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Aditya]: Add schema models (ActorType, NodeType, ContextView, ToolDefinition, RouteDefinition, ActorConfigSchema) with strict validation.
- Code [Aditya]: Add tool-node schema fields that reference Tool Registry names, including validation nodes.
- Code [Aditya]: Add YAML load/serialize helpers and schema version guard.
- Docs [Aditya]: Add
docs/reference/actors_schema.mdwith field definitions, tool node semantics, and graph constraints. - Tests (Behave) [Rui]: Add
features/actor_schema.featurescenarios for validation and topology errors. - Tests (Robot) [Rui]: Add
robot/actor_schema.robotYAML load smoke test. - Tests (ASV) [Rui]: Add
asv/benchmarks/actor_schema_bench.pyfor YAML validation cost. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "feat(actor): add actor yaml schema models".
- COMMIT (Owner: Aditya | Group: C1.examples) - Commit message: "docs(actor): add actor yaml examples" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Docs [Aditya]: Add
docs/reference/actors_examples.mdwith strategist, executor, reviewer, tool-only, validation-node, and graph YAML examples. - Tests (Behave) [Rui]: Add
features/actor_examples.featureto ensure all examples validate. - Tests (Robot) [Rui]: Add
robot/actor_examples.robotto load each example. - Tests (ASV) [Rui]: Add
asv/benchmarks/actor_examples_load_bench.pyfor YAML load throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "docs(actor): add actor yaml examples".
- Docs [Aditya]: Add
Parallel Group C2: Actor Loading & Compilation [Aditya + Jeff] (depends on C1)
- COMMIT (Owner: Aditya | Group: C2.loader) - Commit message: "feat(actor): add actor registry and loader" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Aditya]: Implement actor loader/registry with namespaced lookup and cache invalidation.
- Code [Aditya]: Add registry integration with Tool Registry so tool nodes resolve at load time.
- Docs [Aditya]: Add
docs/reference/actors_loading.mdwith discovery rules and namespaces. - Tests (Behave) [Rui]: Add
features/actor_loading.featurefor discovery, duplicates, and namespace lookup. - Tests (Robot) [Rui]: Add
robot/actor_loading.robotfor loader smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/actor_loading_bench.pyfor registry load performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "feat(actor): add actor registry and loader".
- COMMIT (Owner: Jeff | Group: C2.compiler) - Commit message: "feat(actor): compile actor configs to LangGraph" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement ActorCompiler that builds LangGraph for LLM, TOOL, and GRAPH actors with tool node wiring.
- Code [Jeff]: Resolve tool node references through Tool Registry and validate required bindings before compile.
- Docs [Jeff]: Add
docs/reference/actors_compilation.mdcovering compile outputs and error modes. - Tests (Behave) [Rui]: Add
features/actor_compilation.featurefor LLM/GRAPH compilation and tool node wiring. - Tests (Robot) [Rui]: Add
robot/actor_compilation.robotsmoke test compiling all examples. - Tests (ASV) [Rui]: Add
asv/benchmarks/actor_compilation_bench.pyfor compilation speed. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(actor): compile actor configs to LangGraph".
- COMMIT (Owner: Jeff | Group: C2.refs) - Commit message: "feat(actor): resolve actor references and subgraphs" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement reference resolution, cycle detection, and subgraph wiring for actor refs.
- Code [Jeff]: Ensure cross-namespace reference resolution follows
[server:]namespace/namerules. - Docs [Jeff]: Update
docs/reference/actors_compilation.mdwith reference semantics. - Tests (Behave) [Rui]: Add
features/actor_reference_resolution.featurefor missing/recursive refs. - Tests (Robot) [Rui]: Add
robot/actor_reference_resolution.robotfor subgraph wiring. - Tests (ASV) [Rui]: Add
asv/benchmarks/actor_reference_bench.pyfor reference resolution performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(actor): resolve actor references and subgraphs".
Parallel Group C3: Skill Protocol & Context [Jeff] (critical path; depends on C1)
- COMMIT (Owner: Jeff | Group: C3.protocol) - Commit message: "feat(skill): add skill protocol and metadata" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Define Skill protocol interface, SkillMetadata, SkillResult, and SkillError types.
- Code [Jeff]: Add
SkillDefinitionmodel that references Tool Registry names and optional inline tool definitions. - Docs [Jeff]: Add
docs/reference/skills_protocol.mddescribing metadata, tool composition, and JSON schema rules. - Tests (Behave) [Rui]: Add
features/skill_protocol.featurefor metadata validation and error capture. - Tests (Robot) [Rui]: Add
robot/skill_protocol.robotsmoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/skill_protocol_bench.pyfor validation throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(skill): add skill protocol and metadata".
- COMMIT (Owner: Jeff | Group: C3.context) - Commit message: "feat(skill): add skill context and registry" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement SkillContext (plan/resource access, sandbox path, change tracker) and SkillRegistry.
- Code [Jeff]: Wire SkillRegistry to Tool Registry for tool resolution and validation node inclusion.
- Docs [Jeff]: Add
docs/reference/skills_context.mdwith context fields and helper methods. - Tests (Behave) [Rui]: Add
features/skill_context.featurefor sandboxed access and registry resolution. - Tests (Robot) [Rui]: Add
robot/skill_context.robotfor registry smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/skill_context_bench.pyfor registry resolution overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(skill): add skill context and registry".
- COMMIT (Owner: Jeff | Group: C3.inline) - Commit message: "feat(skill): add inline tool executor" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement inline tool execution with timeouts and restricted environment.
- Code [Jeff]: Ensure inline tools conform to Tool Registry schema and return structured results.
- Docs [Jeff]: Add
docs/reference/skills_inline.mdwith safety constraints. - Tests (Behave) [Rui]: Add
features/skill_inline.featurefor execution and timeout handling. - Tests (Robot) [Rui]: Add
robot/skill_inline.robotfor inline tool smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/inline_tool_bench.pyfor execution overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(skill): add inline tool executor".
Parallel Group C4: Built-in Skills [Jeff + Luis] (depends on C3)
- COMMIT (Owner: Jeff | Group: C4.file) - Commit message: "feat(skill): add file operation skills" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement ReadFile, WriteFile, EditFile, and DeleteFile tools with read_only enforcement.
- Code [Jeff]: Register tools in Tool Registry with resource bindings for fs/git resources.
- Docs [Jeff]: Add
docs/reference/skills_file.mdwith examples and error cases. - Tests (Behave) [Rui]: Add
features/skill_file_ops.featurefor read/write/edit/delete flows. - Tests (Robot) [Rui]: Add
robot/skill_file_ops.robotfor file ops integration. - Tests (ASV) [Rui]: Add
asv/benchmarks/file_tool_bench.pyfor read/write throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(skill): add file operation skills".
- COMMIT (Owner: Jeff | Group: C4.search) - Commit message: "feat(skill): add directory and search skills" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement ListDir, Glob, and Grep tools with ignore patterns and size limits.
- Code [Jeff]: Register tools in Tool Registry with resource bindings and sandbox awareness.
- Docs [Jeff]: Add
docs/reference/skills_search.mdwith examples. - Tests (Behave) [Rui]: Add
features/skill_search.featurefor listing/globbing/searching. - Tests (Robot) [Rui]: Add
robot/skill_search.robotfor search integration. - Tests (ASV) [Rui]: Add
asv/benchmarks/search_tool_bench.pyfor search performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(skill): add directory and search skills".
- COMMIT (Owner: Luis | Group: C4.git) - Commit message: "feat(skill): add git operation skills" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement read-only git tools (status, diff, log, show) for sandboxed repos.
- Code [Luis]: Register git tools in Tool Registry with read-only capability metadata.
- Docs [Luis]: Add
docs/reference/skills_git.mdclarifying no destructive ops in MVP. - Tests (Behave) [Rui]: Add
features/skill_git.featurefor git tool outputs. - Tests (Robot) [Rui]: Add
robot/skill_git.robotfor git tool integration. - Tests (ASV) [Rui]: Add
asv/benchmarks/git_tool_bench.pyfor diff/log performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(skill): add git operation skills".
Parallel Group C5: Tool Routing & Change Tracking [Luis + Jeff] (depends on C3/C4)
- COMMIT (Owner: Luis | Group: C5.model) - Commit message: "feat(change): add ChangeSet models and invocation tracker" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add Change/ChangeSet/ToolInvocation models and SkillInvocationTracker.
- Code [Luis]: Ensure ChangeSet stores resource references, sandbox paths, and tool metadata.
- Docs [Luis]: Add
docs/reference/change_tracking.mddescribing tool-to-change mapping. - Tests (Behave) [Rui]: Add
features/change_tracking.featurefor ChangeSet aggregation. - Tests (Robot) [Rui]: Add
robot/change_tracking.robotfor tracker smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/change_tracking_bench.pyfor invocation tracking overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(change): add ChangeSet models and invocation tracker".
- COMMIT (Owner: Jeff | Group: C5.router) - Commit message: "feat(change): add tool router for providers" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement ToolCallRouter for OpenAI/Anthropic/LangChain tool schemas with deterministic IDs.
- Code [Jeff]: Add mapping for tool/validation names and argument schemas based on Tool Registry metadata.
- Docs [Jeff]: Add
docs/reference/tool_router.mdwith provider-specific mappings. - Tests (Behave) [Rui]: Add
features/tool_router.featurefor schema mapping. - Tests (Robot) [Rui]: Add
robot/tool_router.robotfor routing smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/tool_router_bench.pyfor routing performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(change): add tool router for providers".
- COMMIT (Owner: Luis | Group: C5.diff) - Commit message: "feat(change): add diff review artifacts" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement DiffBuilder and ReviewArtifact models for CLI review.
- Code [Luis]: Add support for multi-resource diffs and per-resource grouping.
- Docs [Luis]: Add
docs/reference/diff_review.mdwith output format. - Tests (Behave) [Rui]: Add
features/diff_review.featurefor diff generation. - Tests (Robot) [Rui]: Add
robot/diff_review.robotfor review artifacts. - Tests (ASV) [Rui]: Add
asv/benchmarks/diff_review_bench.pyfor diff building performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(change): add diff review artifacts".
Parallel Group C6: Validation Pipeline [Luis + Jeff] (depends on C5 and project validation config)
- COMMIT (Owner: Luis | Group: C6.pipeline) - Commit message: "feat(validation): add validation pipeline and results model" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement ValidationCommand, ValidationResult, and ValidationPipeline using Validation attachments from Tool Registry.
- Code [Luis]: Run validations at end of Execute phase only; do not re-run during Apply per spec.
- Code [Luis]: Enforce required vs informational validation modes and fix-then-revalidate loop hooks.
- Docs [Luis]: Add
docs/reference/validation_pipeline.mdwith ordering, timeouts, and failure handling. - Tests (Behave) [Rui]: Add
features/validation_pipeline.featurefor pass/fail paths and required/informational modes. - Tests (Robot) [Rui]: Add
robot/validation_pipeline.robotfor pipeline smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/validation_pipeline_bench.pyfor pipeline runtime. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(validation): add validation pipeline and results model".
- COMMIT (Owner: Jeff | Group: C6.gating) - Commit message: "feat(validation): integrate validation with apply gating" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Block apply on required validation failure; surface validation artifacts for review.
- Code [Jeff]: Ensure informational validation failures do not block apply but are logged in plan status.
- Docs [Jeff]: Update
docs/reference/plan_actor_integration.mdwith validation gating behavior. - Tests (Behave) [Rui]: Add
features/validation_gating.featurefor apply blocking. - Tests (Robot) [Rui]: Add
robot/validation_gating.robotfor end-to-end gating. - Tests (ASV) [Rui]: Add
asv/benchmarks/validation_gating_bench.pyfor gating overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(validation): integrate validation with apply gating".
Parallel Group C7: MCP Adapter [Aditya] (depends on C3)
- COMMIT (Owner: Aditya | Group: C7.mcp) - Commit message: "feat(skill): add MCP adapter for external tools" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Aditya]: Implement MCP client adapter conforming to Tool interface with connection config.
- Code [Aditya]: Register MCP tools in Tool Registry with dynamic discovery from MCP server.
- Docs [Aditya]: Add
docs/reference/skills_mcp.mdwith server connection examples. - Tests (Behave) [Rui]: Add
features/skill_mcp.featurefor MCP tool calls. - Tests (Robot) [Rui]: Add
robot/skill_mcp.robotfor MCP adapter smoke test. - Tests (ASV) [Rui]: Add
asv/benchmarks/mcp_adapter_bench.pyfor tool invocation latency. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "feat(skill): add MCP adapter for external tools".
Parallel Group C8: Built-in Provider Actors [Aditya] (depends on C1/C2)
- COMMIT (Owner: Aditya | Group: C8.providers) - Commit message: "feat(actor): add built-in provider actors" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Aditya]: Add built-in actor configs for
openai/,anthropic/, andopenrouter/(plusgoogle/if configured). - Code [Aditya]: Add built-in actors for invariant reconciliation and estimation roles (using provider defaults).
- Docs [Aditya]: Add
docs/reference/provider_actors.mdwith provider defaults. - Tests (Behave) [Rui]: Add
features/provider_actors.featurefor built-in actor loading. - Tests (Robot) [Rui]: Add
robot/provider_actors.robotfor registry visibility. - Tests (ASV) [Rui]: Add
asv/benchmarks/provider_actor_load_bench.pyfor registry load cost. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "feat(actor): add built-in provider actors".
- Code [Aditya]: Add built-in actor configs for
Parallel Group C9: Plan-Actor Integration [Jeff + Luis] (depends on C2/C5/C6)
- COMMIT (Owner: Jeff | Group: C9.execute) - Commit message: "feat(plan): execute strategize and execute phases via actors" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Connect PlanLifecycleService to actor execution for Strategize and Execute phases.
- Code [Jeff]: Ensure Strategize is read-only and records decisions without modifying resources.
- Code [Jeff]: Ensure Execute uses sandbox resources and tool calls routed through Tool Router + ChangeSet.
- Docs [Jeff]: Add
docs/reference/plan_actor_integration.mdwith phase flow. - Tests (Behave) [Rui]: Add
features/plan_actor_integration.featurefor strategy/execute flows. - Tests (Robot) [Rui]: Add
robot/plan_actor_integration.robotfor end-to-end actor execution. - Tests (ASV) [Rui]: Add
asv/benchmarks/plan_actor_integration_bench.pyfor execution overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(plan): execute strategize and execute phases via actors".
- COMMIT (Owner: Jeff | Group: C9.apply) - Commit message: "feat(plan): integrate change review and apply flow" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Wire ChangeSet review artifacts into
plan diffand review-before-apply flow. - Code [Jeff]: Ensure Apply merges sandbox into real resources only after required validations pass.
- Docs [Jeff]: Update CLI docs for
plan diffandplan applyreview output. - Tests (Behave) [Rui]: Add
features/plan_review_apply.featurefor review gate behavior. - Tests (Robot) [Rui]: Add
robot/plan_review_apply.robotfor review-before-apply path. - Tests (ASV) [Rui]: Add
asv/benchmarks/plan_apply_bench.pyfor apply throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(plan): integrate change review and apply flow".
- Code [Jeff]: Wire ChangeSet review artifacts into
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
- 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 1: After M3, all workstreams coordinate ---
Section 6: Execution Pipeline, Decisions & Invariants [M3-M4]
Target: Milestone M4 (+21 days)
Parallel Group D1: Decision Domain [Hamza + Rui] (foundation for D2-D5)
- COMMIT (Owner: Hamza | Group: D1.domain) - Commit message: "feat(domain): add decision model and context snapshots" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Add
DecisionType,ContextSnapshot, andDecisionmodels with correction fields and helpers. - Code [Hamza]: Include required fields: question, chosen option, alternatives, confidence score, rationale, dependencies, and context hash.
- Docs [Hamza]: Add
docs/reference/decision_model.mdwith examples and schema notes. - Tests (Behave) [Rui]: Add
features/decision_model.featurefor validation and helpers. - Tests (Robot) [Rui]: Add
robot/decision_model.robotsmoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/decision_model_bench.pyfor decision validation throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(domain): add decision model and context snapshots".
- Code [Hamza]: Add
Parallel Group D2: Decision Recording Service [Hamza + Luis] (depends on D1)
- COMMIT (Owner: Hamza | Group: D2.service) - Commit message: "feat(service): add decision recording and snapshot store" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement
DecisionServicewithrecord_decision, sequence numbers, tree queries, and downstream linking. - Code [Hamza]: Add
ContextSnapshotStoreinterface with a file-backed MVP implementation and hash dedupe. - Code [Luis]: Integrate decision recording into strategize/execute phases (prompt/strategy/subplan/tool decisions).
- Docs [Hamza]: Add
docs/reference/decision_service.mdcovering recording and snapshots. - Tests (Behave) [Rui]: Add
features/decision_recording.featurescenarios. - Tests (Robot) [Rui]: Add
robot/decision_recording.robotintegration smoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/decision_recording_bench.pyfor record throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(service): add decision recording and snapshot store".
- Code [Hamza]: Implement
Parallel Group D3: Decision CLI & Viewing [Hamza + Rui] (depends on D1/D2)
- COMMIT (Owner: Hamza | Group: D3.cli) - Commit message: "feat(cli): add plan tree and explain commands" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement
plan treeandplan explainwith rich/json/flat formats and--show-superseded/--show-context. - Code [Hamza]: Add
--show-reasoningto include confidence and alternatives in explain output per spec. - Docs [Hamza]: Update CLI reference for decision viewing commands.
- Tests (Behave) [Rui]: Add tree/explain scenarios including superseded handling.
- Tests (Robot) [Rui]: Add
robot/decision_cli.robotsmoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/decision_cli_bench.pyfor tree rendering overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(cli): add plan tree and explain commands".
- Code [Hamza]: Implement
Parallel Group D4: Decision Correction [Jeff + Luis] (depends on D2/D3)
- COMMIT (Owner: Jeff | Group: D4.revert) - Commit message: "feat(service): add decision correction revert flow" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement correction impact analysis and dry-run reporting.
- Code [Jeff]: Revert flow with checkpoint rollback, supersede downstream decisions, and subtree re-exec.
- Code [Jeff]: Persist correction attempt IDs and link them to superseded decisions.
- Docs [Jeff]: Add
docs/reference/decision_correction.mdfor revert behavior. - Tests (Behave) [Rui]: Add revert + dry-run scenarios.
- Tests (Robot) [Rui]: Add revert integration tests with checkpoint rollback.
- Tests (ASV) [Rui]: Add
asv/benchmarks/decision_correction_revert_bench.pyfor correction overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(service): add decision correction revert flow".
- COMMIT (Owner: Jeff | Group: D4.append) - Commit message: "feat(service): add decision correction append flow" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Append flow creating fix subplan without rewriting history; link correction attempt + decision tree updates.
- Code [Jeff]: Record append corrections as separate subtree with explicit lineage.
- Docs [Jeff]: Extend correction docs for append mode and guidance-file usage.
- Tests (Behave) [Rui]: Add append correction scenarios.
- Tests (Robot) [Rui]: Add append correction smoke test.
- Tests (ASV) [Rui]: Add
asv/benchmarks/decision_correction_append_bench.pyfor append overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(service): add decision correction append flow".
Parallel Group D5: Decision Persistence [Hamza + Luis] (depends on D1)
- COMMIT (Owner: Hamza | Group: D5.db) - Commit message: "feat(db): add decision tables" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Add Alembic migrations for
decisionsandcontext_snapshotswith indexes. - Code [Hamza]: Add indexes for plan_id, decision_type, and superseded flags for fast tree queries.
- Docs [Hamza]: Update
docs/reference/database_schema.mdwith decision tables. - Tests (Behave) [Rui]: Add migration verification scenarios.
- Tests (Robot) [Rui]: Add DB migration smoke test.
- Tests (ASV) [Rui]: Add
asv/benchmarks/decision_migration_bench.pyfor migration baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(db): add decision tables".
- Code [Hamza]: Add Alembic migrations for
- COMMIT (Owner: Hamza | Group: D5.repo) - Commit message: "feat(repo): add decision repositories" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement DecisionRepository + ContextSnapshotRepository with tree queries and max-sequence helpers.
- Code [Hamza]: Add repository methods for superseded decision lookup and subtree retrieval.
- Docs [Hamza]: Document repository interfaces in
docs/reference/repositories.md. - Tests (Behave) [Rui]: Add decision persistence scenarios (create/query/superseded).
- Tests (Robot) [Rui]: Add repository integration smoke test.
- Tests (ASV) [Rui]: Add
asv/benchmarks/decision_repository_bench.pyfor tree query performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(repo): add decision repositories".
- COMMIT (Owner: Luis | Group: D5.di) - Commit message: "feat(di): wire decision services" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Wire decision repositories + services into DI and CLI.
- Docs [Luis]: Update DI docs for decision wiring.
- Tests (Behave) [Rui]: Add DI wiring scenarios for decision commands.
- Tests (Robot) [Rui]: Add CLI smoke test using persisted decisions.
- Tests (ASV) [Rui]: Add
asv/benchmarks/decision_di_bench.pyfor DI resolution overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(di): wire decision services".
- COMMIT (Owner: Rui | Group: D5.tests) - Commit message: "test(persistence): add decision persistence suites" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Tests (Behave) [Rui]: Add
features/decision_persistence.featurescenarios. - Tests (Robot) [Rui]: Add
robot/decision_persistence.robotE2E coverage. - Docs [Rui]: Update
docs/development/testing.mdwith decision suites. - Tests (ASV) [Rui]: Add
asv/benchmarks/decision_persistence_bench.pyfor DB persistence throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Rui]:
git commit -m "test(persistence): add decision persistence suites".
- Tests (Behave) [Rui]: Add
Parallel Group DOD: Definition of Done + Invariants [Luis + Jeff] (depends on D2/D4)
- COMMIT (Owner: Luis | Group: DOD.dod) - Commit message: "feat(dod): enforce definition-of-done gating" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Evaluate
definition_of_donebefore apply; block apply with clear error if unmet. - Code [Luis]: Ensure DoD templating uses plan arguments and preserves template in plan metadata.
- Docs [Luis]: Add
docs/reference/definition_of_done.mdwith examples. - Tests (Behave) [Rui]: Add DoD pass/fail scenarios.
- Tests (Robot) [Rui]: Add DoD integration smoke test.
- Tests (ASV) [Rui]: Add
asv/benchmarks/dod_evaluation_bench.pyfor evaluation overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(dod): enforce definition-of-done gating".
- Code [Luis]: Evaluate
- COMMIT (Owner: Jeff | Group: DOD.invariants) - Commit message: "feat(invariant): add invariant models and enforcement" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Add invariant models, merge order (plan > project > action > global), and enforcement before strategize.
- Code [Jeff]: Add Invariant Reconciliation Actor role and record
invariant_enforceddecisions. - Code [Jeff]: Add
agents invariant add/list/removeCLI with scope flags. - Docs [Jeff]: Add
docs/reference/invariants.mdand update CLI reference. - Tests (Behave) [Rui]: Add invariant merge + violation scenarios.
- Tests (Robot) [Rui]: Add invariant CLI integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/invariant_merge_bench.pyfor merge overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(invariant): add invariant models and enforcement".
Section 7: Subplans & Parallelism [M5]
Target: Milestone M5 (+25 days)
Parallel Group E1: Subplan Domain [Luis + Rui]
- COMMIT (Owner: Luis | Group: E1.domain) - Commit message: "feat(domain): add subplan config and status models" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add
ExecutionMode,MergeStrategy,SubplanConfig,SubplanStatus, andSubplanAttemptmodels. - Code [Luis]: Extend
Planwith parent/root IDs, subplan statuses, and helpers (is_subplan,has_subplans). - Docs [Luis]: Add
docs/reference/subplan_model.md. - Tests (Behave) [Rui]: Add
features/subplan_model.featurescenarios. - Tests (Robot) [Rui]: Add
robot/subplan_model.robotsmoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/subplan_model_bench.pyfor model validation. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(domain): add subplan config and status models".
- Code [Luis]: Add
Parallel Group E2: Subplan Spawning [Jeff + Aditya] (depends on D2 + E1)
- COMMIT (Owner: Jeff | Group: E2.service) - Commit message: "feat(service): add subplan service and spawn workflow" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Implement
SubplanServicewithspawn_subplan,spawn_batch, tree queries, bounded context builder. - Code [Jeff]: Link SUBPLAN_SPAWN decisions to created subplans and status tracking.
- Docs [Jeff]: Add
docs/reference/subplan_service.md. - Tests (Behave) [Rui]: Add subplan spawn scenarios.
- Tests (Robot) [Rui]: Add subplan spawn integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/subplan_spawn_bench.pyfor spawn throughput. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(service): add subplan service and spawn workflow".
- Code [Jeff]: Implement
- COMMIT (Owner: Aditya | Group: E2.actor) - Commit message: "feat(actor): add plan_subplan tool and decision emission" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Aditya]: Add
plan_subplantool to strategy actors and emit SUBPLAN_SPAWN decisions. - Docs [Aditya]: Update actor YAML examples for subplan emission.
- Tests (Behave) [Rui]: Add scenarios for subplan decision emission.
- Tests (Robot) [Rui]: Add actor tool integration smoke tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/subplan_actor_tool_bench.pyfor tool invocation overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Aditya]:
git commit -m "feat(actor): add plan_subplan tool and decision emission".
- Code [Aditya]: Add
Parallel Group E3: Parallel Execution [Luis + Jeff] (depends on E1/E2)
- COMMIT (Owner: Luis | Group: E3.exec) - Commit message: "feat(service): add subplan scheduler and execution" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add subplan scheduler with
max_parallel, dependency ordering, and fail-fast handling. - Code [Luis]: Track status updates for subplans and propagate to parent plan.
- Docs [Luis]: Add
docs/reference/subplan_execution.md. - Tests (Behave) [Rui]: Add parallel + dependency execution scenarios.
- Tests (Robot) [Rui]: Add parallel execution integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/subplan_scheduler_bench.pyfor scheduler overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(service): add subplan scheduler and execution".
- Code [Luis]: Add subplan scheduler with
Parallel Group E4: Result Merging [Jeff + Luis] (depends on E3)
- COMMIT (Owner: Jeff | Group: E4.merge) - Commit message: "feat(merge): add subplan merge strategies" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Add three-way merge strategy for file changes and conflict markers.
- Code [Luis]: Add sequential merge and JSON merge strategies; expose merge result artifacts.
- Docs [Jeff]: Add
docs/reference/subplan_merge.md. - Tests (Behave) [Rui]: Add merge + conflict scenarios.
- Tests (Robot) [Rui]: Add merge integration tests for multi-subplan plans.
- Tests (ASV) [Rui]: Add
asv/benchmarks/subplan_merge_bench.pyfor merge performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(merge): add subplan merge strategies".
Parallel Group E5: Multi-Project Plans [Hamza + Luis] (depends on E2/E4)
-
COMMIT (Owner: Hamza | Group: E5.multi) - Commit message: "feat(plan): add multi-project subplan support" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Allow plans to target multiple projects with separate resource link contexts.
- Code [Luis]: Ensure sandbox isolation and cross-project dependency resolution.
- Docs [Hamza]: Add
docs/reference/multi_project_plans.md. - Tests (Behave) [Rui]: Add multi-project subplan scenarios.
- Tests (Robot) [Rui]: Add multi-project integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/multi_project_bench.pyfor multi-project overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(plan): add multi-project subplan support".
-
Stage E5: Multi-Project Plans (Day 25) [Hamza]
SEQUENTIAL ORDER: E5.1 (Model extension) → E5.2 (Strategy changes) → E5.3 (Apply per project) → E5.4 (Cross-project deps) → E5.5 (Tests)
- E5.1 [Hamza] Extend Plan model for multiple projects:
- E5.1a [Hamza] Add projects field to Plan:
# In Plan model project_ids: list[str] = Field( default_factory=list, description="Project IDs this plan targets" ) @property def is_multi_project(self) -> bool: """Check if plan targets multiple projects.""" return len(self.project_ids) > 1- Commit: "feat(domain): add multi-project support to Plan"
- E5.1b [Hamza] Add per-project sandbox tracking:
project_sandboxes: dict[str, str] = Field( default_factory=dict, description="Map of project_id to sandbox_id" ) project_apply_status: dict[str, ApplyStatus] = Field( default_factory=dict, description="Apply status per project" )- Commit: "feat(domain): add per-project sandbox tracking"
- E5.1a [Hamza] Add projects field to Plan:
- E5.2 [Hamza] Update strategy to include project assignments:
- E5.2a [Hamza] Add project field to subplan decisions:
# Strategy actor can specify project for subplan context.create_subplan_decision( action_name="local/code-fix", description="Fix auth in backend", target_files=["src/auth/*.py"], target_project="backend" # New field )- Commit: "feat(actor): add project targeting to subplan decisions"
- E5.2b [Hamza] Build cross-project dependency graph:
def build_cross_project_dag( self, decisions: list[Decision] ) -> CrossProjectDAG: """Build dependency graph that spans projects.""" dag = CrossProjectDAG() for decision in decisions: project = self._get_target_project(decision) dag.add_node(decision.decision_id, project=project) for dep_id in self._get_depends_on(decision): dep_project = self._get_project_for_decision(dep_id) dag.add_edge(dep_id, decision.decision_id) # Track cross-project edges if dep_project != project: dag.mark_cross_project_edge(dep_id, decision.decision_id) return dag- Commit: "feat(service): implement cross-project dependency tracking"
- E5.2a [Hamza] Add project field to subplan decisions:
- E5.3 [Hamza] Apply commits per project:
- E5.3a [Hamza] Implement per-project apply:
async def apply_multi_project( self, plan: Plan ) -> MultiProjectApplyResult: """Apply changes to each project separately.""" results = {} for project_id in plan.project_ids: try: result = await self._apply_single_project(plan, project_id) results[project_id] = ApplyStatus.SUCCESS except Exception as e: results[project_id] = ApplyStatus.FAILED logger.error(f"Apply failed for project {project_id}: {e}") # Don't fail others unless they depend on this one if self._has_dependents(project_id, plan): logger.warning(f"Dependents of {project_id} will also fail") return MultiProjectApplyResult( project_statuses=results, fully_applied=all(s == ApplyStatus.SUCCESS for s in results.values()) )- Commit: "feat(service): implement per-project apply"
- E5.3b [Hamza] Support partial apply:
async def apply_partial( self, plan: Plan, project_ids: list[str] ) -> MultiProjectApplyResult: """Apply only to specified projects.""" # Validate selected projects are valid invalid = set(project_ids) - set(plan.project_ids) if invalid: raise InvalidProjectError(f"Projects not in plan: {invalid}") # Check dependency constraints for pid in project_ids: deps = self._get_project_dependencies(plan, pid) missing_deps = deps - set(project_ids) if missing_deps: raise DependencyNotAppliedError( f"Project {pid} depends on unapplied: {missing_deps}" ) return await self._apply_projects(plan, project_ids)- Commit: "feat(service): implement partial project apply"
- E5.3a [Hamza] Implement per-project apply:
- E5.4 [Hamza] Handle cross-project dependencies:
- E5.4a [Hamza] Enforce dependency order in apply:
def get_project_apply_order( self, plan: Plan ) -> list[str]: """Get order to apply projects respecting dependencies.""" dag = self._build_project_dependency_dag(plan) return dag.topological_sort() async def apply_in_dependency_order( self, plan: Plan ) -> MultiProjectApplyResult: """Apply projects in correct dependency order.""" order = self.get_project_apply_order(plan) results = {} for project_id in order: # Check all dependencies succeeded deps = self._get_project_dependencies(plan, project_id) if not all(results.get(d) == ApplyStatus.SUCCESS for d in deps): results[project_id] = ApplyStatus.SKIPPED_DEPENDENCY_FAILED continue # Apply this project result = await self._apply_single_project(plan, project_id) results[project_id] = result return MultiProjectApplyResult(project_statuses=results)- Commit: "feat(service): implement dependency-ordered project apply"
- E5.4a [Hamza] Enforce dependency order in apply:
- E5.5 [Rui] Write end-to-end tests for multi-project:
- E5.5a [Rui] Multi-project scenarios:
- Scenario: Plan targets two projects with separate sandboxes
- Given plan with project_ids=[proj1, proj2]
- When plan executes
- Then each project has separate sandbox
- Scenario: Changes applied to each project separately
- Given completed multi-project plan
- When apply is called
- Then proj1 gets its changes
- And proj2 gets its changes
- Commit: "test(behave): add multi-project scenarios"
- Scenario: Plan targets two projects with separate sandboxes
- E5.5b [Rui] Cross-project dependency scenarios:
- Scenario: Dependent project waits for dependency
- Given proj2 depends on proj1 changes
- When apply runs
- Then proj1 is applied first
- And proj2 is applied after proj1 succeeds
- Scenario: Dependent project skipped if dependency fails
- Given proj2 depends on proj1
- And proj1 apply fails
- Then proj2 is marked SKIPPED_DEPENDENCY_FAILED
- Commit: "test(behave): add cross-project dependency scenarios"
- Scenario: Dependent project waits for dependency
- E5.5a [Rui] Multi-project scenarios:
- E5.1 [Hamza] Extend Plan model for multiple projects:
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
Parallel Group G1: Large-Project Decomposition [Jeff + Luis]
- COMMIT (Owner: Jeff | Group: G1.decompose) - Commit message: "feat(plan): add large-project decomposition and dependency closure" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Jeff]: Add hierarchical decomposition with 4+ levels and bounded context per subplan.
- Code [Luis]: Add dependency closure computation for large graphs and DAG execution ordering.
- Docs [Jeff]: Add
docs/reference/large_project_decomposition.md. - Tests (Behave) [Rui]: Add deep hierarchy + dependency closure scenarios.
- Tests (Robot) [Rui]: Add large-project decomposition integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/large_project_decompose_bench.pyfor decomposition runtime. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "feat(plan): add large-project decomposition and dependency closure".
Parallel Group G2: Checkpointing & Rollback [Luis]
- COMMIT (Owner: Luis | Group: G2.checkpoint) - Commit message: "feat(checkpoint): add checkpointing and rollback" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add checkpoint declarations for tools and plan-level rollback policy.
- Code [Luis]: Implement
plan rollback <plan_id> <checkpoint_id>command. - Docs [Luis]: Add
docs/reference/checkpointing.md. - Tests (Behave) [Rui]: Add checkpoint/rollback scenarios.
- Tests (Robot) [Rui]: Add rollback integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/checkpoint_rollback_bench.pyfor rollback latency. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(checkpoint): add checkpointing and rollback".
Parallel Group G3: Semantic Validation [Luis]
- COMMIT (Owner: Luis | Group: G3.semantic) - Commit message: "feat(validation): add semantic validation service" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add semantic validation hooks during strategize/execute and error-pattern checks.
- Docs [Luis]: Add
docs/reference/semantic_validation.md. - Tests (Behave) [Rui]: Add semantic validation scenarios.
- Tests (Robot) [Rui]: Add semantic validation integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/semantic_validation_bench.pyfor validation cost. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(validation): add semantic validation service".
Parallel Group G4: Context Tiers & Views [Hamza + Rui]
- COMMIT (Owner: Hamza | Group: G4.context) - Commit message: "feat(context): add hot/warm/cold tiers and actor views" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Implement hot/warm/cold tiers with indexing, LRU eviction, and promotion/demotion.
- Code [Hamza]: Add per-actor context views (strategist/executor/reviewer) and filtered presentation.
- Docs [Hamza]: Add
docs/reference/context_tiers.md. - Tests (Behave) [Rui]: Add context tier scenarios.
- Tests (Robot) [Rui]: Add context tier integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/context_tiers_bench.pyfor tier lookup performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(context): add hot/warm/cold tiers and actor views".
Parallel Group G5: Cost & Risk Estimation [Hamza]
- COMMIT (Owner: Hamza | Group: G5.estimate) - Commit message: "feat(estimation): add cost and risk estimation actor" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Hamza]: Add optional
estimation_actorrole and cost/risk estimation outputs. - Docs [Hamza]: Add
docs/reference/estimation.mdwith output format. - Tests (Behave) [Rui]: Add estimation scenarios.
- Tests (Robot) [Rui]: Add estimation integration smoke tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/estimation_actor_bench.pyfor estimation runtime. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Hamza]:
git commit -m "feat(estimation): add cost and risk estimation actor".
- Code [Hamza]: Add optional
Parallel Group G6: CLI Polish [All]
- COMMIT (Owner: Jeff | Group: G6.cli) - Commit message: "chore(cli): polish help and output" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [All]: Standardize help text, progress indicators, and error messages with recovery hints.
- Docs [All]: Update CLI output examples where needed.
- Tests (Robot) [Rui]: Add CLI UX smoke tests for critical commands.
- Tests (ASV) [Rui]: Add
asv/benchmarks/cli_render_bench.pyfor output rendering overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Jeff]:
git commit -m "chore(cli): polish help and output".
--- MERGE POINT 2: Day 30 - Large Project Autonomy Target (LOCAL MODE ONLY) ---
By Day 30, the system must be able to (all in LOCAL MODE, server connectivity is deferred):
- Handle projects with 10,000+ files using hierarchical decomposition
- Port source code from one language to another autonomously
- Use hierarchical subplans (5+ levels deep) for large tasks
- Correct decisions at any point without full re-execution
- Operate entirely in local mode (server client stubs in place but not implemented)
Note: Server connectivity (M7 as redefined) is deferred beyond Day 30. The server is a separate project. The Day 30 goal focuses on autonomous large project handling in local mode.
Section 9: Full Feature Set [Days 31-35]
Target: Milestone M7 (+35 days)
Parallel Group F0: Server Client Stubs [Luis + Rui] (required for M6; no server implementation)
-
COMMIT (Owner: Luis | Group: F0.stubs) - Commit message: "feat(interfaces): add server client stubs" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add protocol stubs for
ServerClient,RemoteExecutionClient, andAuthClientwith NotImplementedError. - Code [Luis]: Add
agents connect <server_url>CLI stub incli/commands/server_client.py. - Docs [Luis]: Add
docs/reference/server_client_stubs.mdnoting client-only behavior. - Tests (Behave) [Rui]: Add stub behavior scenarios.
- Tests (Robot) [Rui]: Add CLI stub smoke test.
- Tests (ASV) [Rui]: Add
asv/benchmarks/server_stub_bench.py(baseline no-op). - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(interfaces): add server client stubs".
- Code [Luis]: Add protocol stubs for
-
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 G3: Semantic Validation Framework (Day 33-34) [Luis]
- G3.1 [Luis] Decision-time validation in Strategize:
- Every decision includes semantic validation
- Record
validation_performedlist 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 changesvalidate_type_safety- check types are preservedauto_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]
- Method
- 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
- G3.1 [Luis] Decision-time validation in Strategize:
-
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
ActorContextViewservice - 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
- Implement
- 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
- G4.1 [Hamza] Hot context management (10-20 files):
-
Stage G5: Cost & Risk Estimation (Day 35) [Hamza]
- G5.1 [Hamza] Estimation actor implementation:
- Create optional
estimation_actorrole in action model - Estimation actor runs after Strategize completes, before Execute
- Input: strategy output, project context
- Output: cost estimate, risk assessment, time estimate
- Create optional
- 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
- Analyze strategy for risky operations:
- G5.4 [Hamza] Display estimation before execute:
- Show estimated cost before user confirms execute
- Support
--yesto bypass confirmation in automation contexts - 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
- G5.1 [Hamza] Estimation actor implementation:
-
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
- Full test coverage (>85%)
- Documentation complete
- Ready for release
Section 10: Async Infrastructure & Later-Stage Quality Work [Various Leads]
Note: Quality automation setup is in Section 0; Section 10 focuses on async infrastructure and later-stage validation support.
Parallel Group 10A: Async Infrastructure [Luis]
- COMMIT (Owner: Luis | Group: 10A.async) - Commit message: "feat(async): add async command execution and workers" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Implement async command execution per ADR-002 with cancellation and timeout handling.
- Code [Luis]: Add background worker orchestration for plan lifecycle events.
- Docs [Luis]: Update
docs/reference/async_architecture.mdwith execution flow and shutdown rules. - Tests (Behave) [Rui]: Add
features/async_execution.featurefor async command handling. - Tests (Robot) [Rui]: Add
robot/async_execution.robotsmoke tests. - Tests (ASV) [Rui]: Add
asv/benchmarks/async_execution_bench.pyfor worker scheduling overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(async): add async command execution and workers".
- COMMIT (Owner: Luis | Group: 10A.retry) - Commit message: "feat(async): wire retry policies into services" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Integrate retry/circuit breaker policies into service layer operations.
- Docs [Luis]: Document retry policy defaults and override points.
- Tests (Behave) [Rui]: Add retry/circuit breaker behavior scenarios.
- Tests (Robot) [Rui]: Add resilience smoke tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/retry_policy_bench.pyfor retry overhead. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "feat(async): wire retry policies into services".
Parallel Group 10B: Selective Quality Review [Brent]
- COMMIT (Owner: Brent | Group: 10B.review) - Commit message: "docs(qa): add review playbook and priority matrix" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Docs [Brent]: Create
docs/development/review_playbook.mdwith focus areas and skip rules. - Docs [Brent]: Add priority matrix and review SLA guidance.
- Tests (Behave) [Rui]: Add scenarios validating review playbook references exist.
- Tests (Robot) [Rui]: Add docs build smoke test covering the new guide.
- Tests (ASV) [Rui]: Add
asv/benchmarks/docs_build_bench.pyfor docs build baseline. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Brent]:
git commit -m "docs(qa): add review playbook and priority matrix".
- Docs [Brent]: Create
Parallel Group 10C: Validation Testing Support [Brent + Luis]
- COMMIT (Owner: Brent | Group: 10C.edge) - Commit message: "test(validation): add edge case suites" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Brent]: Add shared edge-case fixtures under
features/fixtures/validation/. - Docs [Brent]: Update
docs/development/testing.mdwith validation test catalog. - Tests (Behave) [Rui]: Add edge-case scenarios for concurrency, conflicts, and rollbacks.
- Tests (Robot) [Rui]: Add integration coverage for edge-case suites.
- Tests (ASV) [Rui]: Add
asv/benchmarks/validation_edge_bench.pyfor edge-case runtime. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Brent]:
git commit -m "test(validation): add edge case suites".
- Code [Brent]: Add shared edge-case fixtures under
- COMMIT (Owner: Luis | Group: 10C.semantic) - Commit message: "test(validation): add semantic validation suites" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Luis]: Add semantic validation fixtures and error-pattern samples.
- Docs [Luis]: Document semantic validation coverage expectations.
- Tests (Behave) [Rui]: Add semantic validation scenarios.
- Tests (Robot) [Rui]: Add semantic validation integration tests.
- Tests (ASV) [Rui]: Add
asv/benchmarks/semantic_validation_suite_bench.pyfor suite runtime. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Luis]:
git commit -m "test(validation): add semantic validation suites".
- COMMIT (Owner: Brent | Group: 10C.performance) - Commit message: "test(perf): add scale test fixtures" (Only check after all subitems +
noxpass + coverage >=97%, then commit)- Code [Brent]: Add scale fixtures for 1K/5K/10K file repos in
features/fixtures/scale/. - Docs [Brent]: Add scale test runbook and environment notes.
- Tests (Behave) [Rui]: Add scale test scenarios validating thresholds.
- Tests (Robot) [Rui]: Add large-project Robot tests for performance runs.
- Tests (ASV) [Rui]: Add
asv/benchmarks/scale_fixture_bench.pyfor baseline performance. - Quality [Brent]: Run
nox(all default sessions, including benchmark). - Quality [Brent]: Verify coverage >=97% via
nox -s coverage_report. - Commit [Brent]:
git commit -m "test(perf): add scale test fixtures".
- Code [Brent]: Add scale fixtures for 1K/5K/10K file repos in
Section 11: Security & Safety [WORKSTREAM F - Luis + Brent]
Target: Throughout project, critical items by Day 14
Note: With automated quality gates in place (Section 0), Brent only reviews security changes after automated scanning.
-
Stage SEC1: Remove eval() Vulnerability (Day 1-2) [Luis - CRITICAL] - [ ] Test with code containing unused imports - [ ] Commit: "feat(qa): add ruff linting to pre-commit"
- 0.1e [Brent] Add pyright type checking hook:
- repo: local hooks: - id: pyright name: Type check with pyright entry: pyright language: system types: [python] require_serial: true- Ensure pyright is installed via dev dependencies
- Test with code containing type errors
- Commit: "feat(qa): add pyright to pre-commit"
- 0.1f [Brent] Add security scanning with bandit:
- Add
bandit[toml]>=1.7.5to dev dependencies - Create
pyproject.tomlsection for bandit config:[tool.bandit] exclude_dirs = ["tests", "features", "benchmarks"] skips = ["B101"] # Skip assert_used test in test files - Add bandit hook:
- repo: https://github.com/PyCQA/bandit rev: '1.7.5' hooks: - id: bandit args: ['-c', 'pyproject.toml'] additional_dependencies: ["bandit[toml]"] - Commit: "feat(qa): add bandit security scanning"
- Add
- 0.1g [Brent] Add vulture for dead code detection:
- Add
vulture>=2.10to dev dependencies - Create
vulture_whitelist.pyfor false positives - Add vulture hook:
- repo: local hooks: - id: vulture name: Find dead code with vulture entry: vulture language: system types: [python] args: [--min-confidence, "80", "--exclude", "*/tests/*,*/features/*"] - Commit: "feat(qa): add vulture dead code detection"
- Add
- 0.1h [Brent] Add test runner hook for changed files:
- repo: local hooks: - id: pytest-changed name: Run tests for changed files entry: bash -c 'git diff --cached --name-only | grep -E "\.py$" | xargs -I {} pytest tests/{} 2>/dev/null || true' language: system pass_filenames: false always_run: true- Commit: "feat(qa): add test runner for changed files"
- 0.1i [Brent] Add semgrep for pattern-based checks:
- Install semgrep: Add
semgrep>=1.45.0to dev dependencies - Create
.semgrep.ymlwith initial rules:rules: - id: no-eval pattern: eval(...) message: "eval() is dangerous and banned" languages: [python] severity: ERROR - id: no-exec pattern: exec(...) message: "exec() is dangerous and banned" languages: [python] severity: ERROR - id: no-bare-except pattern: | try: ... except: ... message: "Use specific exception types" languages: [python] severity: WARNING - Add semgrep hook:
- repo: local hooks: - id: semgrep name: Scan with semgrep entry: semgrep --config=.semgrep.yml language: system types: [python] - Commit: "feat(qa): add semgrep pattern scanning"
- Install semgrep: Add
- 0.1j [Brent] Add commit message linting:
- repo: https://github.com/commitizen-tools/commitizen rev: v3.13.0 hooks: - id: commitizen stages: [commit-msg]- Configure conventional commits format
- Commit: "feat(qa): add commit message linting"
- 0.1k [Brent] Create developer setup script
scripts/setup-dev.sh:#!/bin/bash set -euo pipefail echo "Setting up pre-commit hooks..." pip install pre-commit pre-commit install pre-commit install --hook-type commit-msg echo "Running initial quality checks..." pre-commit run --all-files echo "Developer environment ready!"- Make executable:
chmod +x scripts/setup-dev.sh - Update README.md developer setup instructions
- Commit: "feat(qa): add developer setup script"
- Make executable:
Day 2: CI/CD Pipeline with GitHub Actions (or GitLab CI equivalent)
- 0.2 [Brent] Create GitHub Actions workflow for PR validation:
- 0.2a [Brent] Create
.github/workflows/pr-validation.yml:name: PR Validation on: pull_request: types: [opened, synchronize, reopened] jobs: quality-gates: name: Quality Gates runs-on: ubuntu-latest- Commit: "feat(ci): add PR validation workflow scaffold"
- 0.2b [Brent] Add Python setup and dependency caching:
steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # For proper git history - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.13' - name: Cache pip packages uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} restore-keys: | ${{ runner.os }}-pip-- Commit: "feat(ci): add Python setup with caching"
- 0.2c [Brent] Install dependencies and run formattin check:
- name: Install dependencies run: | pip install -e .[dev,tests] pip install pre-commit - name: Check code formatting run: | pre-commit run ruff-format --all-files --show-diff-on-failure- Commit: "feat(ci): add formatting check"
- 0.2d [Brent] Add linting step:
- name: Lint with Ruff run: | ruff check . --output-format=github- Use GitHub annotations format for inline PR comments
- Commit: "feat(ci): add linting with GitHub annotations"
- 0.2e [Brent] Add type checking step:
- name: Type check with pyright run: | pyright --outputjson > pyright-results.json || true python scripts/parse-pyright-results.py pyright-results.json- Create
scripts/parse-pyright-results.pyto format errors as GitHub annotations - Commit: "feat(ci): add type checking with annotations"
- Create
- 0.2f [Brent] Add security scanning:
- name: Security scan with bandit run: | bandit -r src/ -f json -o bandit-results.json || true python scripts/parse-bandit-results.py bandit-results.json - name: Check for vulnerabilities run: | pip install safety safety check --json > safety-results.json || true python scripts/parse-safety-results.py safety-results.json- Create parsing scripts for annotations
- Commit: "feat(ci): add security scanning"
- 0.2g [Brent] Add test execution with coverage:
- name: Run tests with coverage run: | nox -s unit_tests -- --junit-xml=test-results.xml nox -s coverage_report - name: Upload test results if: always() uses: actions/upload-artifact@v4 with: name: test-results path: test-results.xml - name: Comment coverage on PR uses: py-cov-action/python-coverage-comment-action@v3 with: GITHUB_TOKEN: ${{ github.token }} MINIMUM_GREEN: 85 MINIMUM_ORANGE: 70- Commit: "feat(ci): add test execution with coverage reporting"
- 0.2h [Brent] Add semgrep scanning:
- name: Semgrep scan uses: returntocorp/semgrep-action@v1 with: config: .semgrep.yml generateSarif: true - name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif- Commit: "feat(ci): add semgrep scanning with SARIF"
- 0.2i [Brent] Add PR comment summary:
- name: Generate quality report if: always() run: | python scripts/generate-quality-report.py \ --coverage coverage.xml \ --pyright pyright-results.json \ --bandit bandit-results.json \ --output pr-comment.md - name: Comment on PR if: always() uses: actions/github-script@v7 with: script: | const fs = require('fs'); const comment = fs.readFileSync('pr-comment.md', 'utf8'); github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment });- Create
scripts/generate-quality-report.pyto aggregate results - Commit: "feat(ci): add PR quality report comment"
- Create
- 0.2j [Brent] Add job failure conditions:
- name: Check quality gates run: | python scripts/check-quality-gates.py \ --coverage-min 85 \ --type-errors-max 0 \ --security-issues-max 0- Script exits with code 1 if any gate fails
- Commit: "feat(ci): add quality gate enforcement"
- 0.2k [Brent] Create branch protection rules documentation:
- Document in
docs/development/branch-protection.md:- Require PR validation workflow to pass
- Require at least 1 review (Brent reviews all)
- Dismiss stale reviews on new commits
- Require branches to be up to date before merging
- Commit: "docs(qa): add branch protection documentation"
- Document in
- 0.2a [Brent] Create
Day 3: Advanced Automation and Monitoring
- 0.3 [Brent] Set up advanced quality automation:
- 0.3a [Brent] Create nightly quality check workflow
.github/workflows/nightly-quality.yml:name: Nightly Quality Check on: schedule: - cron: '0 0 * * *' # Run at midnight UTC workflow_dispatch: # Allow manual trigger- Run full test suite including slow tests
- Run mutation testing with mutmut
- Generate comprehensive reports
- Commit: "feat(ci): add nightly quality checks"
- 0.3b [Brent] Add dependency update automation:
name: Dependency Updates on: schedule: - cron: '0 9 * * MON' # Weekly on Mondays jobs: update-deps: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Update dependencies run: | pip install pip-tools pip-compile --upgrade pip install .[dev,tests] pre-commit autoupdate - name: Create Pull Request uses: peter-evans/create-pull-request@v5 with: title: "chore: update dependencies" body: "Automated dependency updates" branch: deps/automated-update- Commit: "feat(ci): add dependency update automation"
- 0.3c [Brent] Create complexity monitoring:
- Install
radon>=6.0.1for complexity analysis - Add to pre-commit:
- repo: local hooks: - id: complexity-check name: Check code complexity entry: radon cc src/ -nb -s language: system pass_filenames: false - Add to CI pipeline with threshold enforcement
- Commit: "feat(qa): add complexity monitoring"
- Install
- 0.3d [Brent] Set up performance regression detection:
- Create
benchmarks/directory with ASV benchmarks - Add benchmark job to CI:
- name: Run benchmarks run: | asv machine --yes asv run HEAD^..HEAD asv compare HEAD^ HEAD - Fail if performance regresses >10%
- Commit: "feat(ci): add performance regression detection"
- Create
- 0.3e [Brent] Create quality metrics dashboard script:
- Script
scripts/generate-metrics-dashboard.py:- Aggregate coverage trends
- Track type checking progress
- Monitor code complexity trends
- Count TODO/FIXME/HACK comments
- Generate markdown report
- Run weekly and post to team
- Commit: "feat(qa): add quality metrics dashboard"
- Script
- 0.3f [Brent] Set up documentation quality checks:
- Add doc linting:
- repo: local hooks: - id: doc-quality name: Check documentation quality entry: python scripts/check-docstrings.py language: system types: [python] - Verify all public functions have docstrings
- Check docstring format (Google style)
- Commit: "feat(qa): add documentation quality checks"
- Add doc linting:
- 0.3g [Brent] Create ADR compliance checker:
- Script
scripts/check-adr-compliance.py:- Parse ADRs from
docs/architecture/decisions/ - Check code against ADR requirements
- Flag violations (e.g., sync code in async modules)
- Parse ADRs from
- Add to pre-commit and CI
- Commit: "feat(qa): add ADR compliance checking"
- Script
- 0.3h [Brent] Set up coverage delta checking:
- Modify CI to track coverage changes:
- name: Check coverage delta run: | git fetch origin main nox -s coverage_report -- --compare-branch=origin/main python scripts/check-coverage-delta.py --min-delta=-0.5 - Fail if coverage drops more than 0.5%
- Commit: "feat(ci): add coverage delta enforcement"
- Modify CI to track coverage changes:
- 0.3i [Brent] Create PR template with quality checklist:
- Create
.github/pull_request_template.md:## Description Brief description of changes ## Quality Checklist - [ ] Tests added/updated for new functionality - [ ] Type hints added for all new functions - [ ] Docstrings added/updated - [ ] No new linting warnings - [ ] Coverage maintained or increased - [ ] ADRs followed - [ ] Security implications considered ## Testing How has this been tested? - Commit: "feat(qa): add PR template with quality checklist"
- Create
- 0.3j [Brent] Document quality automation setup:
- Create
docs/development/quality-automation.md:- Pre-commit hook reference
- CI/CD pipeline overview
- How to run quality checks locally
- How to handle quality gate failures
- Exemption process (when needed)
- Add to developer onboarding
- Commit: "docs(qa): document quality automation"
- Create
- 0.3a [Brent] Create nightly quality check workflow
Post Day 3: Transition Plan
-
0.4 [Brent] Transition to selective manual review (Days 4-8):
- 0.4a [Brent] Focus manual reviews on:
- Architectural decisions
- Complex algorithms
- API contracts
- Security-sensitive code
- Skip reviewing: formatting, basic types, simple CRUD
- 0.4b [Brent] Create review priority matrix:
- P0: Security, API changes, architecture
- P1: Complex business logic, algorithms
- P2: Normal features
- P3: Tests, docs, refactoring (trust automation)
- 0.4a [Brent] Focus manual reviews on:
-
0.5 [Brent] Transition to high-impact work (After Day 8):
- 0.5a [Luis + Brent] Move to validation pipeline work:
- Help implement semantic validation in execution actors
- Create validation test suites
- Document validation patterns
- 0.5b [Luis + Brent] Assist with change tracking edge cases:
- Test tool-based change tracking thoroughly
- Find and fix edge cases
- Create comprehensive test scenarios
- 0.5a [Luis + Brent] Move to validation pipeline work:
- 0.1e [Brent] Add pyright type checking hook:
Section 11: Security & Safety [WORKSTREAM F - Luis + Brent]
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 insrc/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
- Search for
- 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
- Audit
- SEC1.4 [Brent] Code review all eval removal changes
- SEC1.1 [Luis] Audit all files for
- 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
- SEC1.5 [Rui] Write Behave scenarios in
- Code: Remove all eval() from config parsing
-
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
- SEC2.1 [Luis] Replace
- 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
- SEC2.4 [Rui] Write Behave scenarios in
- Code: Secure template rendering
-
Stage SEC3: Exception Handling Audit (Day 4-5) [Luis]
- Code: Stop swallowing exceptions (automated checks + manual fixes)
- SEC3.1 [Luis] Run automated exception handling audit:
- Use semgrep rules to find bare
except:orexcept Exception: - Use vulture to find unreachable exception handlers
- Document each occurrence for manual review
- Use semgrep rules to find bare
- SEC3.2 [Luis] 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 [Luis] Add error context propagation:
- Errors should include stack trace reference
- Errors should identify the component that failed
- Errors should suggest recovery actions where possible
- SEC3.4 [Brent] Review complex exception handling patterns only:
- Review async exception handling edge cases
- Validate error propagation across actor boundaries
- SEC3.1 [Luis] Run automated exception handling audit:
- Tests: Exception handling tests
- SEC3.5 [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
- SEC3.5 [Rui] Write Behave scenarios in
- Code: Stop swallowing exceptions (automated checks + manual fixes)
-
Stage SEC4: Async Lifecycle Correctness (Day 5-6) [Luis]
- Code: Fix async resource leaks (automated detection + fixes)
- SEC4.1 [Luis] Run automated async pattern detection:
- Use semgrep to find all
asyncio.new_event_loop()calls - Use custom linter to detect unclosed resources
- Generate report of potential resource leaks
- Use semgrep to find all
- SEC4.2 [Luis] Fix RxPy subscription leaks:
- Ensure subscriptions are disposed on shutdown
- Dispose subscriptions on stream reconfiguration
- Track active subscriptions for debugging
- SEC4.3 [Luis] Fix LangGraph checkpoint file leaks:
- Audit checkpoint file creation
- Implement cleanup for old checkpoint files
- Add retention policy for checkpoints
- SEC4.4 [Brent] Selective review of async patterns:
- Review only complex async state machines
- Validate concurrent access patterns
- SEC4.1 [Luis] Run automated async pattern detection:
- Tests: Resource leak tests
- SEC4.5 [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
- SEC4.5 [Rui] Write Behave scenarios in
- Code: Fix async resource leaks (automated detection + fixes)
-
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
- SEC5.1 [Hamza] Implement secrets masking in logs:
- 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
- SEC5.4 [Rui] Write Behave scenarios in
- Code: Secure credential handling
-
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: truemetadata - Block execution if write skill detected in read-only action
- Check if action has
- SEC6.2 [Luis] Implement safety profile validation (DEFERRED to post-30; see Stage POST1):
- Action can specify
safety_profilewith:allowed_skill_categories: list[str] | Nonedenied_skill_categories: list[str] | Nonerequire_checkpoints: boolrequire_sandbox: boolrequire_human_approval: bool(apply approval gate)max_cost_usd: float | Nonemax_retries: int
- Add action-create CLI flags to populate SafetyProfile:
--require-sandbox--require-checkpoints--require-apply-approval--allow-skill-category <category>(repeatable)--deny-skill-category <category>(repeatable)--max-cost-usd <amount>--max-retries <count>
- Enforce safety profile at execution time
- Action can specify
- SEC6.1 [Luis] Add skill metadata validation 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
- SEC6.3 [Rui] Write Behave scenarios in
- Code: Enforce read_only actions
-
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_logtable:- Schema:
audit_id,event_type,user_id,plan_id,details,created_at - Index on
event_type,plan_id,created_at
- Schema:
- SEC7.3 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] audit listCLI command:- List recent audit events
- Filter by event type, plan, date range
- SEC7.1 [Hamza] Implement apply audit logging:
- 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
- SEC7.4 [Rui] Write Behave scenarios in
- Code: Comprehensive audit trail
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
Sessionmodel insrc/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
- Field
- SESS1.2 [Hamza] Create
SessionServiceinsrc/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
- Method
- SESS1.3 [Hamza] Create Alembic migration for
sessionstable:- Schema matching Session model
- Index on
last_active_atfor 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 [--data-dir PATH] [--config-path PATH] session endcommand
- Store session ID in
- SESS1.5 [Hamza] Add session CLI commands:
agents [--data-dir PATH] [--config-path PATH] session start- create new session explicitlyagents [--data-dir PATH] [--config-path PATH] session end- end current sessionagents [--data-dir PATH] [--config-path PATH] session set automation-level <level>- set session automationagents [--data-dir PATH] [--config-path PATH] session info- show current session detailsagents [--data-dir PATH] [--config-path PATH] session tell "<prompt>" [--session <id|name>] [--actor <actor>]- send a prompt in the active session
- SESS1.1 [Hamza] Define
- 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
- Scenario:
agents [--data-dir PATH] [--config-path PATH] session tell "..."uses current session and actor
- SESS1.6 [Rui] Write Behave scenarios in
- Code: Implement stable session persistence
-
Stage SESS2: Memory Service Persistence (Day 9-10) [Hamza]
- Code: Fix memory loss between invocations
- SESS2.1 [Hamza] Update
MemoryServiceto 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_historytable:- Schema:
history_id,session_id,plan_id,role,content,created_at - Foreign key to sessions
- Index on
session_id,plan_id
- Schema:
- SESS2.3 [Hamza] Add explicit memory configuration:
CLEVERAGENTS_MEMORY_BACKEND=sqlite|redis|memory- Document that
memorybackend loses history between invocations - Default to
sqlitefor persistence
- SESS2.4 [Hamza] Surface warning if memory not persistent:
- On first CLI invocation, warn if memory backend is
memory - Suggest configuring persistent backend
- On first CLI invocation, warn if memory backend is
- SESS2.1 [Hamza] Update
- 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
- SESS2.5 [Rui] Write Behave scenarios in
- Code: Fix memory loss between invocations
-
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 [--data-dir PATH] [--config-path PATH] 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)
- PROV1.1 [Luis] Remove FakeListLLM as default behavior:
- 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
- PROV1.5 [Rui] Write Behave scenarios in
- Code: Fix provider issues
-
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
- PROV2.1 [Luis] Add token tracking per plan:
- 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
- PROV2.6 [Rui] Write Behave scenarios in
- Code: Implement cost controls and fallback
Section 13: Additional CLI Commands & UX [Days 10-14]
Commands missing from initial plan
-
Stage CLI0: Core System Commands (Day 10) [Hamza]
- Code: Implement core CLI metadata commands
- CLI0.1 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] version:- Print CLI version and build metadata
- Include config path and data dir in verbose output
- CLI0.2 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] info:- Show configuration summary (data dir, config path, providers, defaults)
- Show current session if present
- CLI0.3 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] diagnostics:- Run self-checks (config readable, DB reachable, write access)
- Print warnings for missing providers or invalid config
- CLI0.1 [Hamza] Implement
- Tests: Core CLI command tests
- CLI0.4 [Rui] Write Behave scenarios in
features/cli_core.feature:- Scenario: Version prints semantic version
- Scenario: Info prints config and data paths
- Scenario: Diagnostics reports missing providers
- CLI0.4 [Rui] Write Behave scenarios in
- Code: Implement core CLI metadata commands
-
Stage CLI1: Plan Interaction Commands (Day 10-11) [Hamza]
- Code: Implement additional plan commands
- CLI1.1 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] plan prompt <plan_id> "<guidance>":- Provide additional instructions to a stuck plan
- Works when plan is in errored state
- Resumes execution with new guidance
- CLI1.2 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] plan diff <plan_id>:- 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 [--data-dir PATH] [--config-path PATH] plan diff --correction <plan_id>:- Compare old vs new after correction
- Show what changed between correction attempts
- CLI1.4 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] plan artifacts <plan_id>:- List all artifacts produced by plan
- Show file paths, operation types, sizes
- CLI1.1 [Hamza] Implement
- 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
- CLI1.5 [Rui] Write Behave scenarios in
- Code: Implement additional plan commands
-
Stage CLI2: Configuration Commands (Day 11-12) [Hamza]
- Code: Implement config commands
- CLI2.1 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] config set <key> <value>:- Set global configuration values
- Supported keys:
automation-level,default-actor,log-level - Persist to
~/.cleveragents/config.toml
- CLI2.2 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] config get <key>:- Get current configuration value
- Show source (default, file, environment)
- CLI2.3 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] config list:- List all configuration values
- Show current value and source
- CLI2.4 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] providers list:- List available providers
- Show which are configured vs missing API keys
- CLI2.1 [Hamza] Implement
- 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
- CLI2.5 [Rui] Write Behave scenarios in
- Code: Implement config commands
-
Stage CLI3: Context Commands (Day 12-13) [Hamza]
- Code: Implement project/actor context policy commands
- CLI3.1 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project context set:- Flags:
--project <name>,--policy hot|warm|cold,--hot-max-tokens <int> --hot-max-tokensis a soft cap; allow null/omitted to disable- LLM hard context limit can override soft cap
- Flags:
- CLI3.2 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] project context show:- Display current policy and hot/warm/cold sizing
- CLI3.3 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] actor context set:- Reuse same arguments/behavior as project context set and legacy context commands
- CLI3.4 [Hamza] Implement
agents [--data-dir PATH] [--config-path PATH] actor context show:- Reuse same output format as project context show
- CLI3.1 [Hamza] Implement
- Tests: Context command tests
- CLI3.5 [Rui] Write Behave scenarios in
features/context_cli.feature:- Scenario: Project context set updates policy
- Scenario: Project context show displays hot/warm/cold tiers
- Scenario: Actor context set mirrors project context args
- Scenario: Actor context show displays policy summary
- CLI3.5 [Rui] Write Behave scenarios in
- Code: Implement project/actor context policy commands
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
- CONC1.1 [Luis] Implement plan-level locking:
- 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
- CONC1.4 [Rui] Write Behave scenarios in
- Code: Prevent concurrent plan modification
-
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 [--data-dir PATH] [--config-path PATH] plan resume <plan_id>:- 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"
- CONC2.1 [Luis] Persist step-level progress:
- 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
- CONC2.4 [Rui] Write Behave scenarios in
- Code: Implement plan resume capability
-
Stage CONC3: Garbage Collection (Day 13-14) [Hamza]
- Code: Cleanup abandoned resources
- CONC3.1 [Hamza] Implement sandbox garbage collection:
- On startup, find orphaned sandbox directories
- Clean sandboxes from crashed processes
- Add
agents [--data-dir PATH] [--config-path PATH] cleanup sandboxesCLI command
- CONC3.2 [Hamza] Implement checkpoint file cleanup:
- Track checkpoint files in database
- Retention policy (default: 7 days after plan completion)
- Add
agents [--data-dir PATH] [--config-path PATH] cleanup checkpointsCLI command
- CONC3.3 [Hamza] Implement session cleanup:
- Clean sessions with no activity for 30 days
- Clean associated conversation history
- CONC3.4 [Hamza] Add automatic cleanup on startup:
- Run cleanup for orphaned resources
- Log what was cleaned
- CONC3.5 [Brent] Review resource lifecycle patterns only:
- Validate cleanup doesn't affect active resources
- Review concurrent access during cleanup
- CONC3.1 [Hamza] Implement sandbox garbage collection:
- Tests: Cleanup tests
- CONC3.6 [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
- CONC3.6 [Rui] Write Behave scenarios in
- Code: Cleanup abandoned resources
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_donefield - Identify MUST, SHOULD, MAY requirements
- Generate validation checklist from DoD
- Parse action's
- 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)
- DOD1.1 [Luis] Parse DoD must/should/may structure:
- 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
- DOD1.4 [Rui] Write Behave scenarios in
- Code: Implement DoD validation
-
Stage DOD2: Invariant System (Day 14-15) [Luis]
- Code: Implement user-defined invariants
- DOD2.1 [Luis] Define
Invariantmodel:- 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
- Field
- DOD2.2 [Luis] Implement
agents [--data-dir PATH] [--config-path PATH] 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)
- DOD2.1 [Luis] Define
- 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
- DOD2.4 [Rui] Write Behave scenarios in
- Code: Implement user-defined invariants
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
IndexingServiceinsrc/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
- Method
- 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
- CTX1.1 [Hamza] Create
- 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
- CTX1.4 [Rui] Write Behave scenarios in
- Code: Implement repo indexing for large codebases
-
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
- Method
- CTX2.3 [Hamza] Make embedding index optional:
- Only build if
CLEVERAGENTS_ENABLE_EMBEDDINGS=true - Fall back to full-text search if not available
- Only build if
- CTX2.1 [Hamza] Integrate with VectorStoreService:
- 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
- CTX2.4 [Rui] Write Behave scenarios in
- Code: Optional embedding-based search
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
SkillRegistryinsrc/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]
- Method
- 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 [--data-dir PATH] [--config-path PATH] skills list:- List all registered skills
- Show capabilities (read_only, checkpointable, etc.)
- SKILL1.1 [Aditya] Create
- 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
- SKILL1.5 [Rui] Write Behave scenarios in
- Code: Implement skill registry for safety validation
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 connectivity (server is a separate project)
- 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 - Requires server connectivity (server is a separate project)
- 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)
- POST1: Safety Profile Enforcement (Post-30) - Deferred safety policy system
- Move
safety_profileinto Action model (from Stage A2 follow-up) - Define
SafetyProfilemodel with allow/deny skill categories and approval gates - Add action-create CLI flags for safety profile:
--require-sandbox--require-checkpoints--require-apply-approval--allow-skill-category <category>(repeatable)--deny-skill-category <category>(repeatable)--max-cost-usd <amount>--max-retries <count>
- Enforce safety profile during execution and apply
- Add Behave + Robot tests for safety profile enforcement
- Move
- Removed: Old 67-command structure - Replaced by new command structure
- Removed: Configuration migration utilities - CleverAgents is standalone
Timeline Summary
TEAM ROLES AND ASSIGNMENTS
| 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 |
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 [--data-dir PATH] [--config-path PATH] plan tree, agents [--data-dir PATH] [--config-path PATH] plan explain |
| 17 | D5.1-D5.8 Decision Correction | Jeff | agents [--data-dir PATH] [--config-path PATH] 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) - M6 Target (Large Project Autonomy - LOCAL MODE ONLY)
| 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 | Deep Subplan Hierarchies (5+ levels) | Jeff + Luis | Autonomous decomposition |
| 28-29 | F0.1-F0.5 Server Client Interface Stubs + Large Project Tests | Luis + Rui | Client stubs (NOT server impl), 10K file tests |
| 30 | M6 integration testing | All | Large project autonomy verified (Server connectivity DEFERRED) |
Note
: Server connectivity (F1-F4) is DEFERRED beyond Day 30. Days 26-29 focus on client stubs only and large project testing. The server is a separate project.
Week 5 (Days 31-35) - M7 Target (Server Connectivity - Client Side Only)
| Day | Focus | Owner | Deliverable |
|---|---|---|---|
| 31-32 | F1.1-F1.4 Server Client Infrastructure | Luis | HTTP client for server communication |
| 33 | F2.1-F2.6 Plan Sync Client | Luis | Client can sync plans to server |
| 34 | F3.1-F3.3 WebSocket Client | Luis | Client receives real-time updates |
| 35 | F4.1-F4.3 Remote Project Support | Hamza | Client can request server execution |
Week 6 (Days 36-40) - M8 Target (Full Feature Set + Polish)
| Day | Focus | Owner | Deliverable |
|---|---|---|---|
| 36 | Automation level refinement | Jeff + Luis | G1 automation enhancements |
| 37 | Cost estimation actors | Aditya | G5 estimation working |
| 38 | Error recovery mechanisms | Jeff | G2 checkpointing + rollback |
| 39 | Performance optimization | Luis + Jeff | Benchmarks passing |
| 40 | Final integration + documentation | All | Release candidate ready |
Continuous Tasks (Throughout)
Brent (Quality - Independent, Low Contention):
- Review all PRs within 4 hours of submission
- Run
nox -s typecheckon all branches before merge - Run
nox -s lintand ensure 0 warnings - Monitor test coverage (must stay >=97%)
- 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.core/B2.persistence/B2.service/B3.cli (Project/Resource) ─┐│
Day 3: B4.sandbox (Sandbox) ────────────────────────────────────────┼┤
Day 4: C1.schema/C2.compiler (Actor) ───────────────────────────────┘│
Day 5: C3.protocol/C4.file (Skills) ─────────────────────────────────┤
Day 6: C4.search/C5.model (Change Tracking) ─────────────────────────┤
Day 7: C6.pipeline/C7.mcp/C8.providers (Validation + Providers) ─────┘
│
Day 8-9: C9.execute/C9.apply (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: CTX/G + F0 (Context + Large Project + Stubs) ─┘
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)
- ✅ Code implemented with full type annotations
- ✅ Behave scenarios written and passing
- ✅ Robot integration tests (for CLI/E2E tasks) passing
- ✅
nox -s typecheckpasses with 0 errors - ✅
nox -s lintpasses with 0 warnings - ✅ Test coverage >=97%
- ✅ PR reviewed by Brent (or Jeff for critical items)
- ✅ Implementation notes added to this document
MILESTONE SUCCESS CRITERIA (DETAILED)
M1: MVP (Day 7) - Minimally Usable for Source Code
End-to-end verification command sequence:
# 1. Create an action
cat > /tmp/test_action.yaml <<EOF
name: local/test-action
description: MVP test action
strategy_actor: openai/gpt-4
execution_actor: openai/gpt-4
definition_of_done: "All files created successfully"
EOF
agents [--data-dir PATH] [--config-path PATH] action create --config /tmp/test_action.yaml
agents [--data-dir PATH] [--config-path PATH] action available local/test-action
# 2. Register a git resource (built-in git-checkout type)
agents [--data-dir PATH] [--config-path PATH] resource add git-checkout local/main-repo \
--path /path/to/repo \
--branch main # Optional; default is main per spec
# 3. Create project and link resource
agents [--data-dir PATH] [--config-path PATH] project create local/test-project
agents [--data-dir PATH] [--config-path PATH] project link-resource local/test-project local/main-repo
# Note: project link-resource is defined in Section 4 (B3.cli)
# 4. Use action to create plan
agents [--data-dir PATH] [--config-path PATH] plan use local/test-action local/test-project
# 5. Execute plan (sandbox created, changes made)
agents [--data-dir PATH] [--config-path PATH] plan execute <plan_id>
# 6. Review diff
agents [--data-dir PATH] [--config-path PATH] plan diff <plan_id>
# 7. Apply changes
agents [--data-dir PATH] [--config-path PATH] plan apply <plan_id>
# 8. Verify changes in repo
cd /path/to/repo && git log -1 # Shows CleverAgents commit
Technical Criteria:
- Plan and Action records persist to SQLite database
- Phase transitions (ACTION → STRATEGIZE → EXECUTE → APPLY → APPLIED) work correctly
- Git worktree sandbox creates isolated working directory
- Changes in sandbox do not affect original until Apply
- At least 3 automation levels work (manual mode minimum)
- Error handling produces actionable messages
- Test coverage remains >85%
M3: Full Plan Lifecycle with Actors (Day 14)
End-to-end verification:
# Create actor YAML file
cat > my_actor.yaml <<EOF
version: "3"
name: my_coder
namespace: local
type: llm
model: openai/gpt-4
temperature: 0.7
system_prompt: "You are a helpful coding assistant."
EOF
# Load actor
agents [--data-dir PATH] [--config-path PATH] actor add --file ./my_actor.yaml
# Create action using custom actor
cat > /tmp/custom_action.yaml <<EOF
name: local/custom-action
strategy_actor: local/my_coder
execution_actor: local/my_coder
definition_of_done: "Code written and tests pass"
EOF
agents [--data-dir PATH] [--config-path PATH] action create --config /tmp/custom_action.yaml --available
# Use and execute (should use custom actor)
agents [--data-dir PATH] [--config-path PATH] plan use local/custom-action local/test-project
agents [--data-dir PATH] [--config-path PATH] plan execute <plan_id>
# Verify multi-file generation
agents [--data-dir PATH] [--config-path PATH] plan artifacts <plan_id> # Should show multiple files
Technical Criteria:
- Actor YAML files parse and validate correctly
- Actors compile to LangGraph StateGraphs
- Inline skill code executes in sandboxed environment
- Built-in file skills (read/write/edit/delete) work
- ChangeSet built from skill invocations (not parsed from output)
- Validation pipeline runs (syntax check, lint, tests)
- Multi-file generation produces correct ChangeSet
- MCP skill adapter can connect to external servers (basic)
M4: Decision Tree & Correction (Day 21)
End-to-end verification:
# Execute a plan to generate decisions
agents [--data-dir PATH] [--config-path PATH] plan use local/complex-action local/large-project
agents [--data-dir PATH] [--config-path PATH] plan execute <plan_id>
# View decision tree
agents [--data-dir PATH] [--config-path PATH] plan tree <plan_id>
# Output shows:
# ├── [prompt_definition] "Build user authentication"
# │ ├── [strategy_choice] "Use JWT tokens" (confidence: 0.85)
# │ │ └── [subplan_spawn] "Create token service" → subplan_01ABC
# │ └── [implementation_choice] "Store tokens in Redis"
# Explain a decision
agents [--data-dir PATH] [--config-path PATH] plan explain <decision_id>
# Shows: question, chosen_option, alternatives, rationale, context
# Add and list project invariants
agents [--data-dir PATH] [--config-path PATH] invariant add --project local/large-project "Use session cookies"
agents [--data-dir PATH] [--config-path PATH] invariant list --project local/large-project
# Correct a decision (dry run first)
agents [--data-dir PATH] [--config-path PATH] plan correct <decision_id> --mode=revert --guidance "Use session cookies instead of JWT" --dry-run
# Shows impact: 3 decisions, 1 subplan affected
# Execute correction
agents [--data-dir PATH] [--config-path PATH] plan correct <decision_id> --mode=revert --guidance "Use session cookies instead of JWT"
# Re-executes from that point
# Verify new outcome
agents [--data-dir PATH] [--config-path PATH] plan tree <plan_id>
# Shows corrected decision and regenerated downstream work
Technical Criteria:
- Decisions recorded during Strategize with full context snapshot
- Decision tree persists to database
agents [--data-dir PATH] [--config-path PATH] plan treedisplays ASCII tree correctlyagents [--data-dir PATH] [--config-path PATH] plan explainshows all decision details- Correction in revert mode:
- Archives old decisions
- Rolls back sandbox to checkpoint
- Re-executes from decision point
- Generates new downstream decisions
- Correction in append mode creates fix subplan
- History preserved for comparison
M5: Subplans & Parallel Execution (Day 25)
End-to-end verification:
# Execute plan that spawns multiple subplans
agents [--data-dir PATH] [--config-path PATH] plan use local/refactor-action local/monorepo
agents [--data-dir PATH] [--config-path PATH] plan execute <plan_id>
# View subplan tree
agents [--data-dir PATH] [--config-path PATH] plan tree <plan_id>
# Shows:
# ├── [root] Refactor codebase
# │ ├── [subplan] Refactor auth module (status: COMPLETE)
# │ ├── [subplan] Refactor api module (status: PROCESSING)
# │ └── [subplan] Refactor utils module (status: QUEUED)
# Check status until complete
agents [--data-dir PATH] [--config-path PATH] plan status <plan_id>
# Verify merged results
agents [--data-dir PATH] [--config-path PATH] plan diff <plan_id> # Shows merged changes from all subplans
Technical Criteria:
- SUBPLAN_SPAWN decisions created during Strategize
- Subplans actually spawned during Execute
- Sequential subplan execution works (one at a time)
- Parallel subplan execution works (with max_parallel limit)
- Each subplan has isolated sandbox
- Three-way merge combines non-conflicting changes
- Merge conflicts detected and marked
- Parent plan tracks all subplan statuses
- A plan with 10+ subplans completes successfully
M6: Large Project Handling (Day 30)
End-to-end verification:
# Index a large project (10,000+ files)
agents [--data-dir PATH] [--config-path PATH] project create local/large-project
agents [--data-dir PATH] [--config-path PATH] resource add git-checkout local/large-repo \
--path /path/to/large/repo \
--branch main # Optional; default is main per spec
agents [--data-dir PATH] [--config-path PATH] project link-resource local/large-project local/large-repo
# Note: project link-resource is defined in Section 4 (B3.cli)
# Verify indexing handles scale
agents [--data-dir PATH] [--config-path PATH] project show local/large-project
# Shows: 15,247 files indexed, 2.3M tokens
# Execute complex hierarchical task
cat > /tmp/port_action.yaml <<EOF
name: local/port-to-typescript
strategy_actor: local/architect
execution_actor: local/coder
definition_of_done: "All Python files converted to TypeScript with tests"
EOF
agents [--data-dir PATH] [--config-path PATH] action create --config /tmp/port_action.yaml --available
agents [--data-dir PATH] [--config-path PATH] plan use local/port-to-typescript local/large-project
agents [--data-dir PATH] [--config-path PATH] plan execute <plan_id>
# Monitor hierarchical decomposition
agents [--data-dir PATH] [--config-path PATH] plan tree <plan_id>
# Shows multi-level hierarchy:
# ├── Root: Port codebase to TypeScript
# │ ├── Phase 1: Core modules (3 subplans)
# │ │ ├── Port auth module (5 subplans)
# │ │ │ ├── Convert auth types
# │ │ │ ├── Convert auth handlers
# │ │ │ └── ...
# │ ├── Phase 2: API layer (4 subplans)
# │ └── Phase 3: Integration tests (2 subplans)
# Correct mid-level decision if needed
agents [--data-dir PATH] [--config-path PATH] plan correct <module_decision_id> --mode=revert --guidance "Use Zod instead of io-ts for validation"
# Only affected module and its subplans recompute
# Complete and apply
agents [--data-dir PATH] [--config-path PATH] plan status <plan_id>
agents [--data-dir PATH] [--config-path PATH] plan apply <plan_id>
Technical Criteria:
- Projects with 10,000+ files index without timeout
- Context window management works (hot/warm/cold tiers)
- Hierarchical decomposition creates 4+ levels of subplans
- Decision correction at any level recomputes only affected subtree
- Parallel execution scales to 10+ concurrent subplans
- Memory usage stays bounded (lazy context loading)
- A realistic porting task (500 file Python → TypeScript) completes autonomously
QUICK REFERENCE: TASK DEPENDENCIES
LEGEND:
───► = Sequential dependency (must complete before next)
═══► = Parallel tracks that can proceed simultaneously
⊕ = Merge point (all parallel tracks must complete)
WEEK 1 CRITICAL PATH:
DAY 1-2: DATA LAYER
┌─────────────────────────────────────────────────────────────────┐
│ [Jeff] A5.alpha DB migrations ═══► [Luis] A5.beta ORM models │
│ │ │ │
│ └───────────⊕───────────────┘ │
│ │ │
│ [Jeff] A5.gamma Repos + Service + DI │
│ │ │
│ [Rui] A5.tests Persistence suites │
└─────────────────────────────────────────────────────────────────┘
DAY 1-3: RESOURCE LAYER (PARALLEL)
┌─────────────────────────────────────────────────────────────────┐
│ [Hamza] B1.core Domain Models │
│ │ │
│ ▼ │
│ [Hamza] B2.persistence + B2.service + B3.cli │
└─────────────────────────────────────────────────────────────────┘
DAY 3-5: SANDBOX LAYER
┌─────────────────────────────────────────────────────────────────┐
│ [Luis] B4.sandbox strategy + manager ═══► [Hamza] git_worktree │
│ │ │ │
│ └───────────⊕───────────────┘ │
│ │ │
│ [Luis] B4.sandbox copy_on_write stub │
└─────────────────────────────────────────────────────────────────┘
DAY 4-7: ACTOR/SKILL LAYER
┌─────────────────────────────────────────────────────────────────┐
│ [Aditya] C1.schema/C1.examples Actor Schema │
│ │ │
│ ▼ │
│ [Aditya+Jeff] C2.loader/C2.compiler Actor Compiler │
│ │ │
│ [Jeff] C3.protocol/C3.context/C3.inline ═══► [Aditya] C7.mcp │
└─────────────────────────────────────────────────────────────────┘
DAY 6-9: CHANGE TRACKING LAYER
┌─────────────────────────────────────────────────────────────────┐
│ [Luis] C5.model/C5.router Change Model + Router │
│ │ │
│ ▼ │
│ [Luis] C5.diff + C6.pipeline Validation Pipeline │
└─────────────────────────────────────────────────────────────────┘
DAY 8: M1 MERGE POINT ⊕
┌─────────────────────────────────────────────────────────────────┐
│ All tracks converge: │
│ - Plan lifecycle (A) + Resources (B) + Actors (C) + Skills │
│ - End-to-end verification of MVP criteria │
│ - All tests must pass │
└─────────────────────────────────────────────────────────────────┘
WEEK 2: INTEGRATION + DECISIONS
┌─────────────────────────────────────────────────────────────────┐
│ [Jeff+Luis] C9 Plan-Actor Integration │
│ │ │
│ ▼ │
│ [Hamza] D1.domain/D2.service/D3.cli Decisions │
│ │ │
│ ▼ │
│ [Luis] E1 Subplan Model │
└─────────────────────────────────────────────────────────────────┘
DAY 14: M3 MERGE POINT ⊕
┌─────────────────────────────────────────────────────────────────┐
│ Full plan lifecycle with actors verified │
│ Multi-file generation working │
│ Validation pipeline operational │
└─────────────────────────────────────────────────────────────────┘
WEEK 3: DECISION CORRECTION + SUBPLANS
┌─────────────────────────────────────────────────────────────────┐
│ [Jeff] D4.revert/D4.append Decision Correction ─┐ │
│ │ │
│ [Jeff+Luis] E2/E3/E4 Subplan Spawning + Merging ┤ │
│ │ │
│ [Hamza] D5.db/D5.repo Decision Persistence ────┘ │
└─────────────────────────────────────────────────────────────────┘
DAY 21: M4 MERGE POINT ⊕
┌─────────────────────────────────────────────────────────────────┐
│ Decision tree viewing and correction working │
│ Can correct any decision and recompute affected work │
└─────────────────────────────────────────────────────────────────┘
WEEK 4: SCALE + SERVER PREP
┌─────────────────────────────────────────────────────────────────┐
│ [Hamza] CTX1.index Context indexing │
│ [Luis] G3.semantic validation + perf tuning │
│ [Jeff] F0.stubs server connectivity (client-only) │
└─────────────────────────────────────────────────────────────────┘
DAY 30: M6 TARGET ⊕
┌─────────────────────────────────────────────────────────────────┐
│ Handle 10,000+ file projects │
│ Autonomous language porting with hierarchical subplans │
│ Decision correction enables efficient iteration │
└─────────────────────────────────────────────────────────────────┘
SERVER CONNECTIVITY DEFERRAL NOTICE
Server connectivity (WORKSTREAM F) is deferred beyond the 30-day timeline. The server is a separate project—this implementation covers the client only.
The CleverAgents executable (agents) is purely a client application that can:
- Run in stand-alone local-only mode (no server required)
- Connect to an independently developed CleverAgents server for multi-user/collaborative features
During Days 1-30, the following client stub infrastructure should be created:
- Server client connection command (
agents [--data-dir PATH] [--config-path PATH] connect <server_url>- stub) - Abstract interfaces for client-to-server communication
- Resource abstraction that can detect local vs remote resources
- Placeholder client methods that return "Server connectivity not yet implemented"
What is NOT needed by Day 30:
- Server implementation (the server is a separate project)
- Full client-server API implementation
- WebSocket client implementation
- Remote plan execution requests
- Authentication flow with server
- Permission system integration
The client code should be structured so that adding server connectivity later is straightforward, but no functional server communication code is required for the 30-day milestone. The server will be developed as a separate project.