Commit Graph

331 Commits

Author SHA1 Message Date
freemo 583e6b7ea2 feat(correcting-plans): implement Predictive Error Prevention (Layer 4) with Error Pattern Database
Implement spec-mandated Layer 4 Predictive Error Prevention system:

- ErrorPattern domain model with pattern text, historical failures,
  preventive checks, frequency tracking, and keyword-based matching.
- ErrorPatternRepository with in-memory CRUD + context-matching query.
- ErrorPatternService with record_failure(), match_patterns(), and
  get_statistics() methods.
- Wire into plan execution via plan_lifecycle_service pre-execution hook.
- Add error pattern statistics to CLI diagnostics output.

Behave BDD: 11 scenarios covering recording, matching, formatting, stats.
Robot Framework: 3 integration smoke tests.
ASV benchmarks: pattern matching performance.

ISSUES CLOSED: #571
2026-03-08 21:53:21 -04:00
freemo 61fc70d84b fix(cli): pass decision tree and influence edges to CorrectionService in plan correct handler (#639)
## Summary

Fixes the `plan correct` CLI handler which never passes the decision tree or influence edges to `CorrectionService`, producing single-node impact analysis regardless of the plan's actual decision structure.

Closes #606

## Root Cause

The `correct_decision()` handler in `plan.py` created a bare `CorrectionService()` and called `analyze_impact()` and `execute_correction()` without passing `decision_tree` or `influence_edges`. Both parameters default to `None` -> empty dicts, causing `_compute_affected_subtree()` BFS to return only the single target decision, ignoring all descendants and influence-DAG dependents.

## Changes

### Production Fix (`src/cleveragents/cli/commands/plan.py`)
- Resolve `DecisionService` via `get_container()` (following the pattern used by `plan explain` and `plan tree`)
- Build structural tree adjacency list from `decision_svc.list_decisions(plan_id)` using `parent_decision_id` relationships
- Fetch influence edges from `decision_svc.get_influence_edges(plan_id)`
- Pass both `decision_tree` and `influence_edges` to `svc.analyze_impact()` and `svc.execute_correction()`

### Existing Test Fixups
- Updated 4 step definition files that mock `CorrectionService` to also mock the new `DecisionService` resolution path

### New Tests
- **Behave BDD**: 3 scenarios verifying tree/edge forwarding (dry-run subtree, execution subtree, leaf node)
- **Robot Framework**: 3 integration smoke tests
- **ASV Benchmark**: Tree building and analyze_impact overhead benchmarks

## Quality Gates

- `nox -s lint` — PASSED
- `nox -s typecheck` — 0 errors
- `nox -s unit_tests` — 9,109 scenarios, 0 failures
- `nox -s coverage_report` — 97%

ISSUES CLOSED: #606

Reviewed-on: cleveragents/cleveragents-core#639
Co-authored-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-committed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
2026-03-08 23:28:05 +00:00
freemo a44082ab70 feat(guardrails): implement Plan Generation Pre-flight Guardrails (7 checks before execution)
Implement spec-mandated pre-flight guardrail checks that validate plan
readiness before entering the Strategize phase:

1. Action schema validation — verifies action exists and is well-formed.
2. Actor availability — confirms all 4 actor roles registered.
3. Skill/tool existence — transitively resolves all tools/skills.
4. Automation policy — verifies profile permits execution.
5. Rollback feasibility — ensures all tools checkpointable if required.
6. Resource accessibility — shallow connectivity check on linked resources.
7. Validation attachment resolution — pre-resolves all applicable validations.

PlanPreflightGuardrail service runs all 7 checks via run_all_checks().
On first failure, raises PreflightRejection with check name and message.
Wired into plan_lifecycle_service before Strategize phase.

Behave BDD: 18 scenarios covering all 7 checks (positive + negative).
Robot Framework: 3 integration smoke tests.
ASV benchmarks: pre-flight check execution time.

ISSUES CLOSED: #582
2026-03-08 22:31:40 +00:00
freemo 7b1020e735 feat(security): implement Prompt Injection Mitigation (5 mechanisms)
Implement spec-mandated prompt injection protections:

1. Input sanitization (PromptSanitizer.sanitize_user_input): escapes HTML
   entities, strips C0/C1 control characters, rejects 8 known injection
   patterns including instruction override, role assumption, ChatML tags,
   and boundary marker spoofing.

2. Prompt boundary markers (PromptSanitizer.wrap_user_content): wraps user
   content with [USER_CONTENT_START]/[USER_CONTENT_END] markers;
   augment_system_prompt() prepends boundary recognition instructions.

3. Output validation: existing schema_validator.py validates tool I/O
   against JSON Schema in ToolRuntime.execute() (verified, tested).

4. Tool capability restrictions: existing _enforce_capabilities() in
   lifecycle.py enforces read_only/writes/checkpointable/side_effects
   declarations (verified, tested).

5. Unsafe tool gating: existing _enforce_capabilities() blocks unsafe
   tools unless allow_unsafe_tools=true in automation profile (verified,
   tested).

Integrates sanitizer into session prompt construction, invariant text
processing, and action argument handling paths.

ISSUES CLOSED: #572
2026-03-08 22:19:40 +00:00
freemo d3cc7d30d7 fix(tool): persist tool registration to database after add
ToolRegistryRepository.create(), .update(), and .delete() called
session.flush() but never session.commit().  The CLI factory creates a
raw sessionmaker without a UnitOfWork wrapper, so the transaction was
never committed and SQLAlchemy performed an implicit rollback when the
session was garbage-collected.

The same bug existed in ValidationAttachmentRepository.attach() and
.detach().

Changes:
- Add session.commit() after session.flush() in all five mutating
  methods across ToolRegistryRepository and
  ValidationAttachmentRepository.
- Add finally: session.close() to guarantee session cleanup regardless
  of success or failure.
- Update class docstrings to reflect the new commit-on-write semantics.
- Add Behave BDD feature (tool_add_persist.feature) with scenarios for
  single-tool round-trip, multi-tool persistence, and duplicate
  rejection, using file-based SQLite to reproduce the cross-session
  issue.
- Add Robot Framework integration test (tool_add_persist.robot) with
  add-then-list and fresh-list-empty scenarios.
- Add ASV benchmark (tool_add_persist_bench.py) with
  track_list_after_add_count metric.

Key decisions:
- File-based SQLite (not in-memory) is used in tests because the bug
  only manifests when the session/engine is fully disposed between add
  and list, simulating separate CLI invocations.
- Step patterns are prefixed with "tool-persist" to avoid AmbiguousStep
  collisions with existing tool_registry_steps.py.
- The commit-in-repository approach was chosen over adding a UnitOfWork
  to the CLI factory because the CLI commands are simple CRUD operations
  that should auto-persist without requiring callers to remember to
  commit.

ISSUES CLOSED: #621
2026-03-08 22:11:49 +00:00
freemo 9704281bdd fix(skill): persist skill registration to database after add
Wire SkillService to use SkillRepository for database persistence,
fixing the bug where `agents skill add` stored skills only in an
in-memory OrderedDict that was lost when the CLI process exited.

Changes:
- SkillService now accepts optional skill_repo and session_factory
  parameters.  When provided, add_skill() persists to the database
  and the constructor pre-loads existing skills from DB rows.
- _get_skill_service() in the CLI now creates a DB-backed service
  following the same engine/sessionmaker/repository pattern used by
  the tool CLI (tool.py).
- _reset_skill_service() now installs a fresh in-memory SkillService
  (instead of setting None) to avoid DB side-effects during unit
  testing with parallel runners.
- remove_skill() also persists the deletion to the database.

Test coverage:
- Behave BDD: features/skill_add_persist.feature (4 scenarios)
- Robot Framework: robot/skill_add_persist.robot (3 smoke tests)
- ASV benchmark: benchmarks/skill_add_persist_bench.py

ISSUES CLOSED: #620
2026-03-08 02:57:44 +00:00
freemo 64cfdc782a fix(resource): call bootstrap_builtin_types during initialization
Add a call to bootstrap_builtin_types() in init_command() (project.py)
immediately after initialize_project() returns.  This seeds the built-in
resource types (fs-directory, git-checkout, etc.) into the database so
that "resource add" commands succeed without "Resource type not found"
errors.

The call is idempotent — invoking it multiple times will not create
duplicate types.

Also fix the TDD robot test (resource_type_bootstrap_git.robot) to
initialize a project before running "resource add", and fix a
pre-existing parallel test failure in plan_commands_new_coverage where
unittest.mock.patch could not reliably intercept PlanApplyService under
behave-parallel fork() workers.

ISSUES CLOSED: #523, #524
2026-03-07 19:36:09 +00:00
freemo f6d27de1cd feat(extensibility): implement pluggable scope chain resolution
Introduce ComponentResolver with a deterministic 3-level scope chain
(plan > project > global) for resolving pluggable Protocol-based
components. The resolver supports caching, thread-safety, config.toml
extension loading, plan metadata loading, introspection APIs, and
security-restricted dynamic imports.

Includes 39 BDD scenarios, 9 Robot Framework integration tests,
ASV benchmarks, and vulture whitelist updates. 100% code coverage
on component_resolver.py; overall coverage at 97.07%.

ISSUES CLOSED: #552
2026-03-07 11:49:14 -05:00
freemo 620adfee01 fix(cli): add --yes flag to agents init for non-interactive setup
Added --yes/-y flag to the agents init CLI command to support non-interactive
initialization as specified in the documentation. When --yes is passed, all
interactive prompts are skipped and default values are applied. The command
produces the expected initialization summary output including data directory,
config file, database, and created directories.

The flag was added to both the top-level "agents init" command in main.py and
the "agents project init" subcommand in project.py. Both delegate to the shared
init_command() function which now accepts a yes parameter and produces
spec-aligned Rich panel output (Data Dir, Config, Database, Directories) with
the "Initialized (non-interactive)" status message when yes=True. When
yes=False (default), existing interactive behavior is preserved unchanged.

ISSUES CLOSED: #522
2026-03-07 15:07:17 +00:00
freemo 4221582368 feat(acms): implement pipeline Phase 3 components
Implemented the remaining ACMS pipeline components and advanced context
strategies:

Pipeline Phase 3:
- FragmentOrdererProtocol + RelevanceCoherenceOrderer: orders fragments
  by relevance while maintaining narrative coherence via UKO node prefix
  grouping.  Groups related fragments together, sorts groups by max
  relevance, and within groups orders by relevance desc / depth asc.
- PreambleGeneratorProtocol + ProvenancePreambleGenerator: generates
  provenance preamble with strategy contributions (fragment counts and
  token percentages), confidence indicators (avg/min/max), tier and
  depth distribution, UKO node coverage, and coverage gap detection.

Advanced Strategies:
- ArceStrategy (quality 0.95): adaptive recursive context expansion with
  iterative multi-backend refinement and configurable iteration limit
  (default 5) to prevent unbounded refinement.  Uses composite scoring
  (relevance + depth + diversity) with contextual boosting for fragments
  related to the current top-ranked anchor set.
- TemporalArchaeologyStrategy (quality 0.5): historical context retrieval
  from graph+cold backends.  Prioritises cold-tier fragments using a
  temporal scoring model (tier bonus + relevance + depth).
- PlanDecisionContextStrategy (quality 0.7): decision history retrieval
  from warm/cold backends.  Prioritises warm then cold tier fragments
  for correction and retry scenarios.

All strategies registered in strategy registry with correct quality scores
and backend requirements.  All components implement their respective
Protocol interfaces and can be injected into the ContextAssemblyPipeline
via constructor dependency injection.

Tests:
- 33 BDD scenarios in features/acms_pipeline_phase3.feature
- Robot Framework integration tests in robot/acms_pipeline_phase3.robot
- ASV performance benchmarks in benchmarks/acms_pipeline_phase3_bench.py

ISSUES CLOSED: #545
2026-03-07 14:53:18 +00:00
hamza.khyari 44fae392d7 fix(acms): address self-review findings F1-F4 on PR #617
F1 [P1]: Split Turtle validation (125 lines) from ontology_registry.py
into _turtle_validation.py. Registry is now 412 lines (was 514).

F2 [P2]: Deduplicate DetailLevelMap presets — depth_breadth_projection.py
code_detail_map/docs_detail_map/database_detail_map/infra_detail_map now
delegate to ontology_registry.get_domain() instead of hardcoding level
dicts. Removes 112 lines of duplicated data.

F3 [P2]: Add __all__ to ontology_registry.py (18 exports, ruff-sorted).

F4 [P3]: Remove unused import logging / logger from ontology_registry.py.

Refs: #574
2026-03-06 23:26:35 +00:00
hamza.khyari 04f24b39c0 feat(acms): implement UKO Layer 1 Domain Ontologies (uko-code, uko-doc, uko-data, uko-infra)
Implement the four Layer 1 domain-specific OWL/Turtle ontology vocabularies
that specialize Layer 0 universal concepts for specific knowledge domains.

Ontology (docs/ontology/uko.ttl):
- Added uko-doc: namespace with 17 classes (Document, Part, Chapter, Section,
  Subsection, Paragraph, Sentence, CodeBlock, Citation, Figure, Table,
  Footnote, Annotation, Bookmark, CrossReference, PageBreak, SectionBreak),
  5 properties, and 4 relationships
- Added uko-data: namespace with 13 classes (Schema, Table, Column, View,
  StoredProcedure, Constraint, Index, ForeignKey, Trigger, Annotation,
  Bookmark, PartitionBoundary, ShardBoundary), 6 properties, and
  5 relationships
- Added uko-infra: namespace with 7 classes (Service, Network, Endpoint,
  ConfigKey, Volume, FirewallRule, SubnetBoundary) and 2 relationships
- All classes use rdfs:subClassOf from Layer 0 base classes

Domain registry (ontology_registry.py):
- DomainDescriptor dataclass with namespace IRI, prefix, layer, classes,
  superclass mappings, and DetailLevelMap
- Registry functions: get_domain(), list_domains(), get_layer1_domains()
- DetailLevelMap chain builder for hierarchical depth resolution
- Turtle validation with TurtleValidationError (no rdflib dependency)
- All DetailLevelMap data inlined to maintain DIP compliance (domain
  layer does not import from application layer)

DetailLevelMap presets (depth_breadth_projection.py):
- code_detail_map: 10 spec-complete levels (depths 0-9)
- docs_detail_map: 11 spec-complete levels (depths 0-10)
- database_detail_map: 12 spec-complete levels (depths 0-11)
- infra_detail_map: 9 spec-complete levels (depths 0-8)

Tests:
- 31 BDD scenarios in uko_ontology_registry.feature covering domain
  lookup, all DetailLevelMap levels, inheritance chains, Turtle
  validation, Universal View Guarantee, and negative/edge cases
- 6 Robot Framework integration tests
- Updated existing tests: depth_breadth_projection.feature (TABLE_LISTING
  depth 0->1, added SCHEMA_LISTING), uko_ontology.feature (Layer 1
  node count 8->67)

Spec reference: docs/specification.md §41830-42332

ISSUES CLOSED: #574
2026-03-06 23:14:30 +00:00
hamza.khyari 13618fb8d5 fix(acms): address PR #611 review findings F1-F7
- F1/F2 [P1]: Split postgresql_analyzer.py (695→310 lines) by
  extracting regex patterns, URI builders, and parsing functions
  into _postgresql_helpers.py (440 lines).  Split
  domain_analyzers.feature (605→217 lines) into separate
  postgresql_analyzer.feature (201) and
  docker_compose_analyzer.feature (199).

- F3 [P1]: Fix _extract_body and _split_entries to track
  single-quoted SQL string literals so parentheses inside
  DEFAULT/CHECK values (e.g. 'func(x)') do not corrupt depth
  counting.  Added regression scenarios.

- F4 [P2]: Remove prohibited `# type: ignore[arg-type]` by
  adding a static protocol assertion for _DuplicatePyAnalyzer.

- F5 [P2]: Add 1 MiB size guard before yaml.safe_load in
  DockerComposeAnalyzer to mitigate billion-laughs alias
  expansion attacks.

- F6 [P2]: Fix quoted-keyword column names (e.g. "primary")
  being silently dropped by checking raw_first.startswith('"')
  before keyword filtering.  Added regression scenario.

- F7 [P2]: Out-of-scope file changes resolved by rebase onto
  master (changes already merged via other PRs).

All nox gates pass: lint (0 errors), typecheck (0 errors),
security_scan, behave (57 scenarios, 211 steps, 0 failures).
2026-03-06 20:07:03 +00:00
hamza.khyari 77db78d768 feat(acms): add PostgreSQL and Docker Compose domain analyzers (#588)
Add Phase 2 domain-specific analyzers for the ACMS UKO indexing pipeline:

- PostgreSQLAnalyzer: regex-based DDL parser extracting uko-data:Table,
  Column, ForeignKey, View, and Schema triples with column metadata
  (data type, nullability, primary key constraints).
- DockerComposeAnalyzer: YAML-based parser extracting uko-infra:
  DeploymentUnit, Service, Port, EnvironmentVariable, and connectsTo
  triples. Validates Compose format via services/version key detection.

Both satisfy AnalyzerProtocol and register in AnalyzerRegistry by file
extension (.sql/.ddl and .yml/.yaml respectively).

Includes 34 Behave BDD scenarios (protocol conformance, registry ops,
triple extraction for all 4 analyzers, error handling, cross-analyzer
URI scheme and confidence checks), 6 Robot Framework integration smoke
tests, updated __init__.py exports, vulture whitelist, and CHANGELOG.
2026-03-06 19:56:21 +00:00
CoreRasurae 23803f14ec feat(lsp): add LSP server stub
Added minimal LSP server entrypoint supporting initialize/shutdown/exit
handshake over JSON-RPC stdin/stdout transport with Content-Length
framing. Unsupported methods return MethodNotFound error with descriptive
message. Wired LSP requests through ACP facade in local mode. Added
agents lsp serve CLI command with --log-level flag, PID output, and
startup banner. Created reference documentation for the stub server.
Includes Behave BDD tests for protocol handshake, Robot smoke test, and
ASV startup latency benchmark.

ISSUES CLOSED: #203
2026-03-06 18:16:47 +00:00
aditya 3d2b138379 Merge branch 'master' into feature/m6plus-event-bus 2026-03-06 12:44:37 +00:00
hamza.khyari b028c80cab feat(acms): add scoped backend view filtering
Add project-resource isolation to the ACMS context tier system via
ScopedBackendView, ResourceScope, alias resolution, DAG expansion,
and enforcement hooks.

Core types (scoped_view.py): ResourceScope, ScopeViolationError,
ScopedBackendView, ScopedBackendSet, create_scoped_backend_set.

Scope resolution (scope_resolution.py): ResourceAliasResolver,
validate_project_scope, validate_resource_scope, resolve_resource_scope
with registry_lookup callback for DAG expansion.

Tier integration (scoped_tiers.py): ScopedTierMixin with get_scoped,
get_scoped_by_resource, validate_fragment_scope, store_with_scope_check,
get_scoped_metrics mixed into ContextTierService.

Backward compat: tiers.py re-exports ScopedBackendView.

Tests: 74 Behave scenarios (235 steps), 8 Robot Framework cases,
7 ASV benchmark suites. Lint and typecheck clean.

ISSUES CLOSED: #193
2026-03-06 00:49:33 +00:00
hamza.khyari b7effcafc1 fix(acms): address PR #565 review findings from CoreRasurae
Resolve 14 review findings across bugs, spec deviations, design gaps,
security, performance, thread safety, and test quality:

- Fix register() guard ordering: isinstance check before attribute access
- Add BackendSet.temporal field for cold-tier backend availability
- Fix temporal-archaeology/plan-decision-context can_handle to require
  temporal backend (spec §43193-43199)
- Add threading.RLock to StrategyRegistry for thread safety
- Add allowed_module_prefixes (CWE-706) to register_from_module
- Change StrategyConfig.extra and ContextStrategyResult.stats to
  MappingProxyType with field_validator coercion (ADR-004 immutability)
- Switch 6 stub capabilities from @property to @functools.cached_property
- Add resource_types/extra params to update_config()
- Add inject_stale_enabled_entry() public test helper
- Rename colliding step patterns to avoid AmbiguousStep with master
- Add scenarios: non-protocol without name, concurrent threads,
  temporal backend regression tests
- Document spec §25223 vs §28682 conflict and colon vs dot notation
2026-03-05 22:00:15 +00:00
khyari hamza 1521c4ae8c feat(acms): add context strategy registry
Implement the ACMS context strategy registry per spec §25162-25233,
§28682-28708, §42628-42653, and §43167-43199.

- Define ContextStrategy protocol, StrategyCapabilities, BackendSet,
  PlanContext, StrategyConfig, ContextStrategyResult models
- Add 6 built-in stub strategies (simple-keyword, semantic-embedding,
  breadth-depth-navigator, arce, temporal-archaeology,
  plan-decision-context) with spec quality scores and feature flags
- Add StrategyRegistry with register, register_from_module (plugin
  discovery), enable/disable, per-strategy config, and validation
- Add ContextStrategyResult with deterministic fragment ordering
  (-relevance_score, uko_node)
- Add configuration-driven enabled list with per-project overrides
- Add per-strategy timeout, max-fragment, circuit-breaker config
- Add registry validation for resource types and backend capabilities
- Fix update_config to sync _enabled_order when toggling enabled flag
- Fix register_from_module to honour the name parameter as registry key
- Fix update_config to re-run Pydantic validators via model_validate
- Add docs/reference/context_strategies.md
- Add 55 BDD scenarios (Behave), 4 Robot integration tests,
  ASV benchmarks

ISSUES CLOSED: #191
2026-03-05 22:00:15 +00:00
freemo fae438a7a7 refactor(acms): unify ContextFragment model hierarchies by extending CRP base types
Core domain types (FragmentProvenance, ContextFragment, ContextBudget,
ContextPayload) now extend their CRP counterparts via Pydantic v2
inheritance, ensuring isinstance compatibility across the model
hierarchy.

Key changes:
- CRP base types made frozen=True (no consumer mutates them)
- CRP AssembledContext fields changed from list to tuple (frozen consistency)
- Core types extend CRP bases: FragmentProvenance(CRPFragmentProvenance),
  ContextFragment(CRPContextFragment), ContextBudget(CRPContextBudget),
  ContextPayload(CRPAssembledContext)
- Removed duplicate ContextFragment dataclass from skeleton_compressor
- Updated project_context.py to pass tuples to frozen AssembledContext
- Added Behave tests (10 scenarios), Robot integration tests (3 cases),
  and ASV benchmarks for the unified hierarchy
- Updated Known Limitations table in docs/reference/acms.md

ISSUES CLOSED: #569
2026-03-05 21:38:55 +00:00
freemo d990fc1b41 feat(uko): add analyzer plugin framework and initial domain analyzers
Implemented the analyzer plugin framework with AnalyzerProtocol,
AnalyzerRegistry for registration/discovery by file extension,
PythonAnalyzer (AST-based extraction of modules, classes, functions,
imports, docstrings), and MarkdownAnalyzer (section, code block, and
link extraction). Both analyzers produce well-formed UKO triples with
proper URI schemes.

ISSUES CLOSED: #551
2026-03-05 19:20:39 +00:00
freemo 1d15eca866 feat(acms): implement depth/breadth projection system
Add the Depth/Breadth Projection System and Skeleton Context
Propagation as specified in docs/specification.md §25265-25340
and §43057-43128:

- ProjectionSpec: frozen Pydantic model capturing a projection
  request (focus, breadth, depth, gradient, domain)
- ProjectedNode: frozen model for materialized graph nodes with
  resolved depth and distance
- DepthBreadthProjector: stateless BFS projector over UKO graph
  adjacency with depth gradient (linear reduction by distance)
- PlanContextInheritance: service computing child plan context
  from parent assembled context with skeleton injection
- ChildContextResult: frozen result model with request and skeleton
- InheritanceConfig: frozen config for skeleton_ratio (default 0.2)
- Built-in DetailLevelMap presets for code, docs, and database

Includes 27 Behave BDD scenarios, 9 Robot Framework integration
tests, and ASV benchmarks for all components.

ISSUES CLOSED: #544
2026-03-05 15:42:20 +00:00
freemo fe7381c45b feat(acms): implement pipeline Phase 2 components
Add production-grade Phase 2 (Fragment Fusion) components for the ACMS
context assembly pipeline, replacing the no-op defaults:

- ContentHashDeduplicator: Groups fragments by UKO node URI, hashes
  content to detect duplicates, retains highest relevance_score.
- MaxDepthResolver: Resolves depth conflicts by keeping the highest
  detail depth per UKO node, with relevance tiebreaking.
- WeightedCompositeScorer: Computes composite score from configurable
  weighted factors (relevance=0.4, hierarchy=0.3, quality=0.2,
  recency=0.1). Stores component breakdown in metadata.
- GreedyKnapsackPacker: Greedy knapsack selection with depth fallback
  (tries depths [9,4,2,0] for oversized fragments) and minimum
  fragment token threshold (10).

Also adds:
- ScoredFragment frozen Pydantic model (spec §42825) with
  composite_score, score_components, and fragment reference
- score_detailed() method on WeightedCompositeScorer returning
  ScoredFragment objects for callers needing full breakdowns
- All components implement v1 Protocol signatures from acms_service.py
  and can be DI-injected into ACMSPipeline constructor

Testing:
- 31 Behave BDD scenarios in acms_pipeline_phase2.feature covering
  deduplication, depth resolution, scoring, packing, depth fallback,
  budget constraints, pipeline integration, and ScoredFragment model
- 6 Robot Framework integration smoke tests
- ASV benchmark suites for all 4 components and ScoredFragment

Quality gates: lint, typecheck (0 errors), unit_tests (8555 scenarios),
coverage (97.0%), dead_code — all passing.

ISSUES CLOSED: #540
2026-03-05 10:27:36 -05:00
freemo 34f9a587cf feat(acms): implement pipeline orchestrator and Phase 1 components
Add production-quality Phase 1 pipeline components for the ACMS
Context Assembly Pipeline:

- ConfidenceWeightedSelector: strategy selection with preference
  boosting and confidence-based ranking
- ProportionalBudgetAllocator: proportional token budget distribution
  with min_useful_budget enforcement and largest-remainder rounding
- ParallelStrategyExecutor: concurrent strategy execution via
  ThreadPoolExecutor with per-strategy timeouts and circuit breaking
- CircuitBreaker: per-strategy failure tracking with configurable
  threshold and explicit reset
- ContextAssemblyPipeline: extends ACMSPipeline with Phase 1
  production components and per-stage timing (StageTimings)

Includes 28 Behave BDD scenarios, 9 Robot Framework integration tests,
and ASV benchmarks for all components.

ISSUES CLOSED: #539
2026-03-05 15:13:19 +00:00
freemo 10abf8985e feat(acms): add ContextFragment and ScoredFragment data models
Created ScoredFragment frozen model wrapping ContextFragment with
composite_score, score_breakdown, and rank fields. Added pipeline-
specific fragment models in domain/contexts/ with proper equality
based on uko_uri + detail_depth for deduplication support.

ISSUES CLOSED: #538
2026-03-05 14:11:23 +00:00
freemo 487e16a9f0 feat(acms): implement context strategies batch 1
Implement the first three built-in context strategies for the ACMS v1
context assembly pipeline:

1. SimpleKeywordStrategy (quality 0.3) - Keyword matching on fragment
   content with word-density fallback. Universal fallback strategy.
2. SemanticEmbeddingStrategy (quality 0.6) - Jaccard word-overlap
   similarity scoring between query and fragment content.
3. BreadthDepthNavigatorStrategy (quality 0.85) - UKO node hierarchy
   navigation prioritising fragments near focus nodes with higher
   detail depths. Primary strategy for code projects.

All strategies implement the v1 ContextStrategy Protocol from
acms_service.py and can be registered with ACMSPipeline via
register_strategy().

Includes:
- 28 Behave BDD scenarios covering ranking, budget, capabilities,
  can_handle confidence, explain, empty input, and pipeline
  registration
- 9 Robot Framework integration tests
- ASV benchmarks at 10/100/1000 fragment scales for all 3 strategies
- Vulture whitelist entries for public API symbols
- 100% coverage on context_strategies.py

ISSUES CLOSED: #541
2026-03-05 12:58:57 +00:00
aditya 7ab5d8661a Merge branch 'master' into feature/m5-subplan-actor 2026-03-05 06:35:45 +00:00
khyari hamza febea8950f feat(acms): add ACMS v1 context pipeline
Implement the 10-component pluggable ACMS context assembly pipeline
with three built-in strategies (relevance, recency, tiered), DI-based
component injection, ULID-validated plan_id, largest-remainder budget
allocation, and frozen Pydantic v2 domain models.

Closes #188
2026-03-05 01:28:50 +00:00
CoreRasurae 837ff4217b feat(async): add async command execution and workers
- Add AsyncJob domain model with status state machine and Pydantic validation
- Add AsyncWorker service with configurable concurrency and job store
- Add CancellationToken, WorkerHealthReport, InMemoryJobStore
- Add AsyncJobModel SQLAlchemy model and Alembic migration (m6_003)
- Add 5 async config keys to Settings (worker_id, concurrency, poll_interval, max_retries, timeout)
- Add _check_async_worker_health diagnostic check in system.py
- Add comprehensive Behave BDD tests (~60 scenarios) with full step definitions
- Add Robot Framework integration tests (6 smoke tests)
- Add ASV benchmark suite for async execution
- Add architecture documentation
- Update vulture_whitelist with new public API symbols
- All quality gates pass: lint, typecheck, unit_tests, integration_tests, coverage_report (97%)

1. Wire async job creation into PlanLifecycleService:
   - Add optional job_store parameter to __init__
   - Add _maybe_enqueue_async_job() helper that checks settings.async_enabled
     and job store presence before creating and enqueuing an AsyncJob
   - Call helper from execute_plan() (phase="execute") and apply_plan()
     (phase="apply") after phase transitions
   - When async is disabled or no job store is configured, behaviour is
     unchanged (silent no-op)

2. Redact secrets in failed job error messages:
   - Apply shared.redaction.redact_value() to the error string before
     persisting to AsyncJob.error_message, preventing accidental secret
     leakage (e.g. API keys in exception text) into the audit trail

Documentation:
- S1: Added specification reconciliation note (ADR-style) to
  async_architecture.md addressing tension between "No Plan Queuing"
  clause and the async subsystem authorised by issue #312

ISSUES CLOSED: #312
2026-03-04 23:47:20 +00:00
khyari hamza ad53a659de feat(uko): add UKO ontology scaffolding
Add UKO Layer 0-3 ontology skeleton (RDF/TTL) with base URI, version IRI,
and prefix conventions. Python loaders handle URI parsing, inheritance
resolution, versioning metadata, and validation of undefined prefixes and
missing rdf:type. Includes Behave BDD scenarios, Robot Framework integration
tests, ASV benchmarks, and reference documentation.

- Resolve rdfs:domain and rdfs:range values to full URIs in parser
- Fix type: ignore in Robot helper with proper Callable typing
- Export UKO models from core/__init__.py
- Add parent-URI existence validation in validate()
- Rename scenario to clarify parser-skips vs validation-rejects
- Add scenario testing validation with injected typeless node
- Add Scenario Outline for multi-layer node count assertions

- TTL: Layer 0 classes (InformationUnit, Container, Atom, Annotation,
  Boundary) with contains/references/dependsOn properties. Layer 1
  uko-code: classes (Module, Callable, TypeDefinition, TestCase, Import)
  with hasReturnType/hasParameters/testsCallable. Layer 2 uko-oo: classes
  (Class, Interface, Method, Attribute) with inheritsFrom/implements and
  rdfs:subPropertyOf. New URI scheme cleveragents.ai/ontology/uko#.
- TTL: uko-oo:Class has dual rdfs:subClassOf (TypeDefinition + Container),
  uko-oo:Interface has dual rdfs:subClassOf (TypeDefinition + Boundary).
- Model: UKONode.parent_uri replaced with parent_uris: tuple[str, ...]
  to support multi-parent rdfs:subClassOf.
- Loader: prefix regex supports hyphenated names (uko-code, uko-oo).
  Semantic domain prefix maps (_LAYER_PREFIXES, _LAYER_IRI_PREFIXES).
  Comma-separated rdfs:subClassOf parsing. rdfs:domain/range/subPropertyOf
  URI resolution. BFS DAG traversal with DFS cycle detection for
  resolve_inheritance. HTTP URI skip in validation (D-1 fix). Duplicate
  error guard (B-1 fix). Consistent quoting (M-1 fix).
- Services __init__: export UKOLoader and UKOValidationError.
- Tests: 24 Behave scenarios (multi-parent, domain/range resolution,
  non-existent parent validation). 4 Robot smoke tests. Consolidated
  context attributes (T-3 fix).
- Docs: uko.md written for spec-aligned structure.

- Namespace prefix match in parent-URI validation includes a
delimiter guard (# or /) preventing false positives on URIs that share
the UKO prefix string (e.g. ukobogus:, ukoo:).

ISSUES CLOSED: #189
2026-03-04 22:40:34 +00:00
freemo 4ca4874c4d feat(correction): implement cross-plan correction cascading with child plan state handling
Add CrossPlanCorrectionService that implements the four child-plan-state-
dependent behaviours from the specification when a correction's affected
subtree includes child plans:

- Not yet started → cancel the child plan
- In progress → cancel + rollback sandbox to pre-child-plan state
- Completed but not applied → cancel + rollback sandbox
- Already applied → reject the correction (CorrectionRejection)

Key additions:
- ChildPlanState enum classifying child plans into 4 states
- CorrectionRejection result type with reason and affected applied plan IDs
- CascadeAction/CascadeResult models for cascade operation tracking
- CorrectionStatus.REJECTED for rejected corrections
- Atomic cascade-or-rollback: all child plan actions succeed or the
  entire cascade is rolled back
- Protocol-based dependency injection (ChildPlanLookup, ChildPlanCanceller,
  SandboxRollbacker) for testability
- execute_correction_with_cascade() integrates with CorrectionService flow

Testing:
- 24 Behave BDD scenarios in cross_plan_correction.feature
- 8 Robot Framework end-to-end smoke tests
- ASV benchmarks for cascade performance with varying child plan counts

ISSUES CLOSED: #547
2026-03-04 21:20:47 +00:00
freemo abd4c6de49 feat(actor): implement built-in invariant reconciliation actor
Add InvariantReconciliationActor that runs at the start of the Strategize
phase to reconcile invariants from four scopes (global, project, action,
plan). The actor detects conflicts, resolves them using specificity-based
precedence (plan > action > project > global), honours non_overridable
global invariants, records invariant_enforced decisions, and produces a
reconciled InvariantSet.

Changes:
- New: src/cleveragents/actor/reconciliation.py
  - InvariantReconciliationActor class with collect_invariants() and run()
  - reconcile_invariants() pure function
  - ScopeInvariants, ConflictRecord, ReconciliationResult dataclasses
- Modified: src/cleveragents/domain/models/core/invariant.py
  - Added non_overridable: bool field to Invariant model
- New: features/invariant_reconciliation_actor.feature (26 BDD scenarios)
- New: features/steps/invariant_reconciliation_actor_steps.py
- New: robot/invariant_reconciliation_actor.robot
- New: robot/helper_invariant_reconciliation.py
- New: benchmarks/invariant_reconciliation_bench.py

Closes #549
2026-03-04 20:26:42 +00:00
freemo 93e3893d69 feat(validation): implement tool wrapping runtime (wraps + transform delegation)
Implement the runtime execution engine for validation tool wrapping,
as specified in docs/specification.md § Tool Wrapping.

WrappedToolExecutor resolves wraps references and delegates execution
to wrapped tools, supporting composable wrapping chains with cycle
detection and depth limiting (max 10 levels).

ArgumentMapper translates arguments between wrapper and wrapped tool
schemas using the argument_mapping configuration. Supports both
forwarded parameter names and literal fixed values.

TransformExecutor runs user-supplied transform functions in a
sandboxed Python environment with restricted builtins (no imports,
no filesystem, no network access). Validates that transforms return
proper validation-format dicts with a passed boolean.

Wired into the tool package public API via tool/__init__.py exports.
All new error types (WrappedToolNotFoundError, WrappingCycleError,
WrappingDepthExceededError, TransformExecutionError) provide clear
diagnostic messages.

Tests: 20 Behave scenarios covering argument mapping, transform
execution, simple/chained delegation, error handling, and sandbox
restrictions. 8 Robot Framework integration smoke tests. ASV
benchmarks for delegation overhead measurement.

ISSUES CLOSED: #543
2026-03-04 18:21:19 +00:00
freemo db5e5c974f feat(autonomy): implement semantic escalation with confidence scoring and threshold comparison 2026-03-04 12:18:51 -05:00
freemo 5935940276 feat(sandbox): implement sandbox boundary algebra and domain computation
Implement sandbox_boundary(r) function that walks up containment edges
in the resource DAG to the nearest sandboxable ancestor, enabling
resources sharing a boundary to share one sandbox instance.

Changes:
- Add boundary.py: is_sandbox_boundary(), sandbox_boundary(),
  compute_sandbox_domains(), BoundaryCache (thread-safe, per-execution)
- Update SandboxManager: resolve_sandbox_key() and
  get_or_create_sandbox_for_resource() key by (plan_id, boundary_id)
  instead of (plan_id, resource_id); boundary cache lifecycle methods
- Define "sandboxable" via ResourceCapabilities.sandboxable + non-none
  sandbox_strategy as per specification section 24659-24674
- Export new symbols from sandbox __init__.py
- Add vulture whitelist entries for new public API

Tests:
- 26 Behave BDD scenarios (features/sandbox_boundary_algebra.feature)
- 5 Robot Framework integration tests (robot/sandbox_boundary_algebra.robot)
- ASV benchmarks for boundary walk, domain grouping, and cache performance

ISSUES CLOSED: #548
2026-03-04 15:59:15 +00:00
freemo 8e6642e8c9 feat(decision): implement influence DAG traversal in correction affected subtree computation
Extended _compute_affected_subtree() to BFS over both the structural tree
(parent-child plan relationships) and decision_dependencies edges (influence
DAG). The algorithm performs a single O(V+E) BFS pass that unions neighbors
from both edge sources, using a visited set for cycle detection to guard
against data corruption.

Decision creation now supports dependency_decision_ids parameter in
record_decision() which populates the in-memory influence DAG store.
get_influence_edges() returns the adjacency list format consumed by
CorrectionService.

All public CorrectionService methods (analyze_impact, execute_revert,
execute_correction, generate_dry_run_report) accept an optional
influence_edges parameter while remaining backward-compatible (defaults
to None, preserving structural-only traversal when not provided).

Key design decisions:
- Single BFS pass over union of structural + influence edges rather than
  separate traversals, ensuring O(V+E) complexity and consistent visit order
- Cycle detection via visited set with warning log (not an error) since
  cycles indicate data corruption, not a programming error
- Influence edge logging: traversal emits count of influence edges processed
  for observability
- Backward-compatible API: existing callers that only pass decision_tree
  continue to work identically

ISSUES CLOSED: #542
2026-03-04 15:36:34 +00:00
Luis Mendes ff42d59d6d feat(cli): wire project context CLI stubs to ACMS pipeline
Wire all four project context CLI commands (inspect, simulate, set, show)
to live ACMS pipeline services via ContextTierService and CRP models.

- context inspect: queries ContextTierService for tier metrics and
  per-project fragments with filtering by strategy/focus/breadth/depth
- context simulate: dry-run context assembly using CRP models with
  configurable token budget and assembly strategies
- context set: 12 new ACMS pipeline options (hot_max_tokens,
  warm_max_decisions, cold_max_decisions, summary_max_tokens,
  temporal_scope, auto_refresh, focus_area, breadth, depth,
  assembly_strategy, retrieval_strategy, summary_strategy)
- context show: displays ACMS pipeline configuration alongside policy

- `context inspect` displayed global tier fragment counts (hot/warm/cold)
across all projects instead of counts for the target project only.

Add `ContextTierService.get_scoped_metrics(project_names)` which uses
`ScopedBackendView` to filter fragment counts to the specified projects
while keeping hit/miss counters as global service-level cache metrics.
Update `context_inspect()` to call `get_scoped_metrics([project])`
instead of `get_metrics()`.

- `context simulate --focus` accepted focus URIs and passed them to the
`ContextRequest` model but never used them to filter the fragment list,
making the `--focus` flag a no-op.

Add focus URI filtering in `_simulate_context_assembly()` after
`get_scoped_view()` — filters `project_fragments` by matching each
fragment's `resource_id` against the supplied focus URIs.

Also fixes redaction false positives for hot_max_tokens and
summary_max_tokens keys, and Rich Console line-wrapping in test
output that caused JSON parse failures.

Includes 28 new Behave BDD scenarios for wiring coverage, updated
Robot Framework integration tests, and reference documentation.

ISSUES CLOSED: #499
2026-03-03 23:36:15 +00:00
Luis Mendes b4b96d213c feat(security): add safety profile enforcement
Implement safety profile resolution and enforcement in the tool
execution pipeline, replacing the NotImplementedError stub with
working precedence logic and runtime safety checks.

Core changes:
- resolve_safety_profile() now resolves plan > action > project >
  global precedence, returning the highest-priority non-None profile
  (or DEFAULT_SAFETY_PROFILE with GLOBAL provenance when all None)
- ToolExecutionContext gains an optional safety_profile field
- ToolRuntime._enforce_capabilities() extended with three new checks:
  * Unsafe tool gating: blocks tools with unsafe=True when profile
    has allow_unsafe_tools=False (ToolSafetyViolationError)
  * Skill category allow-list: blocks tools whose skill category
    is not in allowed_skill_categories (ToolSafetyViolationError)
  * Checkpoint requirement: OR-combines ctx.require_checkpoints
    with safety_profile.require_checkpoints
- New ToolSafetyViolationError in tool error hierarchy

Test coverage:
- 30 updated BDD scenarios in safety_profile.feature (resolve
  precedence replaces NotImplementedError stub test)
- 24 new BDD scenarios in safety_profile_enforcement.feature
- 9 Robot Framework integration smoke tests
- 4 ASV benchmark suites (construction, serialization, resolution,
  provenance enum)

All nox sessions pass (typecheck 0 errors, unit_tests 7735 scenarios
0 failures, coverage 97%, integration_tests 9/9 passed, benchmarks
complete).

ISSUES CLOSED: #345
2026-03-03 22:21:14 +00:00
freemo 3f14cbbf7e feat(observability): add LLMTrace model and operational metrics
Add LLMTrace Pydantic v2 domain model with all required fields (trace_id,
plan_id, decision_id, actor, provider, model, prompt_tokens, completion_tokens,
cost_usd, latency_ms, tool_calls, context_hash, streaming, retry_count, error).

Define 14 OperationalMetricKey values (PLAN_DURATION_MS, PLAN_TOTAL_COST_USD,
PLAN_DECISION_COUNT, ACTOR_INVOCATION_COUNT, ACTOR_LATENCY_MS,
TOOL_INVOCATION_COUNT, TOOL_ERROR_RATE, CONTEXT_BUILD_TIME_MS,
CONTEXT_TOKEN_COUNT, LLM_CALL_COUNT, LLM_TOTAL_TOKENS, LLM_TOTAL_COST_USD,
LLM_AVG_LATENCY_MS, SUBPLAN_COUNT) with MetricEntry model and MetricCollector.

Add llm_traces database table (LLMTraceModel) with LLMTraceRepository for
persistence. TraceService provides recording, querying, metric computation,
plan lifecycle hooks, and optional LangSmith forwarding when
LANGCHAIN_TRACING_V2=true.

Wired into DI container as trace_service. Includes 28 Behave BDD scenarios,
6 Robot Framework smoke tests, 3 ASV benchmark suites, and reference
documentation.

Fix pre-existing cli_core server_mode test flake by mocking
resolve_server_mode in test steps to avoid stale config file interference.

Closes #500
2026-03-03 17:04:17 -05:00
freemo 4232907ab9 feat(plan): add large-project decomposition and dependency closure
Add hierarchical decomposition with 4+ levels and bounded context per
subplan. Implement decomposition heuristics (max_files_per_subplan,
max_tokens_per_subplan, language/dir clustering). Add dependency closure
computation for large graphs and DAG execution ordering. Add bounded
dependency closure with cutoff thresholds and memoization for 10K+
files. Record decomposition decisions in DecisionService
(strategy_choice + subplan_spawn entries).

New modules:
- decomposition_models.py: DecompositionConfig, DecompositionNode,
  DecompositionResult, DependencyEdge, DependencyGraph
- decomposition_clustering.py: ClusteringStrategy with directory,
  language, and size clustering plus deterministic sort
- decomposition_graph.py: DependencyClosureComputer with bounded
  closure, topological sort, cycle detection, and memoization
- decomposition_service.py: DecompositionService orchestrating
  hierarchy building and decision recording

Settings: planner_max_depth, planner_max_files_per_subplan,
planner_max_tokens_per_subplan, planner_min_files_per_subplan

Closes #205
2026-03-03 21:44:20 +00:00
freemo 738c3b5eda feat(plan): add multi-project subplan support
Add domain models, application service, CLI integration, and full test
coverage for multi-project subplan orchestration.

New components:
- MultiProjectMetadata, ProjectScope, ProjectDependency domain models
- MultiProjectService for creating/managing multi-project plans
- CLI display of multi-project metadata in plan commands
- Behave BDD tests (20 scenarios), Robot Framework integration tests,
  ASV benchmarks, and reference documentation

Also fixes pre-existing test flakiness in cli_core, core_cli_commands,
cli_plan_context_commands, and helper_server_stubs caused by environment
leakage and path-with-spaces issues.

ISSUES CLOSED: #199
2026-03-03 14:55:58 -05:00
freemo ad5f737721 feat(execution): add execution environment routing
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
2026-03-03 14:48:55 -05:00
freemo 6519f140a9 feat(context): add hot/warm/cold tiers and actor views
Implement hot/warm/cold context tiers with ContextTier, ActorRole,
TieredFragment, TierBudget, ActorContextView, TierMetrics, and
ScopedBackendView models. ContextTierService provides store/get,
promotion/demotion with cold-tier summarisation hook, LRU eviction,
per-actor filtered views (strategist/executor/reviewer), and
project-scoped isolation via ScopedBackendView.

Settings: context_max_tokens_hot, context_max_decisions_warm,
context_max_decisions_cold. DI-wired as singleton context_tier_service.

Includes Behave BDD scenarios (30), Robot Framework integration tests (7),
ASV benchmarks (5 suites), and docs/reference/context_tiers.md.

Closes #208
2026-03-03 17:01:57 +00:00
aditya 5bd7a507b8 Merge branch 'master' into feature/m6plus-event-bus 2026-03-03 15:20:19 +00:00
aditya 89bc776381 refactor(events): address PR-509 review comments
- 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.
2026-03-03 15:15:55 +00:00
aditya 5f0bc97d46 Merge branch 'master' into feature/m5-subplan-actor
# Conflicts:
#	CHANGELOG.md
2026-03-03 14:55:28 +00:00
aditya c4cda5d6d8 fix(actor): address second round code review on plan_subplan tool
- 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
2026-03-03 14:40:37 +00:00
khyari hamza 0e36755db9 fix(service): address review findings for decision service
- Rehydrate sequence counter from DB on restart (BUG-1)
- Add uniqueness guard raising SequenceConflictError (BUG-2)
- Fix delete_decision consistency between persisted/in-memory (BUG-3)
- Validate new_decision_id exists in mark_superseded (BUG-4)
- Include orphaned subtrees in get_tree output (BUG-5)
- Remove dead _decision_seq/_next_seq from plan_lifecycle (BUG-7)
- Export SequenceConflictError from services __init__ (SPEC-2)
- Replace list[Any] with list[ArtifactRef] typing (SPEC-4)
- Add actor_reasoning max_length validation (SEC-1)
- Use SELECT COUNT(*) in count_decisions (PERF-1)
- Replace MagicMock with create_autospec(Settings) (TEST-3)
- Eliminate UnitOfWork.__new__() anti-pattern (TEST-4)
- Use exact assertion counts in DI tests (TEST-5)
- Add restart rehydration, BFS order, invalid type, and
  confidence boundary test scenarios (TEST-1/2/6/7)
- Fix decision_service_coverage.feature to match actual API

ISSUES CLOSED: #172
2026-03-03 12:53:28 +00:00
khyari hamza d5802a4878 fix(service): use DecisionService kwargs API in plan lifecycle caller
Align _record_decision_safe() to call record_decision() with keyword
arguments directly instead of manually constructing a Decision model.
The service now handles sequence numbering and model construction
internally.

ISSUES CLOSED: #172
2026-03-03 12:18:27 +00:00
khyari hamza 878bad4848 feat(service): add decision recording and snapshot store 2026-03-03 12:18:27 +00:00