Add ExecutionEnvironment enum (host/container) to domain models, implement
execution environment resolution with priority chain (tool > plan > project
> default), wire the tool runner to check execution_environment before
execution, and add CLI flags to plan use/execute and project context set.
When container is selected but no container resource is available, a clear
ContainerUnavailableError is raised with an actionable message.
Closes#512
- Update event_bus_steps.py to call record_decision() with individual
parameters (plan_id, decision_type, question, chosen_option, rationale)
instead of passing a Decision object, matching the master branch API
- Remove ctx.test_decision construction from DecisionService setup steps
as it is no longer needed with the new signature
- Update robot/helper_event_bus.py decision_service_emits_event() to use
the new record_decision() parameter signature
- All 9 Robot Framework event bus tests passing
- Behave scenarios at lines 125 and 131 now passing
Fixes event bus test failures after master merge.
- Fix CHANGELOG EventType count from 40 to 38 and add missing domains
(invariant, context) for accurate documentation
- Document correlation_id field as spec extension for request traceability
in DomainEvent model
- Add thread safety documentation to ReactiveEventBus and LoggingEventBus
noting single-threaded design and external sync requirements
- Document _persist_audit deferral in ReactiveEventBus.emit() explaining
audit logging via handler subscription or LoggingEventBus following
single-responsibility principle
- Replace bare MagicMock() with create_autospec(Settings, instance=True)
at 5 locations for type-safe test mocking
- Replace nested bare MagicMock for UnitOfWork with create_autospec at 3
locations to prevent silent breakage on API changes
All changes maintain backward compatibility. No linter errors.
- Fix rationale test to assert goal text appears in rationale rather than
only checking non-empty (P1-1)
- Align side_effects value to specification: use ["spawn_subplan"] instead
of ["emit_decision"] per docs/specification.md §18259 (P2-1)
- Remove dead TYPE_CHECKING import guard that contained only pass (P2-2)
- Replace frozenset with tuple for _VALID_CONTEXT_VIEWS to ensure
deterministic JSON schema enum ordering and eliminate CI noise (P2-3)
- Simplify validation error message and schema unpacking now that
context_view values are in a pre-sorted tuple
Behave steps, benchmarks, vulture whitelist, and docs referenced
renamed methods (get_decisions_for_plan, get_decision_tree). Updated
to use the actual API names (list_decisions, get_tree) and the kwargs
record_decision signature.
ISSUES CLOSED: #172
- Remove global _PLAN_ID; generate per-step plan IDs on context (#8)
- Fix sham orphan test; build children_map from all decisions (#1)
- Delete dead constants; use _PATCH_RESUME_SVC_MOD in resume steps (#2)
- Remove dead _resolve_active_plan_id mock from _invoke_correct (#5)
- Make --mode/--guidance required Typer options (#3)
- Show alternatives by default; remove --show-alternatives flag (#4)
- Strengthen weak assertions on depth-limit and show-superseded (#6)
- Add negative assertions for error type conflation (#7)
ISSUES CLOSED: #174
Cover CLI-level code paths for plan explain, tree, correct, resume,
revert, and read-only guards that were unreached by existing unit tests.
Raises plan.py diff-coverage from 69% to 99.7% (1 line remaining).
- Add justification to type: ignore comments in build_decision_tree
- Remove Any from step file signatures, use object instead
- Strengthen non-existent decision test to verify ID exclusion
- Fix O(n²×d) depth computation in table view with dict lookup
- Fix orphan root detection in rich-view to match BFS logic
- Add type annotations to Robot helper dispatch dict
- Deduplicate import json in explain_decision_cmd
ISSUES CLOSED: #174
Add `plan explain` and `plan tree` CLI commands that format decision
trees in json/yaml/table/rich formats. Flags control views for
superseded decisions, context snapshots, and reasoning details.
- plan explain <decision_id>: renders a single decision with optional
--show-context, --show-reasoning, --show-alternatives flags
- plan tree <plan_id>: renders full decision tree with optional
--show-superseded and --depth flags
- BFS tree building uses collections.deque (no list.pop(0))
- Behave BDD scenarios (14 scenarios, 54 steps)
- Robot Framework smoke tests with helper script
- ASV benchmarks for explain formatting and tree operations
- Updated docs/reference/plan_cli.md and CHANGELOG.md
ISSUES CLOSED: #174
Wire all AcpLocalFacade operation handlers to their corresponding
application services via constructor-injected service dependencies:
- session.create/close delegate to SessionService
- plan.create/execute/status/diff/apply delegate to PlanLifecycleService
- registry.list_tools delegates to ToolRegistry
- registry.list_resources delegates to ResourceRegistryService
- event.subscribe delegates to AcpEventQueue
- context.get returns stub pending ACMS ContextAssemblyPipeline
Add domain-to-ACP error code mapping via map_domain_error() translating
ResourceNotFoundError to NOT_FOUND, ValidationError to VALIDATION_ERROR,
PlanError to PLAN_ERROR, BusinessRuleViolation to INVALID_STATE, and
other domain exceptions to their corresponding ACP error codes.
Handlers gracefully fall back to stub responses when services are absent.
Includes 21 Behave scenarios (features/acp_facade_wiring.feature) and
9 Robot Framework integration tests (robot/acp_facade_wiring.robot).
Updated docs/reference/acp.md with wired operation details, service
key table, and error code taxonomy.
ISSUES CLOSED: #501
Implemented SkeletonCompressorService for ACMS context inheritance, producing
compressed context representations for propagation from parent plans to child
plans. Key design decisions and implementation details:
- SkeletonMetadata (frozen Pydantic model): records ratio, original_tokens,
compressed_tokens, and source_decision_ids for full auditability of each
compression pass. Persisted on Plan.skeleton_metadata.
- SkeletonCompressorService: stateless service accepting a list of
ContextFragment objects and a skeleton_ratio in [0.0, 1.0]. Fragments are
sorted by relevance descending with a stable secondary sort on fragment_id
to guarantee deterministic output. Token budget is original_tokens*(1-ratio);
fragments are greedily selected until budget is exhausted.
- Ratio semantics: 0.0 = no compression (pass-through), 1.0 = maximum
compression (single top fragment only), None = default 0.3.
- Integration: Plan model gains optional skeleton_metadata field exposed in
as_cli_dict() under the 'skeleton' key. Service registered in DI container
as skeleton_compressor_service (Singleton, stateless).
- Tests: 22 BDD scenarios (features/skeleton_compressor.feature) covering
ratio validation, stable ordering, metadata correctness, edge cases, and
plan model integration. 6 Robot Framework smoke tests. ASV benchmark suites
at 10/100/1000 fragment scales.
- Documentation: docs/reference/skeleton_compressor.md with ratio table,
algorithm description, metadata schema, and multi-decision plan example.
ISSUES CLOSED: #194
Implemented the Backend Abstraction Layer (BAL) for the Advanced Context
Management System, following the specification in docs/specification.md
Section ACMS > Backend Abstraction Layer and ADR-014.
Key additions:
- TextBackend protocol with search(query, scope, max_results) returning
list[TextResult], and TextResult frozen dataclass (uko_uri, content,
score, metadata fields)
- VectorBackend protocol with similarity_search(embedding, scope, top_k)
returning list[VectorResult], and VectorResult frozen dataclass
- GraphBackend protocol with sparql_query(query, scope),
get_triples(subject), and traverse(start, depth) methods returning
GraphResult frozen dataclass (triples, metadata fields)
- In-memory stub backends (InMemoryTextBackend, InMemoryVectorBackend,
InMemoryGraphBackend) that validate arguments and return empty results,
serving as development placeholders and test doubles
- DI container registration as configurable Singletons with provider
selection via override_providers()
- Behave BDD feature (35 scenarios / 83 steps) covering protocol
compliance, argument validation, result immutability, and DI resolution
- Robot Framework smoke tests (6 tests) for integration verification
- ASV benchmarks for stub query overhead and instantiation time
- Reference documentation at docs/reference/acms_backends.md
Design decisions:
- Used @runtime_checkable Protocol for structural subtyping, consistent
with existing ResourceHandler pattern
- Used frozen dataclasses (not Pydantic) for result types to minimize
overhead in the hot path of context assembly
- scope parameter typed as frozenset[str] for immutability and hashability
- Stubs registered as default Singletons; production backends swap via DI
ISSUES CLOSED: #498
Added three new built-in resource types: container-instance,
devcontainer-instance, and devcontainer-file. The devcontainer-instance
type inherits from container-instance per ADR-042 and is auto-discovered
when git-checkout or fs-directory resources contain .devcontainer/
directories per ADR-043.
Implementation includes:
- DevcontainerHandler extending BaseResourceHandler with snapshot strategy
- Auto-discovery module scanning .devcontainer/devcontainer.json and
root .devcontainer.json with JSON validation
- CLI support for devcontainer-instance and container-instance via
agents resource add with --path and --image flags
- Behave feature with 22 scenarios covering manual registration,
auto-discovery, invalid JSON handling, and protocol conformance
- Robot integration tests with 10 test cases for CLI round-trip and
DAG hierarchy validation
- ASV benchmarks measuring discovery throughput with varying subdirectory
counts, handler resolver cache performance, and result construction
- Reference documentation at docs/reference/devcontainer_resources.md
ISSUES CLOSED: #511
Add SafetyProfile domain model with configurable safety constraints
(checkpoint, human approval, cost limits, retry limits, skill
categories, sandbox requirement). Integrate into Action model with
from_config/as_cli_dict support, and persist via LifecycleActionModel
safety_profile_json column.
Include resolve_safety_profile() stub that raises NotImplementedError
for local mode, signalling that real enforcement is deferred.
Add comprehensive test coverage:
- 20 BDD scenarios in features/safety_profile.feature
- 6 Robot Framework smoke tests
- 5 ASV benchmark suites (11 timing functions)
Add docs/reference/safety_profile.md reference documentation.
ISSUES CLOSED: #332
Add --project flag to config set, config get, and config list CLI
commands, enabling per-project configuration overrides stored under
[project."<name>"] TOML tables in the global config file.
Project-scoped resolution slots between environment variable and global
levels in the ConfigService resolution chain. config list --project
shows only overrides for the named project with source annotations.
Implementation:
- ConfigService: add set_project_value() and get_project_overrides()
methods for TOML-backed project-scoped persistence and retrieval
- CLI config commands: wire --project flag through set, get, and list
subcommands; project-scoped list filters to overrides only
- Database persistence: project-scoped config stored as alternative
backend for projects not using TOML
- Documentation: update docs/reference/config_resolution.md with
project-scopable key lists, CLI examples, precedence diagram, and
non-scopable key rejection behavior
Tests:
- Behave: 12 BDD scenarios in features/config_project_scope.feature
covering set/get/list, precedence over global defaults, and
non-scopable key rejection
- Robot: 5 integration smoke tests in robot/config_project_scope.robot
for end-to-end project-scoped round-trip verification
- ASV: benchmarks/config_project_scope_bench.py measuring resolution
overhead with project scope active
All nox quality gates pass: lint, typecheck, unit_tests (7522 scenarios),
integration_tests (Config Project Scope suite passed), and coverage at
98% line rate (threshold 97%).
Closes#259
Consolidate 141 BDD feature files that each complete in under 0.1 seconds
into 25 domain-grouped feature files, reducing subprocess count from 339
to ~223. Each consolidated file groups scenarios from the same domain/module
that share step definitions and fixtures. All scenarios are preserved with
clear comment headers indicating their original source file.
This reduces subprocess overhead by ~116 invocations (141 original files
replaced by 25 consolidated files), targeting the 42% of subprocess count
that contributed only 0.2% of actual test runtime.
ISSUES CLOSED: #485
Add protocol stubs for remote server communication infrastructure:
- ServerClient: Health check and version negotiation protocol
- RemoteExecutionClient: Remote plan execution and status protocol
- AuthClient: Authentication and token management protocol
- StubServerClient/StubRemoteExecutionClient/StubAuthClient: Stub
implementations raising NotImplementedError for all methods
- ServerConnectionConfig: Validated config model (server_url, namespace,
auth_token_ref, tls_verify)
- Config keys: core.server_url, core.server_namespace, core.server_tls_verify
- CLI: agents connect <url> stub command with explicit warning
- CLI: agents info shows Server Mode (disabled/stubbed)
ISSUES CLOSED: #201
Add SubplanService for building child plans from DecisionService spawn
entries and SubplanConfig. The service validates resource scopes, merge
strategies, and max_parallel bounds before spawning.
Key additions:
- SubplanService: Orchestrates child plan creation from spawn entries
- SpawnMetadata: Persisted metadata (spawn_decision_id, parent/root
plan IDs, execution mode) for status output
- Spawn validation: Checks resource scopes, merge strategy, and
parallelism bounds before spawning
- Documentation: subplan_service.md with spawn workflow and lifecycle
ISSUES CLOSED: #197
- Return parent_decision_id in handler result dict and add meaningful
assertion to the corresponding Behave scenario (B1)
- Add ULID format validators to SubplanPayload for plan_id, dependencies,
and parent_decision_id, consistent with Decision model validation (S1)
- Add non-empty string validator for resource_scopes items (S2)
- Narrow broad except Exception to except (ValidationError, ValueError)
so programming errors surface as real failures (S3)
- Document strategy_with_subplan.yaml in actors_examples.md and assert
it is referenced in the "Verify all examples are documented" scenario (B2)
ISSUES CLOSED: #198
Cap time.sleep and asyncio.sleep globally at 10ms in before_all to
eliminate retry/backoff waits (tenacity wait_fixed, retry_auto_debug
exponential backoff). Save originals as time._original_sleep and
asyncio._original_sleep for tests that need real wall-clock delays
(CircuitBreaker recovery, debounce timers, validation timeouts).
Enhance template-DB patch: add "db." prefix to _SCENARIO_DB_PREFIXES
and check db_path.stat().st_size > 0 so 0-byte auto-created SQLite
files receive the template copy instead of falling through to real
migrations.
Replace subprocess.run CLI invocations with typer.testing.CliRunner
in module_coverage, main_coverage_complete, and coverage_extras step
files, eliminating ~6s Python cold-start overhead per call.
Switch plan_persistence and action_persistence to in-memory SQLite by
default; only cross-restart scenarios use file-based via an explicit
Given step.
Replace MigrationRunner.run_migrations with Base.metadata.create_all
in plan_service_steps for freshly created in-memory engines.
Removed leftover debug comment in environment.py.
Total tier runtime: 565s -> 21s (96% reduction), 20 features all
under 5s behave-internal time.
ISSUES CLOSED: #480
Optimized the 8 features accounting for 64% of total BDD test runtime
(1,505s of 2,352s):
- features/environment.py: Added _ensure_template_db() for direct behave
invocations, expanded _SCENARIO_DB_PREFIXES to include "test_" for
step-file-created DBs, added @mock_only tag support to skip
unnecessary DB setup.
- features/plan_commands_coverage.feature: Added @mock_only tag (fully
mocked, no DB needed).
- features/plan_service.feature: 14 actor-resolution scenarios now use
lightweight in-memory plan service instead of heavyweight file-based
DB + project init.
- features/steps/plan_service_steps.py: New
step_create_lightweight_plan_service for actor-resolution tests.
- features/steps/services_coverage_steps.py: Extracted 3 helper functions
to consolidate 8 near-identical Given steps (~200 lines of duplicated
boilerplate removed).
Per-feature results: services_coverage 245s->2.8s (99%), context_service
215s->2.1s (99%), project_service 140s->0.7s (99%), plan_service
215s->4.6s (98%), core_cli_commands 113s->4.2s (96%), cli_streaming
213s->6.4s (97%), plan_commands_coverage 116s->20s (83%),
cli_plan_context_commands 248s->31.6s (87%).
ISSUES CLOSED: #479
Created scripts/create_template_db.py that builds a pre-migrated SQLite
template database using Base.metadata.create_all() + alembic stamp
(~5ms for 34 tables, vs ~0.5-3s x 25 Alembic migrations per scenario).
Nox unit_tests and coverage_report sessions generate the template before
test execution and propagate CLEVERAGENTS_TEMPLATE_DB env var to all
workers.
features/environment.py before_all() installs a monkey-patch on
MigrationRunner.init_or_upgrade that copies the template for fresh
scenario temp DBs, falling through to real migrations for :memory:,
existing files, and migration-runner unit tests.
Quick wins: sleep(0.5) -> sleep(0.05) in cli_streaming wait step;
removed redundant Background re-declaration in cli_streaming.feature
scenario 7.
ISSUES CLOSED: #483
Implement SubplanExecutionService and SubplanMergeService to enable
parent plans to decompose work into coordinated child subplans with
configurable execution modes (sequential, parallel, dependency-ordered)
and merge strategies (git_three_way, sequential_apply, fail_on_conflict,
last_wins).
- SubplanExecutionService: schedules subplan execution with retry
support via SubplanFailureHandler, max_parallel limits, fail_fast
semantics, and topological DAG ordering for dependency mode
- SubplanMergeService: wraps sandbox merge infrastructure to combine
subplan sandbox outputs using the configured merge strategy
- BDD tests: 21 scenarios covering all execution modes, merge
strategies, validation, and integration flows
- Robot tests: 11 integration test cases with helper module
- ASV benchmarks: performance benchmarks for execution and merge
- Documentation: reference guide in docs/reference/subplans.md
ISSUES CLOSED: #184
Implement the complete configuration system with multi-level resolution
chain, typed key registry, and CLI integration per specification.
ConfigService changes:
- Expand _build_catalog() to register all 102 spec-aligned config keys
across 8 groups: core (14), server (4), actor (5), plan (8),
sandbox (5), index (12), context (43), provider (11)
- Each key carries exact dotted-dash name, Python type, default value,
explicit env var name per spec, project-scopability flag, and
description
- Fix _env_name() to convert dots and dashes to underscores
- Provider keys use standard env var names (e.g., OPENAI_API_KEY)
CLI commands rewiring:
- Rewrite config set/get/list to use ConfigService instead of Settings
- Add --verbose flag to config get showing full 5-level resolution chain
- Add --project flag to config set/get/list for project-scoped overrides
- Support both glob and regex patterns in config list
- Validate keys against ConfigService registry with actionable errors
- Retain backward-compatible helper functions delegating to ConfigService
Documentation:
- Add docs/reference/config_resolution.md covering resolution chain,
all 102 config keys, CLI commands, TOML format, and provider credentials
Testing:
- Update all 4 Behave feature files and step definitions to use new
spec-aligned key names, env vars, and defaults (119 scenarios passing)
- Add robot/config_resolution.robot with 10 integration test cases
- Add benchmarks/config_resolution_bench.py with 8 time + 2 memory suites
ISSUES CLOSED: #258
Added targeted Behave BDD feature files and step definitions to improve
unit test coverage for:
- decision_service.py: Full coverage of all 7 service methods (18 scenarios)
- plan_apply_service.py: Branch coverage for handle_merge_failure (2 scenarios)
- plan_executor.py: Edge cases for rollback, checkpoint, and parse_steps (15 scenarios)
- cli/commands/plan.py: Uncovered region lines 1950-2273 (23 scenarios)
- repositories.py: Remaining missed branches and lines (14 scenarios)
- sandbox/checkpoint.py: Full coverage of CheckpointManager (26 scenarios)
- langgraph/bridge.py: Remaining uncovered lines and branches (10 scenarios)
- cli/commands/config.py: Safety net to maintain 100% coverage (42 scenarios)
Total: 150 new scenarios, 596 steps, all passing.
Also fixed a step definition collision in plan_lifecycle_coverage by renaming
"the delete result should be false" to "the plan delete result should be false".
ISSUES CLOSED: #475
Add runtime autonomy constraints (max steps, tool budget, required
confirmations) and a structured audit trail for plan execution.
New domain models:
- AutonomyGuardrails: enforces step limits, tool budgets, and
confirmation gates with validators and check methods
- GuardrailAuditEntry: records each enforcement event with timestamp,
event type, guard name, result, reason, and context
- GuardrailAuditTrail: ordered collection of audit entries persisted
to plan metadata
New service:
- AutonomyGuardrailService: high-level service for configuring
guardrails per plan, checking constraints, recording audit entries,
and serializing/restoring state via plan metadata
Tests:
- Behave: 69 scenarios covering model validation, step/budget/
confirmation checks, audit trail recording, and service operations
- Robot: 8 test cases for autonomy guardrail CLI flag smoke testing
- ASV: 6 benchmark suites measuring enforcement overhead
Documentation:
- Updated docs/reference/automation_profiles.md with guardrail fields,
enforcement behavior, audit trail schema, and event type reference
ISSUES CLOSED: #204
Implemented namespace/project/plan/skill permission model with role
bindings (owner/admin/editor/viewer) and default deny policy. Added
enforcement hooks at CLI/service boundaries that are server-only; local
mode returns permissive defaults. Includes role enums, permission check
service, role matrix documentation.
Includes Behave BDD scenarios, Robot integration tests, ASV benchmarks,
and reference documentation.
ISSUES CLOSED: #344
Patch time.monotonic alongside time.sleep in the retry timeout step
so stop_after_delay cannot elapse due to wall-clock overhead on
busy CI runners. The fake monotonic clock advances by 1µs per call,
keeping elapsed time well under the 0.01s timeout while preserving
retry semantics.
Closes#200
Revert module-level import refactor and instead patch at
cleveragents.application.container.get_container — matching the
established pattern used by all existing context CLI tests.
Lazy imports inside each function re-read from the source module,
so patching there intercepts correctly.
Closes#200