Commit Graph

1210 Commits

Author SHA1 Message Date
freemo c9be72a99f fix: rename cls to klass in _validate_protocol staticmethod for pyright compliance 2026-03-24 20:28:19 +00:00
freemo 8e9aa7af48 fix(client): address server client chain review findings
- Promote _request() to public method request() in ServerHttpClient
  to fix encapsulation violation across sync_client and remote_project
- Fix WebSocket connect() to raise NotImplementedError with clear TODO
  documenting that real websockets transport is not yet implemented
- Fix thread safety: protect last_event_id write under self._lock
  in ws_client.process_event()
- Broaden exception handling in sync() to catch ServerTimeoutError
  and A2aNotAvailableError in addition to ServerConnectionError
- Add has_next to PageResult in benchmark and test helpers
- Add comments explaining Retry-After header logging-only behavior
  and why blocking time.sleep is acceptable in sync client
- Update all test steps, robot helpers, and benchmarks to use the
  renamed public request() method and updated connect() behavior

Refs: #335, #336, #337, #338
2026-03-24 20:28:19 +00:00
freemo 3fe7dabb65 feat(client): add remote project support
Implement RemoteProjectClient for accessing and executing projects
hosted on a remote CleverAgents server:
- Remote resource selection and server execution request wiring
- Project-name resolution for remote namespaces and server aliases
- Resolve project with fallback from custom to default namespace
- Remote project caching with configurable TTL (default 5 min)
- Explicit ResourceNotFoundError when remote project not found
- Cache invalidation per-namespace or global
- RemoteProject dataclass with project_id, name, namespace, alias,
  description
- Behave scenarios (16 scenarios, 54 steps)
- Robot Framework smoke tests
- ASV benchmark for request overhead baseline
- Reference documentation at docs/reference/server_remote_projects.md

ISSUES CLOSED: #338
2026-03-24 20:28:19 +00:00
freemo 61dc421975 feat(client): add websocket updates
Implement WebSocketClient for receiving real-time plan update events
from a CleverAgents server via WebSocket connection:
- Plan update subscription with reconnect/exponential backoff
- Event schema for plan status, progress, and log stream updates
- Heartbeat/ping handling that resets reconnect counter
- Resume from last event ID on reconnect
- Event version negotiation
- Event de-duplication by event_id via LRU-bounded EventDeduplicator
- Ordered delivery guarantees with thread-safe callback dispatch
- Configurable reconnect backoff parameters (base, max, max_reconnects)
- ConnectionState model tracking lifecycle state
- websockets library added to pyproject.toml dependencies
- Behave scenarios (16 scenarios, 62 steps)
- Robot Framework smoke tests
- ASV benchmark for message handling baseline
- Reference documentation at docs/reference/server_websocket.md

ISSUES CLOSED: #337
2026-03-24 20:28:19 +00:00
freemo ae1fd648d5 feat(client): add plan sync and remote execution
Implement PlanSyncClient for synchronizing local resources with a remote
CleverAgents server and submitting plans for remote execution:
- Sync actions, skills, tools, projects with configurable scope flags
- Conflict resolution policies (local_wins / server_wins)
- Remote plan execution, apply, and status query endpoints
- Server-side ID persistence in local item metadata
- Sync summary output (created/updated/skipped/errors)
- Dry-run mode that skips server mutations
- SyncScope, SyncSummary, ExecutionResult data models
- Behave scenarios (18 scenarios, 62 steps)
- Robot Framework smoke tests
- ASV benchmark for sync throughput baseline
- Reference documentation at docs/reference/server_sync.md

ISSUES CLOSED: #336
2026-03-24 20:28:19 +00:00
freemo 5f7bba3e96 feat(client): add server http client
Implement ServerHttpClient with httpx for server communication including:
- Health check endpoint (GET /health)
- Version negotiation (GET /version, POST /version/negotiate)
- Pagination helpers for list endpoints
- Per-request timeout and retry policy with exponential backoff
- Request/response logging with auth header redaction
- TLS verification toggle with warning when disabled
- Server error responses mapped to domain errors (A2aNotAvailableError, etc.)
- Client-specific exceptions (ServerConnectionError, ServerTimeoutError,
  ServerVersionMismatchError)
- Settings fields: server_base_url, server_api_token, server_tls_verify,
  server_request_timeout
- Factory function create_client_from_settings wired to Settings
- httpx added to pyproject.toml dependencies
- Behave scenarios (23 scenarios, 72 steps)
- Robot Framework smoke tests
- ASV benchmark for connection overhead baseline
- Reference documentation at docs/reference/server_client_http.md

ISSUES CLOSED: #335
2026-03-24 20:28:19 +00:00
freemo 2e094ef938 feat(acms): add text, vector, and graph backend protocol implementations
Define TextBackend, VectorBackend, and GraphBackend protocols with
corresponding result dataclasses. Implement in-memory stub backends
for pipeline integration testing. Register backends in DI container
with configurable provider selection.

ISSUES CLOSED: #498
2026-03-24 18:12:16 +00:00
freemo 93da31e80f fix(skill): resolve skill add persistence regression after PR #640
Root cause: _build_skill_service in container.py created a SkillRepository
pointing at the database but did not ensure the skills/skill_items tables
existed. When the tables were missing, SkillRepository.list_all() and
create() failed silently (caught by SkillService._load_from_db and
_persist_skill exception handlers), causing the service to operate in
in-memory-only mode. Skills added in one CLI process were lost when a
new process created a fresh SkillService.

Additionally, SkillRepository lacked auto_commit support. Each call to
session_factory() returned a new session, so the flush in create/update/
delete operated on a different session than the commit in
SkillService._commit(), meaning data was never actually persisted even
when the tables existed.

Fix:
1. Add targeted table creation in _build_skill_service (following the
   pattern in _build_session_service) — checks for missing skills and
   skill_items tables and creates them via Base.metadata.create_all.
2. Add auto_commit parameter to SkillRepository (following the pattern
   in SessionRepository) so each mutating method commits and closes its
   own session.
3. Pass auto_commit=True from the container builder.
4. Remove @tdd_expected_fail from TDD test (leaving @tdd_bug and
   @tdd_bug_980 as permanent regression guards).

ISSUES CLOSED: #980
2026-03-24 17:08:22 +00:00
freemo a6e2bc7842 test: add TDD bug-capture test for #980 — skill add cross-process persistence
Write cross-process Behave and Robot tests capturing skill add
persistence regression. Tests use subprocess invocations to verify
skills persist across CLI process boundaries.

The existing persistence tests (skill_add_persist.feature) verify
round-trip within the same Python process by creating two SkillService
instances sharing the same in-memory database. This approach cannot
detect the cross-process regression where _build_skill_service falls
back to in-memory storage because the skills table does not exist in
the database created by agents init.

Behave: features/tdd_skill_add_regression.feature
Robot:  robot/tdd_skill_add_regression.robot

Tags: @tdd_bug, @tdd_bug_980, @tdd_expected_fail

ISSUES CLOSED: #981
2026-03-24 17:08:22 +00:00
hamza.khyari 4a5f826f77 Merge pull request 'feat(resource): implement ResourceHandler CRUD and discovery methods' (#1054) from feature/resource-handler-crud into master
Reviewed-on: cleveragents/cleveragents-core#1054
2026-03-24 14:40:34 +00:00
hamza.khyari 90e5bbb99c feat(resource): implement ResourceHandler CRUD and discovery methods
Extend the ResourceHandler protocol with six content operations (read,
write, delete, list_children, diff, discover_children) and four frozen
dataclass result types (Content, WriteResult, DeleteResult, DiffResult).

Handler implementations:
- GitCheckoutHandler: read via git show (binary-safe), write/delete via
  filesystem ops, list via git ls-tree, diff via git diff --no-index
  with locale-safe shortstat parsing, discover via git ls-tree -d
- FsDirectoryHandler: full CRUD via pathlib/os/difflib/shutil
- DevcontainerHandler: read/write/discover via devcontainer exec
- CloudResourceHandler: NotImplementedError stubs for protocol compliance
- DatabaseResourceHandler: inherits base NotImplementedError stubs

Security:
- Path traversal guard (_safe_resolve) on all read/write/delete ops
  using os.sep-suffixed startswith check to prevent prefix collisions
- Empty-path deletion rejected with PermissionError

Tests:
- 22 Behave scenarios (115 steps): CRUD for FsDirectory and GitCheckout,
  path traversal rejection (3 scenarios), NotImplementedError defaults
- 2 Robot integration tests: read -> write -> diff cycle on real temp
  directories and git repos

ISSUES CLOSED: #827
2026-03-24 13:53:41 +00:00
hamza.khyari 188a9edd49 Merge pull request 'feat(resource): add LSP resource types' (#1046) from feature/lsp-resource-types into master
Reviewed-on: cleveragents/cleveragents-core#1046
2026-03-24 13:36:30 +00:00
hamza.khyari 65a2e4db76 feat(resource): add LSP resource types
Add 4 LSP-related built-in resource types to the resource registry:

- executable: system binary/interpreter/LSP server binary with
  auto-discovery from container-exec-env and fs-directory (lazy)
- lsp-server: LSP server definition with command, language-ids,
  transport, args, port, initialization-options config;
  children: lsp-workspace
- lsp-workspace: workspace root tracked by LSP server, auto-discovered
  from lsp-server; children: lsp-document; not user-addable
- lsp-document: text document tracked by LSP server, auto-discovered
  from lsp-workspace; read+write capabilities; not user-addable

Type definitions extracted to _resource_registry_lsp.py for consistency
with existing type modules. Parent/child hierarchy: lsp-server ->
lsp-workspace -> lsp-document. YAML configs with ADR references
(ADR-039, ADR-040). All 7 lsp-server CLI args per ADR-040.

Behave tests (21 scenarios): YAML loading, user-addable flags,
capabilities, parent/child hierarchy, auto-discovery for all 3
discoverable types, BUILTIN_NAMES, DB bootstrap roundtrip, negative
tests for manual registration rejection.

Robot tests (6 tests): import, BUILTIN_NAMES, DB roundtrip, hierarchy,
auto-discovery, user-addable guard.

ISSUES CLOSED: #832
2026-03-24 13:21:12 +00:00
hamza.khyari e07b68221a Merge pull request 'feat(lsp): implement functional LSP runtime' (#1044) from feature/lsp-functional-runtime into master
Reviewed-on: cleveragents/cleveragents-core#1044
2026-03-24 13:17:44 +00:00
hamza.khyari 4ff075e0da feat(lsp): implement functional LSP runtime
Replace local-mode stubs with real LSP protocol support:

- StdioTransport: subprocess management with JSON-RPC framing
- LspClient: LSP protocol (initialize/shutdown/diagnostics/completions)
- LspLifecycleManager: reference-counted instances, health checks, crash restart
- LspRuntime: registry-based server lookup, auto-restart on crash
- LspToolAdapter: runtime-delegating handlers with local-mode fallback
- LanguageDiscovery: 4-layer detection (extension, shebang, UKO, project)
- activate_bindings/deactivate_bindings: actor compiler LSP binding wiring

Tests: 27 Behave scenarios, 6 Robot integration tests, 250 existing pass.

ISSUES CLOSED: #826
2026-03-24 13:01:12 +00:00
aditya a854de7e1f Merge pull request 'test(cli): add regression-guard tests for Container.resolve() crash' (#1053) from tdd/m3-container-resolve-crash into master
Reviewed-on: cleveragents/cleveragents-core#1053
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Reviewed-by: Hamza Khyari <hamza.khyari@cleverthis.com>
Reviewed-by: Rui Hu <rui.hu@cleverthis.com>
2026-03-24 09:25:49 +00:00
aditya 36c36bc0ee test(cli): add regression-guard tests for Container.resolve() crash
Add Behave and Robot Framework regression tests for bug #647, where
plan tree, plan explain, and plan correct CLI commands crashed with
AttributeError when resolving DecisionService from the DI container.

Tests use a real DI container with seeded decisions (not MagicMock)
to catch the exact class of bug that existing M3 tests missed.
Assertions verify successful execution and command-specific output
content. Includes Settings.reset() classmethod for robust singleton
cleanup in test teardown.

Review feedback addressed (hurui200320 Round 5):
- Fixed Behave step engine leak by capturing UoW in cleanup closure
- Removed dead @then decorator; renamed to private _assert_command_succeeded
- Strengthened plan correct assertions with revert/dry-run content checks
- Updated misleading get_container() comment to reflect singleton warming
- Added test-only warning to Settings.reset() docstring
- Added type annotations to 4 settings step functions
- Fixed CONTRIBUTORS.md alphabetical ordering and removed duplicate entry
- Replaced glob.glob with pathlib suffix iteration in Robot helper
- Fixed feature description line break for readability
- Removed redundant TYPE_CHECKING import for Decision

ISSUES CLOSED: #648
2026-03-24 08:46:58 +00:00
Luis Mendes 9e316b1a3e fix(domain): align plan lifecycle model validation with specification
Aligned the plan lifecycle model with the specification:

1. ERRORED is now treated as terminal in is_terminal property,
   matching the spec table where errored is marked "Terminal? Yes"
   for all processing phases.

2. Added per-phase state validation via model_validator: APPLIED
   and CONSTRAINED are only valid in APPLY phase; COMPLETE is only
   valid in STRATEGIZE or EXECUTE phases. Invalid combinations
   now raise ValueError at construction time.

3. Updated ProcessingState.COMPLETE docstring to clarify phase-level
   terminality semantics.

4. Fixed assignment ordering in execute_plan() to set
   processing_state before phase, consistent with the state-first
   pattern used in apply_plan() and _perform_reversion().

5. Added defensive coercion in LifecyclePlanModel.to_domain() to
   handle legacy DB rows with invalid phase/state combinations
   (e.g. APPLY/COMPLETE -> APPLY/APPLIED) with warning-level
   logging for observability.

6. Updated module docstrings: ERRORED description now reflects
   terminal semantics, terminal outcomes location clarified for
   all phases, can_revert_to docstring notes ERRORED/CONSTRAINED
   are terminal but revertable, is_terminal docstring explains
   the distinction between terminal and permanently irrecoverable
   and documents why COMPLETE is not plan-terminal despite the
   spec marking it "Terminal? Yes" (phase-level vs plan-level).

7. Updated PlanResumeService.validate_eligibility() docstring to
   reflect that ERRORED is now terminal but still eligible for
   resume.

8. Added CHANGELOG entry.

ISSUES CLOSED: #918
2026-03-23 23:33:33 +00:00
Luis Mendes bd18491b8d fix(test): replace shell=True with shell=False in cli_coverage_steps.py subprocess call
Replaced shell=True with shell=False and shlex.split() for command
tokenization in cli_coverage_steps.py, consistent with the pattern
already used in cli_plan_context_commands_steps.py. Audited all step
files for additional shell=True usages.

ISSUES CLOSED: #734
2026-03-23 22:22:16 +00:00
Luis Mendes 1ffb0fddbe feat(plan): decision correction recomputes only affected subtree
Enhanced the CorrectionService to properly isolate correction scope:

1. analyze_impact() now populates excluded_decisions by computing
   the set difference between all plan decisions and the affected
   subtree, ensuring root and sibling decisions are tracked.

2. Added rollback_tier computation that counts parent hops from
   the target decision to the root, enabling depth-aware rollback
   strategies (tier 0 = root targeted, tier N = N levels deep).

3. Enhanced dry-run report with excluded decisions list, rollback
   tier, and tier-0 warning when entire tree is affected.

4. Added subtree isolation validation confirming root exclusion
   and sibling non-contamination for non-root corrections.

5. Fixed status state-machine regression in execute_revert() where
   analyze_impact() overwrote status back to ANALYZING from EXECUTING.
   Guard now only transitions to ANALYZING when status is PENDING.
   execute_revert() now transitions through ANALYZING before EXECUTING
   for correct lifecycle ordering.

6. Fixed validate_subtree_isolation() to use structural-only BFS for
   the sibling invariant check, so that influence-DAG-caused sibling
   reachability is not misreported as an isolation violation (per spec
   § Affected Subtree Computation).

7. Fixed false-positive cycle-detection warnings from convergent
   (diamond) topologies by replacing per-node seen_this_round with a
   global enqueued set in BFS, preventing duplicate queue insertions
   from different parents.

8. Added dry_run enforcement guard in _assert_executable() to prevent
   execution of dry-run-only corrections per spec (§ plan correct
   --dry-run: "Show impact without executing").

9. Fixed generate_dry_run_report() to preserve request status so that
   generating a preview does not advance the correction lifecycle
   (dry-run is non-mutating per spec).  Status restoration now uses
   try/finally to guarantee recovery even when analyze_impact() raises
   after transitioning the status.

10. Improved cycle-detection log message accuracy to cover both
    structural tree and influence DAG sources.

11. Extracted cost/time estimation constants (_COST_PER_DECISION,
    _RECOMPUTE_SECONDS_PER_DECISION) from magic numbers.

12. Added terminal-state guard in analyze_impact() to reject
    re-analysis after execution (APPLIED/FAILED/CANCELLED/REJECTED),
    preventing audit-data corruption.  Promoted terminal-status set
    to a module-level _TERMINAL_STATUSES frozenset constant.

13. Added mode validation in execute_revert()/execute_append() to
    prevent mode-mismatched execution (e.g. calling execute_revert
    on an APPEND correction).

14. Fixed _collect_all_decisions() to always include the target
    decision in the universe, preventing broken partition invariant
    for isolated single-node plans.

15. Fixed tier-0 dry-run warning to only trigger when the target
    is genuinely in the structural tree (avoiding false warnings for
    nodes not present in the tree).

16. Removed duplicate as_cli_dict regression scenarios in
    resource_type_deferred_physical.feature.

ISSUES CLOSED: #845
2026-03-23 18:41:53 +00:00
freemo a3c3a5c530 Docs: daily update to timeline 2026-03-22 23:45:54 -04:00
freemo 5f5ef891a2 Docs: daily update to timeline 2026-03-22 17:29:19 -04:00
freemo a2113deace fix(a2a): suppress stdout/stderr in facade bootstrap to prevent test pollution
The _notify_facade and _facade_dispatch functions call get_container()
during lazy facade construction. This can trigger structlog output that
corrupts CLI stdout captured by CliRunner in tests.

Wrap facade construction in redirect_stdout/redirect_stderr to
suppress any side-effect output. Also reset the facade singleton
in after_scenario for test isolation.
2026-03-22 05:25:44 +00:00
freemo 4f2aa4189c fix(test): guard result.stderr access against ValueError
Click/Typer CliRunner.Result.stderr is a property that raises
ValueError when stderr was not separately captured (mix_stderr=True
is the default).  Wrap all result.stderr accesses in try/except
to handle this gracefully.
2026-03-22 05:01:06 +00:00
freemo 0c301ac581 fix(test): update facade operation count from 11 to 42
The A2A facade now exposes 42 operations (31 extension + 11 legacy)
after the spec-aligned _cleveragents/ extension methods were added.
Update the BDD assertion and docs to match the actual count.
2026-03-22 03:23:42 +00:00
freemo 24aad463a1 feat(a2a): A2A facade session and plan lifecycle operations functional via CLI
Wire CLI session and plan lifecycle commands through the A2A local
facade, establishing the A2A protocol data flow:
CLI -> A2aLocalFacade.dispatch() -> Service -> Domain.

Key changes:
- Added cli_bootstrap.py module providing get_facade() which lazily
  constructs a process-wide A2aLocalFacade instance wired to the DI
  container (plan_lifecycle_service, session_service,
  resource_registry_service, tool_registry). Service wiring is
  best-effort via contextlib.suppress.
- Session CLI create command now notifies the A2A facade after session
  creation for protocol bookkeeping and telemetry.
- Plan CLI commands (use, execute, lifecycle-apply) now notify the A2A
  facade via _notify_facade() helper after operations complete. The
  notification is best-effort (exceptions are suppressed) to avoid
  breaking CLI functionality if the facade is not available.
- Added Behave feature (a2a_cli_facade_integration.feature) with 8
  scenarios covering: facade bootstrap wiring, all 11 operations
  supported, session/plan dispatch through facade, and best-effort
  error suppression.

The facade notification pattern preserves backward compatibility:
CLI commands still perform the primary work via direct service calls,
then notify the facade for A2A protocol compliance. This allows
incremental migration toward full facade-first routing.

ISSUES CLOSED: #852
2026-03-22 01:54:33 +00:00
freemo f138bab5ff feat(a2a): implement SSE streaming for task updates and artifacts
Add Server-Sent Events (SSE) streaming infrastructure to the A2A
event system, enabling real-time delivery of task status updates
and artifact notifications.

Key changes:
- Defined SSE event type constants: TASK_STATUS_UPDATE
  (TaskStatusUpdateEvent) and TASK_ARTIFACT_UPDATE
  (TaskArtifactUpdateEvent) per the A2A protocol specification.
- Added SseEventFormatter class that converts A2aEvent instances
  to text/event-stream format with event, id, and data fields.
  Includes keepalive formatting for long-lived connections.
- Added EventBusBridge class that subscribes to the internal
  EventBus (ReactiveEventBus) and translates DomainEvent instances
  into A2aEvent instances published to the A2aEventQueue. Maps
  plan lifecycle events (PLAN_CREATED, PLAN_PHASE_CHANGED, etc.)
  to TaskStatusUpdateEvent and checkpoint events to
  TaskArtifactUpdateEvent.
- Bridge handles closed queue gracefully via contextlib.suppress.
- Added 8 Behave scenarios covering SSE formatting, event type
  constants, EventBusBridge translation for both status and
  artifact events, closed queue handling, and JSON payload
  validation.

ISSUES CLOSED: #875
2026-03-22 01:07:20 +00:00
brent.edwards c2a2c5c4bf fix(cli): make plan correct accept plan_id as primary identifier (#1055)
## Summary

- **`plan correct` now accepts a plan_id** as its positional argument (in addition to decision_id). When a plan_id is given, the root decision is automatically selected as the correction target.
- The positional parameter is renamed from `decision_id` to `identifier` with updated help text reflecting dual use.
- Backward compatibility is fully preserved: decision_id inputs continue to work exactly as before.

## How it works

1. Try `container.plan_lifecycle_service().get_plan(identifier)` to check if the identifier is a plan_id
2. If it resolves to a real `Plan` object, use it as `resolved_plan_id` and auto-select the root decision (`parent_decision_id is None`)
3. If lookup fails (`ResourceNotFoundError`) or the result is not a `Plan` instance, fall back to treating the identifier as a decision_id (original behavior)

## Verification

- `nox -s lint` — All checks passed
- `nox -s typecheck` — 0 errors, 1 pre-existing warning
- `nox -s unit_tests` (correction features) — 150 scenarios passed, 683 steps passed, 0 failures

ISSUES CLOSED: #969

Reviewed-on: cleveragents/cleveragents-core#1055
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 18:45:17 +00:00
brent.edwards 34c6972a05 feat(tool): implement BuiltinAdapter class and MCP automatic resource slot creation (#964)
## Summary

Implement `BuiltinAdapter` class and MCP automatic resource slot creation. Two main changes:

### 1. BuiltinAdapter Class (`tool/builtins/adapter.py`)
Formal adapter implementing the tool adapter lifecycle pattern for built-in tools:
- `discover()` — returns all built-in tool descriptors (file, git, subplan tools)
- `register(registry)` — registers all tools in a ToolRegistry, returns registered names
- `activate()`/`deactivate()` — no-ops (built-in tools are always available)
- Wraps existing `ALL_FILE_TOOLS`, `ALL_GIT_TOOLS`, `ALL_SUBPLAN_TOOLS` lists
- Backward compatible — existing registration functions still work

### 2. MCP Resource Slot Inference (`mcp/adapter.py`)
New `infer_resource_slots()` static method on `MCPToolAdapter`:
- Scans MCP tool parameter schemas for file/directory/repo patterns
- Creates `ResourceSlot` objects with appropriate type, access mode, binding mode
- Mapping: `file_path`→file(rw), `directory`→directory(ro), `repo_path`→git-checkout(rw)
- Slots stored in `source_metadata["resource_slots"]` on registered `ToolSpec` objects

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,817 scenarios) |
| `nox -s integration_tests` | PASS (6 new tests) |
| `nox -s coverage_report` | 97% (>= 97%) |

Closes #882

Reviewed-on: cleveragents/cleveragents-core#964
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 05:30:01 +00:00
brent.edwards b88bc0ec1b feat(perf): large project scaling tests (#984)
## Summary

Add large project scaling benchmarks and tests at production scale (10K–100K files).

### New ASV Benchmarks

**IndexingScalingSuite** (`large_project_scaling_bench.py`):
- `time_walk_and_index` at 1K/10K/50K/100K files
- `time_incremental_refresh` (1% modified files)
- `track_indexed_file_count`, `track_tokens_per_second`

**ContextAssemblyScalingSuite** (`context_assembly_scaling_bench.py`):
- `time_full_pipeline` at 100/1K/5K/10K fragments
- `time_tiered_strategy`, `time_recency_strategy`
- `track_assembled_tokens`, `track_fragments_per_second`

**ExecutionThroughputSuite** (`execution_throughput_bench.py`):
- `time_sequential_plans` at 10/50/100 plans
- `time_executor_construction`, `time_decision_tree_scaling`

### Scale Fixture Updates

- Added `xlarge` (50K files) and `xxlarge` (100K files) profiles to `scale_metadata.json`
- Added 50K/100K thresholds to `baseline_thresholds.json`
- Added `context_assembly` and `execution_throughput` threshold sections

### Tests & Documentation

- 15 Behave scenarios validating profiles, thresholds, monotonicity, memory budgets
- 6 Robot integration tests including live 1K-file indexing throughput check
- `docs/reference/scaling_baselines.md` documenting all baseline metrics

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,910 scenarios) |
| `nox -s integration_tests` | PASS (1,526 tests) |
| `nox -s coverage_report` | 97% (>= 97%) |

Closes #859

Reviewed-on: cleveragents/cleveragents-core#984
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 04:46:45 +00:00
brent.edwards 8a87262f86 feat(sandbox): implement overlay filesystem sandbox strategy (#994)
## Summary

Implement the overlay filesystem sandbox strategy with OverlayFS support and userspace fallback.

### Implementation

**`OverlaySandbox`** (`infrastructure/sandbox/overlay.py`, 497 lines):
- Detects OverlayFS availability at runtime via `/proc/filesystems` + `os.geteuid() == 0` check
- **Real OverlayFS mode** (requires root): creates upper/work/merged dirs, mounts overlay filesystem, captures writes in upper layer
- **Userspace fallback** (default in CI/containers): `shutil.copytree` the original into merged dir, tracks changes via `filecmp` diff on commit
- `create()`: sets up directory structure, mounts if available
- `commit()`: copies changed/added files from overlay to original, removes deleted files
- `rollback()`: unmounts (or removes) merged, recreates from scratch
- `cleanup()`: unmounts, removes all temp dirs, idempotent

### Domain Model Updates
- Added `OVERLAY = "overlay"` to `SandboxStrategy` enum in both `resource_type.py` and `resource.py`
- Added `STRATEGY_OVERLAY` to `SandboxFactory`, registered for `fs-mount`, `fs-directory`, `fs-file` resources

### Tests
- **22 Behave scenarios**: full lifecycle (create/commit/rollback/cleanup), status transitions, path traversal guard, fallback detection, error handling
- **6 Robot integration tests**: end-to-end overlay sandbox operations

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,917 scenarios) |
| `nox -s coverage_report` | 97% (>= 97%) |

Closes #880

Reviewed-on: cleveragents/cleveragents-core#994
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-21 03:14:40 +00:00
brent.edwards 6531440431 feat(actor): implement estimation actor type (#962)
## Summary

Implement the estimation actor as a functional actor type. The estimation actor provides cost, time, and resource estimates for plan operations, running after Strategize completes (before Execute). Estimation is informational only and optional — plans work without an estimation actor configured.

### Changes

**New files:**
- `src/cleveragents/domain/models/core/estimation.py` — `EstimationResult` frozen Pydantic model with fields for cost (USD), tokens, steps, child plans, time, risk level/factors, summary
- `features/estimation_actor.feature` — 12 Behave test scenarios (model validation, serialization, stub actor, plan integration, optional behavior)
- `features/steps/estimation_actor_steps.py` — Step definitions
- `robot/estimation_actor.robot` — 6 Robot integration tests
- `robot/helper_estimation_actor.py` — Robot test helper

**Modified files:**
- `domain/models/acms/tiers.py` — Added `ESTIMATOR` to `ActorRole` enum
- `domain/models/core/plan.py` — Added `estimation_result: EstimationResult | None` field, estimation data in `as_cli_dict()`
- `application/services/plan_executor.py` — Added `EstimationStubActor` class
- `application/services/plan_lifecycle_service.py` — Added `_run_estimation()` method, invoked in `execute_plan()`
- `cli/commands/plan.py` — Display estimation results in plan status
- `vulture_whitelist.py` — Added 12 new public symbols

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,818 scenarios) |
| `nox -s integration_tests` | PASS (1,512 tests) |
| `nox -s coverage_report` | 98% (>= 97%) |

Closes #890

Reviewed-on: cleveragents/cleveragents-core#962
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-21 01:40:58 +00:00
brent.edwards 95d3e09925 feat(cli): final CLI polish and UX consistency pass (#1018)
## Summary

Final CLI polish and UX consistency pass: shared constants, centralized error formatting, shell completion, and standardized help text.

### New Modules

- **`cli/constants.py`** (70 lines): Exit codes (`EXIT_SUCCESS`=0 through `EXIT_CONFLICT`=4), format defaults (`FORMAT_TEXT`, `FORMAT_JSON`, `FORMAT_TABLE`)
- **`cli/errors.py`** (105 lines): `cli_error()` with hint support, `cli_warning()`, `cli_not_found()` with resource-type-aware hint

### CLI Changes

- Shell `completion` command generating scripts for bash/zsh/fish/powershell
- Standardized help text across command modules
- Error functions exported from `cli/__init__.py`

### Tests

- **17 Behave scenarios**: Exit codes, error formatting, cli_not_found, format constants, help text, completion
- **15 Robot integration tests**: All subcommands respond to --help, invalid commands return non-zero, completion generation works

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,912 scenarios) |
| `nox -s coverage_report` | 97% (>= 97%) |

Closes #861

Reviewed-on: cleveragents/cleveragents-core#1018
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 01:14:18 +00:00
brent.edwards 00897be24a feat(ci): CI/CD pipeline definitions (#983)
## Summary

Complete CI/CD pipeline definitions: release workflow, caching, status-check consolidation, and documentation.

### Changes

**New: Release pipeline** (`.forgejo/workflows/release.yml`):
- Triggered on `v*` tags
- 3 jobs: `build-wheel` → `build-docker` → `create-release`
- Builds wheel via `nox -s build`, Docker image via multi-stage Dockerfile
- Creates Forgejo release via API with wheel artifact attached
- Configurable registry push via `REGISTRY_*` secrets

**Updated: CI pipeline** (`.forgejo/workflows/ci.yml`):
- Added `actions/cache@v3` for `~/.cache/uv` on all 8 primary jobs (keyed on `pyproject.toml` hash)
- Added `status-check` consolidation job depending on all required checks — single gate for branch protection

**Updated: CONTRIBUTING.md**:
- New CI/CD section: pipeline overview, job table, required merge checks, release process, secrets documentation

**Tests**:
- 13 new Behave scenarios validating workflow YAML structure, tag triggers, job definitions, dependencies
- 9 new Robot tests validating file existence, content, nox session references

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,819 scenarios) |
| `nox -s coverage_report` | 97.9% (>= 97%) |

Closes #858

Reviewed-on: cleveragents/cleveragents-core#983
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 00:29:49 +00:00
brent.edwards fa3f2d6365 test: add TDD bug-capture test for #932 — plan apply missing --yes flag (#958)
## Summary

TDD expected-fail tests proving bug #932 exists: the `plan apply` (`lifecycle-apply`) command does not accept the `--yes`/`-y` flag required by the specification. The flag should skip the confirmation prompt before applying plan changes.

### Tests Added

**Behave scenarios** (`features/tdd_plan_apply_yes_flag.feature`):
- `lifecycle-apply --yes` should be accepted (tests `--yes` long flag)
- `lifecycle-apply -y` should be accepted (tests `-y` short flag)

Tags: `@tdd_expected_fail @tdd_bug @tdd_bug_932`

**Robot Framework tests** (`robot/tdd_plan_apply_yes_flag.robot`):
- `check-yes-long` — invokes CLI with `--yes`, asserts no "No such option" error
- `check-yes-short` — invokes CLI with `-y`, asserts no "No such option" error

### How the Bug Is Proven

The `lifecycle_apply_plan` function (`cleveragents.cli.commands.plan`) defines only `plan_id` and `--format` parameters — no `--yes`/`-y`. When tests invoke `lifecycle-apply --yes`, Typer/Click rejects it with `"No such option: --yes"` and exit code 2. The assertion that this error is absent **fails**, confirming bug #932. The `@tdd_expected_fail` tag inverts this to a pass.

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,808 scenarios) |
| `nox -s integration_tests` | PASS (1,508 tests) |
| `nox -s coverage_report` | 98% (>= 97%) |

Closes #950

Reviewed-on: cleveragents/cleveragents-core#958
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 00:13:17 +00:00
brent.edwards 8d108cb5d1 feat(tool): add tool-level execution environment preferences (#970)
## Summary

Add tool-level execution environment preferences with four modes: `required`, `preferred`, `specific`, and `none`.

### Changes

**New model** (`domain/models/core/execution_environment_preference.py`):
- `EnvironmentPreferenceMode` enum: REQUIRED, PREFERRED, SPECIFIC, NONE
- `ExecutionEnvironmentPreference` frozen Pydantic model with `mode` and `target_resource` fields
- Model validator ensures `target_resource` required iff mode is SPECIFIC

**ToolSpec & Tool model updates:**
- Added `execution_environment: ExecutionEnvironmentPreference` field to both `ToolSpec` (runtime) and `Tool` (domain)
- `Tool.from_config()` parses `execution_environment` from YAML config dicts

**ToolRunner integration** (`tool/runner.py`):
- Before calling `_env_resolver.resolve()`, checks `spec.execution_environment.mode`:
  - REQUIRED: raises `ContainerUnavailableError` if resolved env is not CONTAINER
  - PREFERRED: tries container, gracefully falls back to host
  - SPECIFIC: overrides `tool_env` with `target_resource`
  - NONE: current behavior (caller-supplied tool_env)

### Tests

- **27 Behave scenarios** covering model validation, serialization, preference routing, YAML parsing, error cases
- **12 Robot integration tests** covering CLI tool preference display and end-to-end routing

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,833 scenarios) |
| `nox -s integration_tests` | PASS (12 new tests) |

Closes #879

Reviewed-on: cleveragents/cleveragents-core#970
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-20 23:51:46 +00:00
brent.edwards 4f950a1600 feat(cli): repo indexing CLI functional (#982)
## Summary

Add `agents repo index` and `agents repo status` CLI commands, wiring the existing `RepoIndexingService` backend to the CLI layer.

### Commands

- **`agents repo index <resource_name>`** — Triggers full or incremental indexing of a repository resource. Options: `--full` (force full re-index), `--format text|json`
- **`agents repo status <resource_name>`** — Displays indexing metadata: status, file count, token estimate, primary language, last indexed timestamp. Options: `--format text|json`

### Implementation

- New CLI module `src/cleveragents/cli/commands/repo.py` (238 lines)
- Registered as `repo` subcommand group in `cli/main.py`
- Resolves resource by name via `ResourceRegistryService`
- Calls `RepoIndexingService.index_resource()` / `refresh_index()` / `get_index_status()`
- Both text (Rich panel) and JSON output formats

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,819 scenarios) |
| `nox -s coverage_report` | 98% (>= 97%) |
| Integration tests | 5/5 PASS |

Closes #856

Reviewed-on: cleveragents/cleveragents-core#982
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-20 22:28:32 +00:00
freemo 051ee7c290 test(coverage): add Behave BDD tests to improve coverage across 52 source files
Added 52 new .feature files and corresponding _steps.py files targeting
previously uncovered code paths in the following areas:

- TUI layer: app, commands, persona (state/schema/registry), widgets,
  input (shell_exec, reference_parser)
- Application services: plan lifecycle/service/executor, session,
  project, repo indexing, correction, checkpoint, actor, llm_actors,
  strategy coordinator, resource file watcher, service retry wiring
- CLI commands: session, resource, repl, plan, db, automation_profile
- Domain models: retry_policy, resource_type, cost_budget,
  docker_compose_analyzer, detail_level, _sql_string_aware,
  _postgresql_helpers
- Core: circuit_breaker, retry_service_patterns
- Infrastructure: repositories, transaction_sandbox, strategy_registry,
  plugins/loader, container
- Config: settings
- Agents: plan_generation, context_analysis, auto_debug
- A2A: facade

All new tests follow the Behave/Gherkin BDD standard. Resolved step
definition collisions with unique prefixes. Fixed Alembic fileConfig
logger disabling issue (disable_existing_loggers=False).

ISSUES CLOSED: #1068
2026-03-20 21:22:10 +00:00
CoreRasurae d206b0c5e6 ci: Use docker-benchmark runner for benchmark-publish job
Job takes more time to run,  needing a dedicated runner

ISSUES CLOSED: #1083
2026-03-20 19:33:18 +00:00
salcedo b153e4a0fc Merge pull request 'ci: Use docker-benchmark runner for benchmark-regression jon' (#1082) from ci/fix-ci into master
Reviewed-on: cleveragents/cleveragents-core#1082
Reviewed-by: Brian Salcedo <salcedo@noreply.git.cleverthis.com>
2026-03-20 18:10:26 +00:00
CoreRasurae 2809b72b48 ci: Use docker-benchmark runner for benchmark-regression jon
Job takes longes and uses a dedicated runner

ISSUES CLOSED: #1081
2026-03-20 17:23:16 +00:00
brent.edwards 79b0a2c52e chore(cli): complete renderer migration for remaining command modules (#1059)
## Summary

Migrates 8 CLI command modules from module-level `Console()` objects to the shared `_get_console()` from `renderers.py`. This eliminates redundant Console instances and ensures consistent output handling across all CLI commands.

### Modules Migrated

| Module | Change |
|--------|--------|
| `auto_debug.py` | `Console()` → `_get_console()` |
| `context.py` | `Console()` → `_get_console()` |
| `automation_profile.py` | `Console()` → `_get_console()` |
| `tool.py` | `Console()` → `_get_console()` |
| `project.py` | Both stdout + stderr Console → shared instances |
| `config.py` | `Console()` → `_get_console()` |
| `resource.py` | `Console()` → `_get_console()` |
| `skill.py` | `Console()` → `_get_console()` |

### Approach

Each module-level `console = Console()` was replaced with `console = _get_console()`, keeping the module attribute name `console` intact for backward compatibility with existing test patches. The `from rich.console import Console` import was removed from each module.

Modules NOT migrated in this PR (documented for follow-up):
- `plan.py` — uses streaming/Live display, too large for this scope
- `session.py`, `repl.py`, `lsp.py`, `server.py` — specialized usage patterns

### Quality Gates

| Session | Result |
|---------|--------|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| Unit tests (targeted) | All affected scenarios pass |

Partial implementation of #813 (step 2 of 4: Console consolidation). Steps 1, 3, 4 remain open on issue #813.

Reviewed-on: cleveragents/cleveragents-core#1059
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-19 23:30:55 +00:00
brent.edwards 714d799ae9 feat(examples/actors/code_review.yaml): add a new code review tool (#458)
## Summary

Add a `code_review.yaml` actor example that uses Claude Opus 4 with file and git tools to perform automated code reviews against the project's review playbook.

### Changes
- **New file**: `examples/actors/code_review.yaml` — LLM actor configured with `files/read_file`, `files/list_directory`, and `builtin/git-*` tools, with a system prompt that reads `docs/development/review-playbook.md` and diffs against `master`
- **Updated**: `features/actor_examples.feature` — bumped example count from 7 to 8 and added `code_review.yaml` to the file listing assertion

### Verification
- `nox -e lint` — passed
- `nox -e typecheck` — 0 errors
- `nox -e format -- --check` — all files formatted
- `nox -s unit_tests -- features/actor_examples.feature` — 25 scenarios passed

### Rebase Notes
- Rebased onto current master (`4d3499dc`)
- Squashed 2 commits into 1 (eliminated 3 merge commits)
- Resolved conflict in `actor_examples.feature`: master added `strategy_with_subplan.yaml` (count 7), our branch adds `code_review.yaml` (count now 8)

Reviewed-on: cleveragents/cleveragents-core#458
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-19 22:42:15 +00:00
brent.edwards 202c9bfe75 test(acms): TDD failing tests for context tier runtime logic (bug #821) (#1058)
## Summary

TDD expected-fail tests proving bug #821 exists: `ContextTierService` has data models for hot/warm/cold tiers but **no runtime logic** for automatic promotion, demotion, or eviction.

- **Promotion on access**: Accessing a cold-tier fragment repeatedly via `get()` does NOT auto-promote it — `get()` updates `access_count`/`last_accessed` but never calls `promote()`
- **Demotion on staleness**: No staleness enforcement method exists — tried `enforce_staleness()`, `apply_tier_policy()`, `tick()`, etc. — none are implemented
- **Eviction on budget overflow**: `store()` does NOT enforce `TierBudget.max_tokens_hot` — the hot tier grows without bound

### Files Added
| File | Purpose |
|------|---------|
| `features/tdd_context_tier_runtime.feature` | 3 Behave scenarios tagged `@tdd_expected_fail @tdd_bug @tdd_bug_821 @mock_only` |
| `features/steps/tdd_context_tier_runtime_steps.py` | Type-annotated step definitions exercising real `ContextTierService` |
| `robot/tdd_context_tier_runtime.robot` | 3 Robot Framework integration tests tagged `tdd_expected_fail` |
| `robot/helper_tdd_context_tier_runtime.py` | Helper script for Robot tests with 3 subcommands |

### Verification
- `nox -s lint` — passed
- `nox -s typecheck` — passed (0 errors)
- `nox -s unit_tests -- features/tdd_context_tier_runtime.feature` — **3 scenarios passed** (all assertions fail as expected, `@tdd_expected_fail` inverts to CI pass)

ISSUES CLOSED: #840

Reviewed-on: cleveragents/cleveragents-core#1058
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-19 22:24:41 +00:00
brent.edwards 60af2cae0c fix(cli): make plan explain accept plan_id for plan-level explanation (#1057)
## Summary

Fixes `plan explain` to accept both decision IDs and plan IDs as the positional argument, matching the M3 acceptance test usage pattern `plan explain <plan_id>`.

### Problem
`explain_decision_cmd` only accepted a decision ULID. When the M3 acceptance test passed a plan ID, `svc.get_decision(plan_id)` returned `None`, causing "Decision not found" error with exit code 1.

### Fix
1. Renamed parameter `decision_id` → `identifier`
2. Tries `svc.get_decision(identifier)` first (backward compat)
3. Falls back to `svc.list_decisions(identifier)` treating it as a plan_id, explaining the root decision
4. Clear error if neither resolves

### Quality Gates
| Session | Result |
|---------|--------|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` (explain features) | 46/46 PASS |

Closes #968

Reviewed-on: cleveragents/cleveragents-core#1057
Co-authored-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent Edwards <brent.edwards@cleverthis.com>
2026-03-19 22:10:23 +00:00
brent.edwards 81e220980b Merge pull request 'fix(cli): restore phase-aware execution in plan execute command' (#1056) from bugfix/m3-plan-execute-phase-processing into master
Reviewed-on: cleveragents/cleveragents-core#1056
2026-03-19 21:45:23 +00:00
brent.edwards 35e1807f95 fix(cli): restore phase-aware execution in plan execute command
Consolidate the execute_plan CLI handler to eliminate a redundant
service.get_plan() call (the separate read-only pre-check now
reuses the same current_plan reference used for phase detection),
update the command-table description from the stale 'Transition to
Execute phase' to 'Run phase-aware plan execution', and replace
the static post-execution hint with a state-aware message that
distinguishes execute/complete (ready for apply) from other states
(continue executing).

Update corresponding Behave test mocks to match the reduced
get_plan call sequence and the updated output panel title.

ISSUES CLOSED: #967
2026-03-19 21:13:01 +00:00
freemo 2413b97c52 Docs: Daily update to timeline 2026-03-19 10:58:11 -04:00
hamza.khyari 15728a0f0a Merge pull request 'feat(resource): add deferred physical resource types' (#662) from feature/post-resource-types-physical into master
Reviewed-on: cleveragents/cleveragents-core#662
Reviewed-by: Aditya Chhabra <aditya.chhabra@cleverthis.com>
2026-03-19 14:12:44 +00:00
hamza.khyari e2f90ffcd5 feat(resource): add deferred physical resource types
Add 11 deferred physical resource types covering the git object taxonomy
(git, git-remote, git-branch, git-tag, git-commit, git-tree, git-tree-entry,
git-stash, git-submodule) and filesystem link types (fs-symlink, fs-hardlink).

- YAML configs under examples/resource-types/
- Bootstrap registration via _resource_registry_physical.py module
- Auto-discovery rules with bounded scan_depth (1-2) for git object graph
- fs-directory scan_depth=1 (immediate children only)
- git-branch scan_depth=1 (single HEAD), git-tree scan_depth=2 (capped)
- Updated fs-directory child_types/parent_types/auto_discovery
- Updated git-checkout child_types to include git
- Fixed git-tag child_types to include git-commit (DAG consistency)
- Behave tests, Robot tests, ASV benchmarks
- Documentation in docs/reference/resource_types_builtin.md

ISSUES CLOSED: #330
2026-03-19 14:03:17 +00:00