Commit Graph

2746 Commits

Author SHA1 Message Date
freemo 642eb276a8 chore(agents): add mandatory labels to supervisor tracking issue creation
CI / lint (pull_request) Successful in 22s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 1m3s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 27s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m43s
CI / e2e_tests (pull_request) Successful in 21m0s
CI / integration_tests (pull_request) Successful in 23m6s
CI / docker (pull_request) Successful in 11s
CI / coverage (pull_request) Successful in 10m49s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m45s
Add label requirements to all 16 supervisor launch prompts in
product-builder.md so that any tracking issues created by supervisors
include the required Type/Automation, State/In Progress, and
Priority/Medium labels from creation.

This eliminates the persistent label compliance gap reported by the
system watchdog, where supervisor-created tracking issues consistently
missed required State/ and Priority/ labels.

ISSUES CLOSED: #3070
2026-04-05 17:54:12 +00:00
freemo f5d244cd37 fix(a2a): change A2aErrorDetail.code to int and map error constants to JSON-RPC 2.0 integer codes
CI / lint (pull_request) Failing after 30s
CI / typecheck (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 46s
CI / security (pull_request) Successful in 53s
CI / coverage (pull_request) Has been skipped
CI / helm (pull_request) Successful in 23s
CI / build (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 6m30s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 18m51s
CI / integration_tests (pull_request) Successful in 23m20s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
Per JSON-RPC 2.0 specification (Section 5.1), error codes must be integers.
This commit fixes the protocol compliance defect where A2aErrorDetail.code
was typed as str and error constants were string literals.

Changes:
- src/cleveragents/a2a/models.py: Change A2aErrorDetail.code from str to int;
  update field_validator to only validate 'message' (code no longer needs
  non-empty string check; Pydantic enforces int type)
- src/cleveragents/a2a/errors.py: Change all error code constants from string
  literals to JSON-RPC 2.0 integer codes per docs/reference/a2a.md taxonomy:
    NOT_FOUND = -32001, AUTH_ERROR = -32002, FORBIDDEN = -32003,
    INVALID_STATE = -32004, PLAN_ERROR = -32008, CONFIGURATION_ERROR = -32009,
    VALIDATION_ERROR = -32602, INTERNAL_ERROR = -32603
  Update map_domain_error() return type from tuple[str, str] to tuple[int, str]
- features/steps/a2a_facade_steps.py: Update A2aErrorDetail construction to
  map symbolic string names to integer codes via _CODE_MAP
- features/steps/a2a_facade_wiring_steps.py: Update error code assertion to
  map symbolic names to integers for comparison
- features/steps/a2a_facade_coverage_boost_steps.py: Same as above
- features/steps/a2a_jsonrpc_wire_format_steps.py: Update all A2aErrorDetail
  constructions and JSON-RPC dict payloads to use integer codes
- robot/helper_a2a_facade_wiring.py: Update wired_error_mapping() to compare
  against integer codes
- robot/helper_a2a_jsonrpc_wire_format.py: Update response_error_wire_format()
  to use integer code -32001 instead of string 'NOT_FOUND'

Wire format now produces {"code": -32001, ...} instead of {"code": "NOT_FOUND", ...},
making it compliant with JSON-RPC 2.0 and interoperable with standards-conformant clients.

ISSUES CLOSED: #2746
2026-04-05 17:53:56 +00:00
freemo 32b352832f fix(cli): replace manual DI wiring in _get_tool_registry_service with container resolution
CI / lint (pull_request) Successful in 24s
CI / typecheck (pull_request) Successful in 54s
CI / security (pull_request) Successful in 56s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 30s
CI / unit_tests (pull_request) Successful in 7m1s
CI / e2e_tests (pull_request) Successful in 17m45s
CI / integration_tests (pull_request) Successful in 22m56s
CI / coverage (pull_request) Successful in 11m4s
CI / docker (pull_request) Successful in 1m21s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m51s
_get_tool_registry_service in cli/commands/validation.py was manually
constructing the full ToolRegistryService dependency graph (create_engine,
sessionmaker, ToolRegistryRepository, ValidationAttachmentRepository) instead
of delegating to the DI container. This duplicated wiring logic that belongs
exclusively in the container and made the function harder to test.

Changes:
- Add _build_tool_registry_service() builder function to container.py
  following the established _build_skill_service/_build_session_service pattern
- Register tool_registry_service as a Singleton provider in the Container class
- Refactor _get_tool_registry_service() to delegate to
  container.tool_registry_service() — a one-liner consistent with
  _get_skill_service() in cli/commands/skill.py
- Add TDD Behave feature (tdd_di_tool_registry_service.feature) with two
  scenarios: (1) function delegates to container, (2) container exposes the
  provider — both scenarios were failing before this fix
- Update validation_cli_uncovered_branches_steps.py to match the new
  container-delegation pattern (mock container.tool_registry_service()
  instead of container.database_url())

ISSUES CLOSED: #3006
2026-04-05 17:52:59 +00:00
freemo 8d49a3b242 fix(tui): add plain text format support to session export command
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 1m4s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 18s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m0s
CI / e2e_tests (pull_request) Successful in 15m25s
CI / integration_tests (pull_request) Successful in 23m13s
CI / coverage (pull_request) Successful in 11m18s
CI / docker (pull_request) Successful in 1m29s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m57s
Add plain text (txt) export format to the TUI /session:export command.

- Add Session.as_export_plain_text() domain method that produces a
  human-readable plain text transcript without Markdown formatting
- Update TuiCommandRouter._session_export() to accept 'txt' as a valid
  format, building the plain text content via as_export_plain_text()
- Update the invalid-format error message to include 'txt' as a valid
  option alongside 'json' and 'md'
- Add BDD scenarios covering plain text export via TUI command and
  domain model, including with-messages and no-messages cases
- Add corresponding step definitions for the new BDD scenarios

The plain text format uses a simple separator-based layout:
  Session: <id>
  Actor: <actor>
  ...
  ----------------------------------------
  [0] USER (timestamp):
  message content
  ----------------------------------------

ISSUES CLOSED: #3036
2026-04-05 17:52:30 +00:00
freemo 0f9ca00ce7 fix(tui): show command descriptions in SlashCommandOverlay alongside command names
CI / lint (pull_request) Successful in 20s
CI / typecheck (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 37s
CI / security (pull_request) Successful in 59s
CI / build (pull_request) Successful in 38s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Failing after 7m1s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 16m16s
CI / integration_tests (pull_request) Failing after 23m13s
CI / coverage (pull_request) Successful in 11m18s
CI / status-check (pull_request) Failing after 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m54s
Update SlashCommandOverlay.set_commands() to accept list[SlashCommandSpec]
instead of list[str], and render each entry as aligned columns:
  /command-name       Description text

Changes:
- slash_command_overlay.py: update set_commands() signature to accept
  list[SlashCommandSpec]; render name + description with aligned padding
  using _COMMAND_COL_WIDTH = 28 characters for the name column
- slash_catalog.py: add slash_command_specs() helper returning all specs
- app.py: switch on_mount() to call slash_command_specs() instead of
  slash_command_names() so full spec objects are passed to the overlay
- features/tui_slash_command_overlay_coverage.feature: add scenario
  verifying description rendering; update existing scenarios to use
  SlashCommandSpec objects via _make_specs() helper
- features/steps/tui_slash_command_overlay_coverage_steps.py: update
  step implementations to build SlashCommandSpec objects from CSV names
- features/tui_slash_overlay_descriptions.feature: new feature file with
  BDD scenarios covering description rendering and @tdd_expected_fail
  capture of the pre-fix name-only behaviour
- features/steps/tui_slash_overlay_descriptions_steps.py: step defs for
  the new feature file
- robot/tui_smoke.robot: add Slash Command Overlay Renders Descriptions
  integration test verifying descriptions appear in rendered overlay

ISSUES CLOSED: #3437
2026-04-05 17:50:51 +00:00
freemo abf250901f fix(tool): implement tool_type filter in ToolRegistry.list_tools()
CI / lint (pull_request) Successful in 21s
CI / quality (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 1m1s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 53s
CI / unit_tests (pull_request) Failing after 2m4s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m4s
CI / integration_tests (pull_request) Successful in 23m32s
CI / coverage (pull_request) Failing after 2m7s
CI / status-check (pull_request) Failing after 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m42s
The tool_type parameter in ToolRegistry.list_tools() was explicitly
silenced with '_ = tool_type', making it a no-op. Both
'agents tool list --type validation' and 'agents tool list --type tool'
returned the full unfiltered tool list.

Changes:
- src/cleveragents/tool/runtime.py: Add tool_type: Literal['tool',
  'validation'] field to ToolSpec (default 'tool') so the registry
  has a discriminator to filter on.
- src/cleveragents/tool/registry.py: Remove '_ = tool_type' no-op and
  implement actual filter: specs = [s for s in specs if s.tool_type == tool_type].
  Update docstring to reflect the parameter is now active.
- features/consolidated_tool.feature: Add 7 comprehensive Behave
  scenarios covering all filter combinations (tool, validation, None,
  default type, exclusion).
- features/steps/tool_runtime_steps.py: Add step definition for
  registering a ToolSpec with an explicit tool_type.
- robot/helper_tool_cli.py: Add tool_list_type_tool() and
  tool_list_type_validation() helper functions that verify the CLI
  passes tool_type through to the service layer.
- robot/tool_cli.robot: Add two Robot test cases for
  'tool list --type tool' and 'tool list --type validation'.

The CLI handler (cli/commands/tool.py) and database repository
(infrastructure/database/repositories.py) already passed tool_type
through correctly — no changes needed there.

ISSUES CLOSED: #2974
2026-04-05 17:49:35 +00:00
freemo dd09fadf29 fix(exceptions): replace Any with str | os.PathLike | None for FileSystemError.path
CI / lint (pull_request) Successful in 29s
CI / quality (pull_request) Successful in 35s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 55s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 35s
CI / unit_tests (pull_request) Successful in 6m49s
CI / e2e_tests (pull_request) Successful in 18m32s
CI / integration_tests (pull_request) Successful in 23m18s
CI / coverage (pull_request) Successful in 11m1s
CI / docker (pull_request) Successful in 1m35s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m58s
Narrow the path parameter type hint in FileSystemError.__init__ from Any to
str | os.PathLike[str] | None. This improves static analysis accuracy since
path is semantically a filesystem path, not an arbitrary value.

Changes:
- Add import os to exceptions.py
- Replace path: Any = None with path: str | os.PathLike[str] | None = None
- Reformat __init__ signature to multi-line for line-length compliance
- Audit call-sites (context_service.py, project_service.py): both pass
  pathlib.Path which implements os.PathLike[str], no changes needed
- Add BDD feature file covering str, pathlib.Path, None, and annotation check
- Add corresponding step definitions

ISSUES CLOSED: #3034
2026-04-05 17:49:20 +00:00
freemo 89c215e62c fix(cli): render spec-required panels in agents plan rollback rich output
CI / lint (pull_request) Successful in 26s
CI / build (pull_request) Successful in 39s
CI / quality (pull_request) Successful in 45s
CI / typecheck (pull_request) Successful in 50s
CI / security (pull_request) Successful in 1m2s
CI / helm (pull_request) Successful in 39s
CI / unit_tests (pull_request) Successful in 6m50s
CI / docker (pull_request) Successful in 1m22s
CI / coverage (pull_request) Successful in 10m47s
CI / e2e_tests (pull_request) Successful in 17m11s
CI / integration_tests (pull_request) Successful in 23m20s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m43s
Implemented a rich output upgrade for the agents plan rollback in the CLI by replacing the previous plain-text output in rollback_plan() with a set of four spec-required Rich panels.

- Rollback Summary panel: includes Plan, Checkpoint, Label (only if available), and Files fields.

- Changes Reverted panel: a Rich table with File and Action columns; supports both dict entries and plain string paths for forward compatibility with issue #2454.

- Impact panel: shows Sandbox state and optional fields Child Plans Invalidated, Decisions After CP, Tool Calls After CP.

- Post-Rollback State panel: includes Phase, State, and optional Checkpoints Remaining fields.

- Confirmation line: "✓ OK Rollback complete" displayed after the panels.

- Tests updated: Updated BDD test assertions in features/plan_cli_coverage_r2.feature to align with new panel-based output.

Key design decisions:

- Used getattr(result, field, None) pattern for optional fields not yet present in RollbackResult model (fields: label, child_plans_invalidated, decisions_after_cp, tool_calls_after_cp, phase, state, checkpoints_remaining) to support forward-compatibility as fields get added.

- Handling mixed formats in changed_paths/changes_reverted: both dict-format entries and string-format paths are supported to remain compatible with issue #2454.

- Sandbox state defaults to "restored to {checkpoint_id}" when not explicitly provided.

Files changed:

- src/cleveragents/cli/commands/plan.py (rollback_plan rich output section)

- features/plan_cli_coverage_r2.feature (updated test assertions)

ISSUES CLOSED: #2591
2026-04-05 17:35:35 +00:00
freemo 1783f0a211 docs(timeline): update schedule adherence Day 95 final v3 (2026-04-05)
CI / benchmark-publish (push) Waiting to run
CI / lint (push) Successful in 25s
CI / quality (push) Successful in 45s
CI / build (push) Successful in 22s
CI / typecheck (push) Successful in 50s
CI / security (push) Successful in 51s
CI / benchmark-regression (push) Waiting to run
CI / helm (push) Successful in 45s
CI / unit_tests (push) Successful in 6m33s
CI / docker (push) Successful in 11s
CI / coverage (push) Successful in 10m44s
CI / lint (pull_request) Successful in 19s
CI / e2e_tests (push) Successful in 17m37s
CI / quality (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 51s
CI / build (pull_request) Successful in 27s
CI / helm (pull_request) Successful in 26s
CI / integration_tests (push) Successful in 22m56s
CI / status-check (push) Waiting to run
CI / unit_tests (pull_request) Successful in 7m25s
CI / coverage (pull_request) Successful in 10m57s
CI / e2e_tests (pull_request) Successful in 18m14s
CI / integration_tests (pull_request) Successful in 23m26s
CI / docker (pull_request) Successful in 11s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m45s
Final Day 95 timeline update (v3) with current Forgejo data as of 2026-04-05.

Key Changes:
- Open PRs: 92 → 170 (+78 new PRs from agent-driven activity)
- Open bugs: 536 → 809 (+273 new bugs from UAT/bug-hunt agents)
- Total open issues: 1547
- Session tracker: updated to #3377
- Milestone completions updated (all declined due to agent-driven issue creation outpacing closures)
- Gantt chart footer, update log, and both legend blocks updated
- Current Status Summary, Schedule Risk Summary, and Day 95 adherence entry all updated with final data
- New UAT bugs noted: #3444 (TUI HelpPanelOverlay keybinding mismatch), #3445 (plan rollback Rich output format incomplete)

Supersedes PR #3419 (docs/timeline-day95-v2) which had intermediate data.

Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
2026-04-05 17:29:50 +00:00
freemo f945e15572 fix(agents): Fix issue-implementor supervisor to properly manage N parallel workers
CI / benchmark-publish (push) Waiting to run
CI / helm (push) Successful in 27s
CI / build (push) Successful in 27s
CI / lint (push) Successful in 51s
CI / quality (push) Successful in 52s
CI / typecheck (push) Successful in 1m6s
CI / security (push) Successful in 1m7s
CI / benchmark-regression (push) Waiting to run
CI / unit_tests (push) Successful in 6m49s
CI / docker (push) Successful in 11s
CI / coverage (push) Successful in 10m25s
CI / e2e_tests (push) Successful in 17m17s
CI / integration_tests (push) Successful in 22m17s
CI / status-check (push) Successful in 1s
The issue-implementor supervisor was defining but not using its worker dispatch
logic, causing it to run only 1 worker at a time instead of the configured N
parallel workers. This fix implements proper pool supervision:

- Implement sliding window dispatch pattern to maintain N active workers
- Use curl with prompt_async for asynchronous worker launches
- Track PR workers and issue workers separately with proper monitoring
- Add explicit worker count reporting in health signals (X/Y format)
- Integrate PR priority gate - no new issues until all PRs have workers
- Fix session monitoring and cleanup for completed/failed workers
- Update product-builder heartbeat to show worker pool status

The supervisor now continuously fills empty worker slots for maximum throughput,
properly managing up to CA_MAX_PARALLEL_WORKERS parallel workers as designed.

ISSUES CLOSED: #1
2026-04-05 16:50:47 +00:00
freemo 67b48ee817 feat!: restructure PR workflow to keep implementors accountable through merge
CI / benchmark-publish (push) Waiting to run
CI / lint (push) Successful in 25s
CI / build (push) Successful in 31s
CI / helm (push) Successful in 42s
CI / quality (push) Successful in 44s
CI / typecheck (push) Successful in 50s
CI / security (push) Successful in 1m0s
CI / benchmark-regression (push) Waiting to run
CI / unit_tests (push) Successful in 6m33s
CI / docker (push) Successful in 1m19s
CI / coverage (push) Successful in 10m19s
CI / e2e_tests (push) Successful in 17m25s
CI / integration_tests (push) Successful in 22m34s
CI / status-check (push) Successful in 1s
BREAKING CHANGE: This completely changes how PRs are handled in the system.
Implementors now own their work from creation through merge, and reviewers
focus solely on code quality assessment.

Major changes:
- issue-implementor: Adds absolute PR prioritization - no new issues until
  all PRs have workers. Dispatches workers in two modes: 'pr-fix' for
  existing PRs and 'issue-impl' for new issues.

- ca-issue-worker: Now operates in dual mode. In 'pr-fix' mode, handles
  review feedback, CI fixes, and merging. In 'issue-impl' mode, no longer
  exits after PR creation - monitors the PR until merged.

- ca-continuous-pr-reviewer: Simplified to ONLY dispatch code reviewers.
  Removed all fix, merge, and lifecycle management. Uses dynamic review
  focus areas to catch different types of issues.

- ca-pr-self-reviewer: Removed ALL capabilities beyond code review. No
  longer fixes issues, merges PRs, or manages issue states. Provides
  actionable feedback using rotating focus areas.

- ca-pr-checker: Clarified that it should only be invoked by ca-issue-worker,
  not by reviewers.

Benefits:
- No PR backlogs (absolute priority over new issues)
- Full accountability (creator owns through merge)
- Better reviews (focused on quality, not mechanics)
- Context preservation (no handoffs between agents)
- Cleaner history (amendments instead of fix commits)

This ensures implementors are accountable for their work while reviewers
provide high-quality, focused code reviews without operational overhead.
2026-04-05 16:10:01 +00:00
freemo a887712473 fix(agents): reduce health signal spam, add story point estimation, and improve supervisor monitoring
CI / benchmark-publish (push) Waiting to run
CI / build (push) Successful in 23s
CI / helm (push) Successful in 24s
CI / lint (push) Successful in 40s
CI / quality (push) Successful in 47s
CI / typecheck (push) Successful in 53s
CI / security (push) Successful in 55s
CI / benchmark-regression (push) Waiting to run
CI / unit_tests (push) Successful in 6m29s
CI / docker (push) Successful in 11s
CI / coverage (push) Successful in 10m25s
CI / e2e_tests (push) Successful in 16m37s
CI / integration_tests (push) Successful in 22m27s
CI / status-check (push) Successful in 1s
- Health Signal Frequency: Fixed spam from ca-test-infra-improver, ca-bug-hunter,
  and ca-uat-tester by changing health signals from every 2-10 cycles to every
  60 cycles (~10 min intervals)

- Story Point Assignment: Added automatic story point estimation to ca-project-owner
  and ca-human-liaison during issue verification based on subtask count and
  complexity (XS:1, S:2, M:3, L:5, XL:8, XXL:13)

- Deep Supervisor Inspection: Enhanced product-builder to check pool supervisors
  every 5 heartbeats for actual worker activity, detecting zombie supervisors that
  are running but not dispatching workers

- Watchdog Integration: Added watchdog alert monitoring to product-builder that
  checks for critical alerts every 3 heartbeats and takes action based on severity

- Alert Format Standardization: Updated ca-system-watchdog to use structured
  key-value alert format for easier parsing by product-builder

Fixes issues with excessive Forgejo API usage, missing story point assignments
during triage, and improves overall system reliability through better monitoring.
2026-04-05 15:32:04 +00:00
freemo cce207a7bb fix: improve agent coordination with PR prioritization and unified status tracking
CI / benchmark-publish (push) Waiting to run
CI / helm (push) Successful in 23s
CI / lint (push) Successful in 27s
CI / build (push) Successful in 32s
CI / quality (push) Successful in 33s
CI / typecheck (push) Successful in 1m7s
CI / security (push) Successful in 1m8s
CI / benchmark-regression (push) Waiting to run
CI / unit_tests (push) Successful in 6m37s
CI / docker (push) Successful in 21s
CI / coverage (push) Successful in 10m13s
CI / e2e_tests (push) Successful in 17m15s
CI / integration_tests (push) Successful in 21m50s
CI / status-check (push) Successful in 1s
This commit addresses two critical issues in the CleverAgents autonomous system:

1. Pull Request Bottleneck:
   - Added PR prioritization gate to issue-implementor that checks for open PRs before taking new issues
   - Implementation pool now pauses new issue work when PRs need attention (failing CI, awaiting review, stale)
   - Re-checks PR status every 5 cycles to ensure PRs don't accumulate
   - Posts clear status updates explaining why new work is paused

2. Status Issue Proliferation:
   - Product-builder now creates ONE canonical session state issue: '[Automated] CleverAgents Build Session - <date>'
   - All 16 supervisors receive the session state issue number and post ALL status updates there
   - Removed separate tracking issue creation from ca-uat-tester and other agents
   - Standardized health signal format across all agents for consistent monitoring

The standardized health signal format enables system-watchdog to:
- Detect zombie supervisors from a single issue
- Monitor active workers per pool
- Track work progress across all agents
- Identify stuck or inactive agents

Modified agents:
- issue-implementor: Added PR prioritization gate
- product-builder: Single session state issue management
- All pool supervisors: Updated to use session state issue
- All agents: Standardized health signal format

These changes ensure PRs get merged quickly and reduce issue tracker noise.
2026-04-05 14:54:22 +00:00
freemo 0d4a47f3c0 fix(config): align Settings and alembic/env.py database_url defaults to spec-required ~/.cleveragents/cleveragents.db
CI / lint (pull_request) Successful in 20s
CI / typecheck (pull_request) Successful in 46s
CI / quality (pull_request) Successful in 44s
CI / security (pull_request) Successful in 52s
CI / build (pull_request) Successful in 24s
CI / helm (pull_request) Successful in 22s
CI / unit_tests (pull_request) Successful in 6m37s
CI / e2e_tests (pull_request) Successful in 17m48s
CI / integration_tests (pull_request) Successful in 22m31s
CI / docker (pull_request) Successful in 1m24s
CI / coverage (pull_request) Successful in 10m26s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m45s
- Fix Settings.database_url default from relative 'sqlite:///cleveragents.db'
  to absolute 'sqlite:////home/<user>/.cleveragents/cleveragents.db' using
  Path.home() / '.cleveragents' / 'cleveragents.db'
- Fix test_database_url default similarly to use ~/.cleveragents/cleveragents_test.db
- Fix alembic/env.py fallback default from Path.cwd() / '.cleveragents' / 'db.sqlite'
  to Path.home() / '.cleveragents' / 'cleveragents.db' (matching Settings)
- Both Settings and alembic/env.py now resolve to the same absolute path
- CLEVERAGENTS_DATABASE_URL env var override still works correctly in both
- Update coverage_boost_steps.py assertions to match new correct defaults
- Add 3 new Behave scenarios covering correct database_url default and env var override

ISSUES CLOSED: #2871
2026-04-05 10:17:24 +00:00
freemo a1fb804f21 fix(cli): correct automation-profile list output structure and rich table rendering
CI / lint (pull_request) Failing after 28s
CI / typecheck (pull_request) Successful in 3m59s
CI / build (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 3m43s
CI / security (pull_request) Successful in 4m9s
CI / coverage (pull_request) Has been skipped
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 9m52s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 21m7s
CI / integration_tests (pull_request) Successful in 25m52s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
The non-rich output branch of list_profiles() in
src/cleveragents/cli/commands/automation_profile.py has been refactored
to produce the spec-required envelope rather than a flat list of full
profile objects. The new envelope structure is:
  {"profiles": [...simplified...], "summary": {"built_in": N, "custom": N, "total": N}}
Where profiles entries now contain only five fields: name, source,
select_tool, sandbox, and description.

Key changes:
- Profiles in the profiles array are reduced to match the exact spec
  (name, source, select_tool, sandbox, description). Full details are
  preserved for the show command via the existing _profile_spec_dict().
- The summary object aggregates counts after namespace/regex filtering
  so the numbers accurately reflect what is being displayed.
- The rich table column header renamed from 'Select Tool' to 'Auto-Apply'
  per spec line 16946, and a Summary panel is appended to the rich output
  showing Built-in / Custom / Total counts per spec lines 16959-16963.
- Behave feature file updated with new scenarios covering JSON/YAML output
  structure, rich table column header, and Summary panel.
- New step definitions include a comprehensive profiles-wrapper-with-summary
  step that validates the full spec-required structure.
- Robot Framework helper test_list_json() updated to validate the new dict
  structure with profiles wrapper and summary instead of the old flat list.

ISSUES CLOSED: #2064
2026-04-05 09:46:16 +00:00
freemo 9210fbce33 refactor(cli): deduplicate session list summary logic in list_sessions
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 46s
CI / security (pull_request) Successful in 1m1s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 16s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m4s
CI / e2e_tests (pull_request) Successful in 18m8s
CI / integration_tests (pull_request) Successful in 22m40s
CI / docker (pull_request) Successful in 1m19s
CI / coverage (pull_request) Successful in 10m36s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m8s
Refactor list_sessions to reuse the summary dict already computed by
_session_list_dict instead of recalculating total_msgs, sorted_sessions,
most_recent, and oldest independently.

The rich table summary panel now reads directly from data["summary"],
ensuring JSON and rich table output are always consistent and the
summary logic lives in exactly one place (_session_list_dict).

Add Behave feature (session_list_summary_dedup.feature) with 6 scenarios
verifying that JSON and rich table summary values are consistent across
all required fields: total, most_recent, oldest, total_messages, storage.

ISSUES CLOSED: #3046
2026-04-05 09:38:43 +00:00
freemo 56f424714c fix(tdd): replace non-standard @tdd_bug tags with @tdd_issue per CONTRIBUTING.md
CI / lint (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 52s
CI / quality (pull_request) Successful in 33s
CI / build (pull_request) Successful in 28s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m40s
CI / e2e_tests (pull_request) Successful in 17m40s
CI / integration_tests (pull_request) Successful in 23m10s
CI / coverage (pull_request) Successful in 10m58s
CI / docker (pull_request) Successful in 1m20s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m50s
Audit all feature files for non-compliant @tdd_bug tag usage and replace
with the CONTRIBUTING.md-specified @tdd_issue / @tdd_issue_<N> tags.

Three files were affected:

- features/tdd_actor_list_no_db_update.feature:
  @tdd_bug @tdd_bug_797 → @tdd_issue @tdd_issue_797
  (bug #797 is fixed; permanent regression guard, no @tdd_expected_fail)

- features/tdd_exec_env_resolution_precedence.feature:
  Removed duplicate @tdd_bug @tdd_bug_1080 tags; file already had the
  correct @tdd_issue @tdd_issue_1080 tags.

- features/tdd_use_action_automation_profile.feature:
  @tdd_bug @tdd_bug_1076 → @tdd_issue @tdd_issue_1076
  (bug #1076 is fixed in upstream; @tdd_expected_fail not needed)

Zero occurrences of @tdd_bug or @tdd_bug_<N> remain in features/.
All nox quality gates pass: lint   unit_tests  (14426 scenarios passed).

ISSUES CLOSED: #2779
2026-04-05 09:09:06 +00:00
freemo c1dca80bf2 fix(resource-type): require letter-start for namespace/name in _NAMESPACED_RE
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 47s
CI / quality (pull_request) Successful in 35s
CI / security (pull_request) Successful in 1m3s
CI / build (pull_request) Successful in 18s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m41s
CI / e2e_tests (pull_request) Successful in 18m1s
CI / integration_tests (pull_request) Successful in 22m59s
CI / docker (pull_request) Successful in 1m22s
CI / coverage (pull_request) Successful in 11m29s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m55s
Update _NAMESPACED_RE in resource_type.py and _resource_type_validation.py
to require both namespace and name components to start with a letter, consistent
with _BUILTIN_NAME_RE and the spec requirement that names start with a letter.

Previously, _NAMESPACED_RE used [a-zA-Z0-9] as the first character class,
allowing digit-starting names like '123abc/my-type'. Now uses [a-zA-Z] to
enforce letter-start for both components.

Also adds Behave scenarios covering rejection of digit-starting custom resource
type names and valid letter-starting names.

ISSUES CLOSED: #2983
2026-04-05 09:03:32 +00:00
freemo ffb67e15b9 Merge pull request 'chore(agents): add auto-rebase on conflict to PR reviewer pool supervisor' (#1411) from improvement/pr-reviewer-auto-rebase-on-conflict into master
CI / benchmark-publish (push) Waiting to run
CI / lint (push) Successful in 32s
CI / typecheck (push) Successful in 52s
CI / quality (push) Successful in 34s
CI / security (push) Successful in 1m5s
CI / benchmark-regression (push) Waiting to run
CI / build (push) Successful in 18s
CI / helm (push) Successful in 23s
CI / unit_tests (push) Successful in 7m4s
CI / e2e_tests (push) Successful in 17m34s
CI / integration_tests (push) Successful in 22m50s
CI / coverage (push) Successful in 10m4s
CI / docker (push) Successful in 21s
CI / status-check (push) Successful in 1s
2026-04-05 09:01:17 +00:00
freemo 9f62f9c9c8 fix(skills): replace get_tool() calls with get() in SkillRegistry validation methods
CI / lint (pull_request) Failing after 20s
CI / quality (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 46s
CI / security (pull_request) Successful in 55s
CI / coverage (pull_request) Has been skipped
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Failing after 6m45s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m43s
CI / integration_tests (pull_request) Successful in 22m51s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
SkillRegistry.validate_plan() and validate_skill() called the non-existent
ToolRegistry.get_tool() method, causing AttributeError at runtime. The correct
method is ToolRegistry.get(), which is already used by SkillRegistry.refresh().

Changes:
- Replace self._tool_registry.get_tool(entry.name) with self._tool_registry.get(entry.name)
  in validate_plan()
- Replace self._tool_registry.get_tool(ref) with self._tool_registry.get(ref)
  in validate_skill()
- Update Behave BDD tests to use mock.get instead of mock.get_tool
- Add new BDD scenarios covering validate_skill() happy path, not-found path,
  unregistered include path, and no-tool-registry path
- Remove stale get_tool mock setup from test helpers

ISSUES CLOSED: #2914
2026-04-05 08:59:59 +00:00
freemo c1ebacd1b9 fix(a2a): rename A2aErrorDetail.details to data per JSON-RPC 2.0 spec
CI / lint (pull_request) Successful in 27s
CI / typecheck (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 30s
CI / security (pull_request) Successful in 1m3s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 28s
CI / unit_tests (pull_request) Successful in 6m57s
CI / e2e_tests (pull_request) Successful in 18m7s
CI / integration_tests (pull_request) Successful in 22m32s
CI / docker (pull_request) Successful in 1m20s
CI / coverage (pull_request) Successful in 10m56s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m46s
The A2aErrorDetail model used a field named 'details' for the optional
error payload, but JSON-RPC 2.0 §5.1 and the project specification both
require this field to be named 'data'.

Changes:
- Rename A2aErrorDetail.details -> data in src/cleveragents/a2a/models.py
- Add TDD BDD scenarios to features/a2a_jsonrpc_wire_format.feature that
  verify A2aErrorDetail serializes with 'data' field (not 'details')
- Add corresponding step definitions in a2a_jsonrpc_wire_format_steps.py

No call sites used the 'details' keyword argument when constructing
A2aErrorDetail instances (all existing usages only set code and message),
so no other files required changes.

ISSUES CLOSED: #2745
2026-04-05 08:57:12 +00:00
freemo 0536035d24 fix(a2a): update A2aVersionNegotiator to support JSON-RPC version 2.0
CI / lint (pull_request) Successful in 30s
CI / typecheck (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 38s
CI / security (pull_request) Successful in 58s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 6m48s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m51s
CI / integration_tests (pull_request) Failing after 23m13s
CI / coverage (pull_request) Successful in 10m48s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m47s
Implemented changes to align the A2A version negotiation with JSON-RPC 2.0 as per the specification and updated the test suite accordingly.

What was implemented
- Updated A2aVersionNegotiator.CURRENT_VERSION from "1.0" to "2.0" in src/cleveragents/a2a/versioning.py
- Updated A2aVersionNegotiator.SUPPORTED_VERSIONS from ("1.0",) to ("2.0",) in src/cleveragents/a2a/versioning.py
- Updated 7 Behave scenarios in features/consolidated_misc.feature to reflect "2.0" as the supported version:
  - Negotiate supported version succeeds: now negotiates "2.0" instead of "1.0"
  - Negotiate unsupported version raises error: now uses "99.0" as the unsupported version (since "2.0" is now supported)
  - is_supported returns True for valid version: now checks "2.0" instead of "1.0"
  - get_current returns current version: now expects "2.0" instead of "1.0"
  - M6 smoke A2A version negotiation accepts 2.0: updated from "1.0" to "2.0"
  - M6 smoke A2A version negotiation rejects unsupported: now uses "99.0" instead of "2.0"
  - M6 smoke A2A version is_supported returns correct result: now checks "2.0" instead of "1.0"

Key design decisions
- The A2A protocol is built on JSON-RPC 2.0 per the specification. The version negotiator must be consistent with JSONRPC_VERSION = "2.0" in models.py.
- "1.0" is removed from SUPPORTED_VERSIONS as there is no backward compatibility requirement for the old version in the spec.
- All tests updated to reflect the corrected behavior.

Impacted modules/components
- src/cleveragents/a2a/versioning.py
- features/consolidated_misc.feature
- Behavioral tests referencing A2A version negotiation

ISSUES CLOSED: #2747
2026-04-05 08:52:19 +00:00
freemo 884fe12511 ```
CI / lint (pull_request) Failing after 32s
CI / typecheck (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 44s
CI / security (pull_request) Successful in 1m0s
CI / coverage (pull_request) Has been skipped
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 7m31s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 19m8s
CI / integration_tests (pull_request) Failing after 23m22s
CI / status-check (pull_request) Failing after 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
fix(tool): wire 6-level execution environment precedence chain into ToolRunner

What was implemented
- Updated ToolRunner.execute() to accept plan_priority and project_priority parameters (optional) and to propagate these priority values through the execution path.
- Replaced the legacy four-level resolve_and_validate() with resolve_with_precedence() to implement the correct six-level precedence chain.
- Introduced devcontainer_available derived from has_devcontainer() on linked_resource_types and wired this into the resolution process.
- Updated all call sites (router.py and actor_runtime.py) to accept and forward the new priority parameters.
- Added 12 unit tests verifying the six-level precedence chain behavior in ToolRunner.execute().
- Added integration tests covering override vs. fallback scenarios to ensure correct end-to-end behavior.

Key design decisions and rationale
- Use resolve_with_precedence() instead of resolve_with_dag() because linked_resource_types already provides devcontainer availability information, eliminating the need for a full DAG walk while preserving correct precedence semantics.
- Preserve the existing contract of raising ContainerUnavailableError by retaining a final validate_container_available() call after resolution, ensuring proper error signaling when a container is resolved but no linked container resource exists.
- Make plan_priority and project_priority optional with None defaulting to fallback semantics, aligning with the resolver's _parse_priority() behavior and keeping backward-compatible defaults for existing callers.

ISSUES CLOSED: #2592
```
2026-04-05 08:47:35 +00:00
freemo faf7991a13 fix(domain): add repository protocol interfaces to domain layer
CI / lint (pull_request) Failing after 21s
CI / typecheck (pull_request) Successful in 52s
CI / security (pull_request) Successful in 1m1s
CI / quality (pull_request) Successful in 34s
CI / coverage (pull_request) Has been skipped
CI / build (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 6m24s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m20s
CI / integration_tests (pull_request) Successful in 23m6s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
Implemented domain-level repository protocol interfaces to restore clean
architecture boundaries and enable robust type checks via runtime
structural typing.

- Created domain/repositories package with four protocol interfaces
- Added LifecyclePlanRepositoryProtocol, ActionRepositoryProtocol,
  DecisionRepositoryProtocol, and ProjectRepositoryProtocol
- Updated infrastructure repositories to explicitly inherit protocols
- Added 10 Behave scenarios for protocol compliance verification

ISSUES CLOSED: #2873
2026-04-05 08:43:01 +00:00
freemo 4d31f0ed02 fix(cli): promote --format to global CLI callback option per spec
CI / lint (pull_request) Successful in 21s
CI / quality (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 1m0s
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Failing after 7m5s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 16m51s
CI / integration_tests (pull_request) Successful in 23m16s
CI / coverage (pull_request) Successful in 10m39s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m46s
Add `fmt: OutputFormat` parameter to `main_callback()` in
`src/cleveragents/cli/main.py` and store the selected format in
`ctx.obj["format"]` so all subcommands can read it without needing
their own per-command `--format` flag.

Remove per-command `--format` / `fmt` parameters from `version()`,
`info()`, and `diagnostics()` commands. These commands now read the
format from `ctx.obj.get("format", OutputFormat.RICH.value)`.

The specification states: "The framework supports six distinct output
formats, selectable via the global `--format` flag." This change
aligns the implementation with the spec by making `--format` a global
option on the root `agents` command (via the Typer callback).

All six formats (json, yaml, plain, rich, table, color) are supported
via the global flag and the `-f` shorthand.

Add Behave BDD scenarios covering global `--format` flag propagation
to subcommands for all six formats. Update Robot Framework integration
tests to exercise the global `--format` flag. Update existing tests
that used per-command `--format` for version/info/diagnostics to use
the global flag instead.

ISSUES CLOSED: #2908
2026-04-05 08:39:14 +00:00
freemo fc7e47f66b fix(cli): remove --namespace/-n from agents plan list command
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 49s
CI / quality (pull_request) Successful in 41s
CI / security (pull_request) Successful in 1m1s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m45s
CI / e2e_tests (pull_request) Successful in 17m7s
CI / integration_tests (pull_request) Failing after 23m11s
CI / docker (pull_request) Successful in 1m24s
CI / coverage (pull_request) Successful in 10m54s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m52s
Remove the --namespace/-n option from the agents plan list CLI command
as it is not defined in the specification. The spec defines:

  agents plan list [--phase <PHASE>] [--state <STATE>]
                   [--project <PROJECT>] [--action <ACTION>] [<REGEX>]

Namespace filtering is already supported via the positional <REGEX>
argument (e.g. 'agents plan list "^myteam/"').

Changes:
- Remove namespace parameter from lifecycle_list_plans() function
- Remove namespace=namespace from service.list_plans() call
- Remove Namespace row from TUI Filters panel
- Update docstring examples to remove --namespace references
- Update filter panel condition to exclude namespace check
- Remove 4 namespace-related scenarios from plan_cli_spec_alignment.feature
- Remove corresponding step definitions from plan_cli_spec_alignment_steps.py

ISSUES CLOSED: #2986
2026-04-05 08:38:26 +00:00
freemo 4b9798bc40 fix(sandbox): use spec-required cleveragents/plan- branch prefix in GitWorktreeSandbox
CI / lint (pull_request) Successful in 26s
CI / quality (pull_request) Successful in 44s
CI / typecheck (pull_request) Successful in 55s
CI / security (pull_request) Successful in 54s
CI / build (pull_request) Successful in 20s
CI / helm (pull_request) Successful in 32s
CI / unit_tests (pull_request) Successful in 7m1s
CI / e2e_tests (pull_request) Successful in 17m26s
CI / integration_tests (pull_request) Successful in 23m31s
CI / coverage (pull_request) Successful in 11m6s
CI / docker (pull_request) Successful in 1m20s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m2s
- Implemented branch naming change in GitWorktreeSandbox.create() from sandbox/<plan_id> to cleveragents/plan-<plan_id>, located in src/cleveragents/infrastructure/sandbox/git_worktree.py
- Updated the create() method docstring to reflect the new branch naming convention
- Updated test fixtures:
  - features/steps/git_worktree_coverage_boost_steps.py: sandbox/test -> cleveragents/plan-test, sandbox/cleanup-test -> cleveragents/plan-cleanup-test, sandbox/branch-delete-fail -> cleveragents/plan-branch-delete-fail
- Updated scenario:
  - features/garbage_collection.feature: sandbox/test-plan -> cleveragents/plan-test-plan
- Design rationale:
  - Adopted the spec-required format: cleveragents/plan-{safe_plan_id} to align with the spec-defined namespace for all CleverAgents-managed git branches
  - Ensures consistent branch naming across code, tests, and features for easier policy enforcement and maintainability

ISSUES CLOSED: #2601
2026-04-05 08:29:55 +00:00
freemo 21a551cd6f fix(resource): use namespace column instead of name heuristic in db_to_spec() for built_in field
CI / lint (pull_request) Failing after 21s
CI / typecheck (pull_request) Successful in 58s
CI / security (pull_request) Successful in 52s
CI / quality (pull_request) Successful in 36s
CI / coverage (pull_request) Has been skipped
CI / build (pull_request) Successful in 20s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m5s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m36s
CI / integration_tests (pull_request) Successful in 23m17s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
Replace the name-based heuristic ("/" not in name) in db_to_spec() with
the authoritative namespace column check (str(raw_ns) == "builtin"),
consistent with the existing _load_type_registry() implementation.

The old heuristic would misclassify custom resource types whose names
contain no "/" as built-in, potentially blocking their removal via
remove_type(). The namespace column is set to "builtin" by spec_to_db()
for all built-in types and to the actual namespace prefix for custom types,
making it the correct source of truth.

A name-heuristic fallback is retained for legacy rows where the namespace
column is NULL (e.g. rows inserted directly without going through
spec_to_db()).

New BDD scenarios added to resource_registry_service_coverage.feature:
- _db_to_spec sets built_in True when namespace column is "builtin"
- _db_to_spec sets built_in False when namespace column is not "builtin"

ISSUES CLOSED: #3013
2026-04-05 08:29:36 +00:00
freemo bb97f87a31 docs(spec): fix invariant precedence chain (3-tier->4-tier) and document non_overridable flag
CI / lint (pull_request) Successful in 20s
CI / typecheck (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 33s
CI / security (pull_request) Successful in 1m4s
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m32s
CI / e2e_tests (pull_request) Successful in 17m32s
CI / integration_tests (pull_request) Successful in 23m8s
CI / docker (pull_request) Successful in 1m41s
CI / coverage (pull_request) Successful in 10m28s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m40s
Approved proposal: #3064

Changes:
- Glossary (line 92): Fix 3-tier precedence claim to correct 4-tier chain
  (plan > action > project > global) and add non_overridable exception note
- Line 18980: Fix Invariant Reconciliation Actor step 5 precedence reference
- Line 18991: Fix Strategize phase invariant reconciliation precedence reference
- Lines 19601-19604: Update Precedence and conflict resolution section to include
  action tier as a distinct scope (not promoted to plan tier) and add
  non_overridable exception clause
- Line 19618: Fix invariant view calculation precedence reference
- Lines 19621+: Add Non-overridable global invariants documentation block

Rationale: The glossary and two Strategize-phase descriptions incorrectly stated
a 3-tier precedence chain (plan > project > global), contradicting ADR-016 which
defines a 4-tier chain (plan > action > project > global). The implementation in
actor/reconciliation.py and application/services/plan_lifecycle_service.py
correctly uses the 4-tier model. The non_overridable field on the Invariant domain
model was implemented but completely undocumented in the spec.
2026-04-05 08:27:30 +00:00
freemo cd162488ec fix(resource-registry): implement get_parents() on ResourceDagMixin
CI / lint (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 41s
CI / security (pull_request) Successful in 1m4s
CI / build (pull_request) Successful in 27s
CI / helm (pull_request) Successful in 29s
CI / unit_tests (pull_request) Successful in 7m2s
CI / e2e_tests (pull_request) Successful in 17m44s
CI / integration_tests (pull_request) Successful in 23m6s
CI / docker (pull_request) Successful in 1m23s
CI / coverage (pull_request) Successful in 10m43s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m12s
Add get_parents(name_or_id: str) -> list[Resource] method to ResourceDagMixin
in _resource_registry_dag.py. The method is symmetric to the existing
get_children() method but queries ResourceLinkModel by child_id instead of
parent_id to return all direct parent resources.

Implementation details:
- Calls show_resource() first to raise NotFoundError for non-existent resources
- Queries ResourceLinkModel filtered by child_id=resource.resource_id
- Returns deterministically sorted list (by name, then resource_id)
- Exposed via ResourceRegistryService through the mixin inheritance chain

The BDD scenario 'Get parents returns all direct parents' in
resource_dag.feature now passes. All 15 existing @dag_traversal and other
DAG scenarios continue to pass with no regression.

ISSUES CLOSED: #2844
2026-04-05 08:27:19 +00:00
freemo 6e09842731 fix(cli): raise on subcommand registration failure instead of partial silent return
CI / lint (pull_request) Successful in 22s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 1m5s
CI / quality (pull_request) Successful in 33s
CI / unit_tests (pull_request) Failing after 1m55s
CI / docker (pull_request) Has been skipped
CI / build (pull_request) Successful in 20s
CI / helm (pull_request) Successful in 23s
CI / e2e_tests (pull_request) Successful in 15m57s
CI / integration_tests (pull_request) Successful in 22m58s
CI / coverage (pull_request) Failing after 2m1s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m50s
- What was implemented
  - Fixed _register_subcommands in src/cleveragents/cli/main.py: replaced bare return with raise SystemExit(1) from exc in the exception handler to propagate a non-zero exit code and preserve the original traceback context.
  - Removed # pragma: no cover from the exception handler, enabling test coverage for this path.

- Why this change
  - Ensures the CLI exits with a non-zero status on subcommand registration failure and provides proper error context for debugging, aligning with the project's error-handling goals and B904 linting requirements.

- Tests and verification
  - Added Behave BDD issue-capture test features/tdd_cli_incomplete_subcommand_registration.feature with 3 scenarios to exercise and validate the failure path.
  - Added step definitions features/steps/tdd_cli_incomplete_subcommand_registration_steps.py corresponding to the new scenarios.
  - The @tdd_expected_fail scenario captures the previous buggy behavior (silent return with exit code 0) to ensure regression is addressed.
  - All nox quality gates pass (lint, typecheck).

- Key design decisions
  - Use raise SystemExit(1) from exc to exit with a clear non-zero status while preserving the original exception chain (satisfies B904).
  - Coverage ensured by removing the pragma, bringing the error path under test.
  - Behavior now explicitly signals failure to the shell and any orchestrating tooling, avoiding silent failures.

- Affected modules and artifacts
  - src/cleveragents/cli/main.py
  - features/tdd_cli_incomplete_subcommand_registration.feature
  - features/steps/tdd_cli_incomplete_subcommand_registration_steps.py

ISSUES CLOSED: #2604
2026-04-05 08:27:05 +00:00
freemo e1f5c95bad fix(database): move get_all_for_project call outside loop in LegacyDataMigrator
CI / lint (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 58s
CI / quality (pull_request) Successful in 34s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 22s
CI / unit_tests (pull_request) Successful in 6m48s
CI / e2e_tests (pull_request) Successful in 15m40s
CI / integration_tests (pull_request) Successful in 22m59s
CI / coverage (pull_request) Successful in 10m59s
CI / docker (pull_request) Successful in 1m24s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m1s
Move ctx.plans.get_all_for_project(project.id) outside the plan
iteration loop in LegacyDataMigrator.migrate_project_data to eliminate
an N+1 database query pattern.

Previously, the method fetched all plans from the database on every
iteration of the plans loop, resulting in O(N) queries where N is the
number of plans in the legacy plans.json file. For projects with many
plans, this caused significant unnecessary database load during migration.

The fix fetches all existing plans once before the loop begins, then
uses the in-memory list for duplicate detection on each iteration.

Also verified no other similar N+1 patterns exist in LegacyDataMigrator.

Added a new Behave scenario 'get_all_for_project is called only once for
multiple plans' that patches the repository method to count invocations
and asserts exactly one call regardless of how many plans are migrated.

ISSUES CLOSED: #3047
2026-04-05 08:26:50 +00:00
freemo 9664271562 fix(resources): allow agents resource stop to stop container-instance and devcontainer-instance resources
CI / lint (pull_request) Successful in 20s
CI / typecheck (pull_request) Successful in 1m17s
CI / quality (pull_request) Successful in 40s
CI / security (pull_request) Successful in 1m4s
CI / build (pull_request) Successful in 31s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m52s
CI / e2e_tests (pull_request) Successful in 17m9s
CI / integration_tests (pull_request) Successful in 23m1s
CI / coverage (pull_request) Successful in 10m39s
CI / docker (pull_request) Successful in 1m21s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m45s
Add container-instance to _STOPPABLE_TYPES so that agents resource stop
accepts both container-instance and devcontainer-instance resources, as
required by the specification. The stop_container function already uses
docker stop with the container_id from the lifecycle tracker, which works
generically for both resource types.

- Add container-instance to _STOPPABLE_TYPES frozenset
- Update resource_stop() docstring to reflect both stoppable types
- Update devcontainer_cleanup.feature: F19 scenario now expects success
  for container-instance stop (was incorrectly expecting rejection)
- Add TDD feature file and step definitions for issue #2588 regression
  guard

ISSUES CLOSED: #2588
2026-04-05 08:22:45 +00:00
freemo e05a577090 fix(acms): align DEFAULT_SKELETON_RATIO default value with spec
CI / lint (pull_request) Successful in 19s
CI / quality (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 55s
CI / security (pull_request) Successful in 1m2s
CI / build (pull_request) Successful in 24s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 6m27s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m25s
CI / integration_tests (pull_request) Successful in 23m0s
CI / coverage (pull_request) Successful in 10m52s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m22s
Align all DEFAULT_SKELETON_RATIO / _DEFAULT_SKELETON_RATIO constants
to the spec-required value of 0.15 (docs/specification.md line 35294).

Previously three modules used divergent defaults:
- skeleton_compressor.py: 0.3 (2x the spec value)
- depth_breadth_projection.py: 0.2 (33% above spec)
- project_context.py: 0.2 (33% above spec)

This caused child plans to receive 2-3x more skeleton context than
intended, and produced inconsistent behaviour depending on whether
skeleton compression was invoked via the CLI or the service layer.

Changes:
- Set DEFAULT_SKELETON_RATIO = 0.15 in skeleton_compressor.py
- Set DEFAULT_SKELETON_RATIO = 0.15 in depth_breadth_projection.py
- Set _DEFAULT_SKELETON_RATIO = 0.15 in project_context.py
- Update Behave feature tests to assert the 0.15 default value
- Add new scenario to project_context_cov3.feature asserting
  _DEFAULT_SKELETON_RATIO == 0.15 in _default_acms_config()

ISSUES CLOSED: #2909
2026-04-05 08:22:36 +00:00
freemo 2d07cd5ef8 fix(cli): add NAME positional argument to agents actor add command per spec
CI / lint (pull_request) Successful in 28s
CI / typecheck (pull_request) Successful in 53s
CI / security (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 34s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m0s
CI / e2e_tests (pull_request) Failing after 16m33s
CI / integration_tests (pull_request) Successful in 23m25s
CI / docker (pull_request) Successful in 1m25s
CI / coverage (pull_request) Successful in 10m40s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m9s
The spec (docs/reference/actor_cli.md) defines the synopsis for
`agents actor add` as:

  agents actor add <NAME> --config <FILE> [--update] [--unsafe]
  [--set-default] [--option key=value] [--format FORMAT]

The implementation was missing the required <NAME> positional argument,
silently reading the actor name from the config file's `name` field
instead. This deviates from the spec and breaks the expected CLI UX.

Changes:
- Add `name` as a required positional Argument to the `add` command
- Update docstring to match spec synopsis exactly
- The positional NAME takes precedence over any `name` field in config
- Remove the now-redundant config-file name validation (name comes from CLI)
- Add Behave BDD feature + steps for the NAME positional argument (TDD)
- Update all existing Behave step invocations to pass NAME positional arg
- Update Robot Framework helpers to pass NAME positional arg

ISSUES CLOSED: #2905
2026-04-05 08:12:32 +00:00
freemo 8d7f2103e7 fix(resource-registry): remove type: ignore[override] suppressions from ResourceDagMixin by restructuring mixin/protocol relationship
CI / lint (pull_request) Successful in 29s
CI / quality (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 53s
CI / security (pull_request) Successful in 54s
CI / build (pull_request) Successful in 24s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 7m5s
CI / e2e_tests (pull_request) Successful in 17m54s
CI / integration_tests (pull_request) Successful in 22m51s
CI / coverage (pull_request) Successful in 10m50s
CI / docker (pull_request) Successful in 1m23s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m18s
The two # type: ignore[override] inline suppression comments on the
link_child and unlink_child methods of ResourceDagMixin violated the
project's strict no-suppression policy in CONTRIBUTING.md.

Investigation revealed the suppressions were unnecessary: after removing
them, nox -e typecheck passes with 0 errors and 0 warnings. The
underlying Pyright type checker already accepts the mixin pattern with
self: RegistryHost annotations without any suppression.

Both comments are removed with no other changes required.

ISSUES CLOSED: #2830
2026-04-05 08:07:21 +00:00
freemo dbf3b8d7f7 fix(resources): remove overlay from SandboxStrategy enum - not in spec
CI / lint (pull_request) Successful in 27s
CI / typecheck (pull_request) Successful in 51s
CI / quality (pull_request) Successful in 38s
CI / security (pull_request) Successful in 58s
CI / build (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m46s
CI / e2e_tests (pull_request) Successful in 18m2s
CI / integration_tests (pull_request) Successful in 22m24s
CI / docker (pull_request) Successful in 1m20s
CI / coverage (pull_request) Successful in 11m11s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m8s
Add 'overlay' to _VALID_STRATEGIES frozenset in ResourceTypeConfigSchema
validator so that resource type YAML configs specifying
sandbox_strategy: overlay are accepted without raising ValueError.

The overlay strategy is defined in the specification for fs-mount
resources using OverlayFS. The domain model SandboxStrategy enum
correctly includes OVERLAY = 'overlay', but the YAML schema validator
in src/cleveragents/resource/schema.py was missing it from
_VALID_STRATEGIES, causing a validation error on valid configurations.

Changes:
- Add 'overlay' to _VALID_STRATEGIES in src/cleveragents/resource/schema.py
- Add BDD scenario: 'Schema accepts overlay sandbox strategy'
- Add step definitions for the new scenario

ISSUES CLOSED: #2827
2026-04-05 08:04:27 +00:00
freemo 03e5403374 chore(agents): add auto-rebase on conflict to PR reviewer pool
CI / lint (pull_request) Successful in 28s
CI / typecheck (pull_request) Successful in 53s
CI / security (pull_request) Successful in 1m3s
CI / quality (pull_request) Successful in 32s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 6m36s
CI / e2e_tests (pull_request) Successful in 18m52s
CI / integration_tests (pull_request) Successful in 23m10s
CI / docker (pull_request) Successful in 1m35s
CI / coverage (pull_request) Successful in 11m41s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m43s
Agent evolver identified a systematic pattern:
- Pattern: Dead-end conflict handling in PR reviewer
- Evidence: When the reviewer detects merge conflicts, it posts a comment
  saying 'implementor needs to rebase' and marks the PR as done. But the
  issue worker has already exited after PR creation — nobody acts on the
  rebase request. This created a dead end where 11+ approved PRs were
  abandoned due to conflicts (PRs #1219, #1236, #1247, #1248, #1220,
  #1237, #1238, #1246, #1252, #1269).
- Fix: When the reviewer reports a conflict, the pool supervisor (which
  has full bash permissions and maintains a clone) now attempts to rebase
  the PR branch onto latest master itself. If the rebase succeeds, the
  PR is re-queued for merge. If it fails, the PR is abandoned with a
  clear comment explaining manual intervention is needed.

This change requires human approval before taking effect.
2026-04-05 07:53:08 +00:00
freemo 1411adfed3 Merge pull request 'fix(lsp): release lock before blocking I/O in LspLifecycleManager.restart_server() to prevent deadlock' (#3165) from fix/lsp-lifecycle-restart-lock-deadlock into master
CI / benchmark-publish (push) Waiting to run
CI / lint (push) Successful in 27s
CI / typecheck (push) Successful in 51s
CI / quality (push) Successful in 35s
CI / security (push) Successful in 59s
CI / benchmark-regression (push) Waiting to run
CI / build (push) Successful in 24s
CI / helm (push) Successful in 23s
CI / unit_tests (push) Successful in 6m59s
CI / e2e_tests (push) Successful in 17m58s
CI / integration_tests (push) Successful in 22m57s
CI / coverage (push) Successful in 10m52s
CI / docker (push) Successful in 1m30s
CI / status-check (push) Waiting to run
2026-04-05 07:50:09 +00:00
freemo 491781714f fix(actors): enforce --update flag in agents actor add - reject re-adding existing actor without --update
CI / lint (pull_request) Successful in 22s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 54s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 25s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 6m58s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 18m30s
CI / integration_tests (pull_request) Failing after 23m24s
CI / coverage (pull_request) Successful in 10m59s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m21s
Before calling upsert_actor(), check if the actor already exists using
registry.get_actor() or service.get_actor(). If the actor exists and
update_existing is False, print the spec-required error panel and exit
with error code 1.

Error panel includes:
- Actor name
- Registration timestamp (formatted as YYYY-MM-DD HH:MM)
- Hint to use --update flag

Adds Behave tests for:
- Duplicate-without-update failure case (exit code 1, error panel shown)
- Duplicate-with-update success case (exit code 0, actor updated)
- New actor without --update success case (exit code 0, actor added)

ISSUES CLOSED: #2609
2026-04-05 07:49:49 +00:00
freemo 7c2f5a1c76 fix(mcp): correct MCPToolResult.data type annotation for MCP 1.4.0 content list format
CI / lint (pull_request) Successful in 35s
CI / typecheck (pull_request) Successful in 58s
CI / security (pull_request) Successful in 1m0s
CI / quality (pull_request) Successful in 39s
CI / build (pull_request) Successful in 24s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m4s
CI / e2e_tests (pull_request) Successful in 17m25s
CI / integration_tests (pull_request) Successful in 22m49s
CI / docker (pull_request) Successful in 1m29s
CI / coverage (pull_request) Successful in 11m6s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m30s
- What was implemented
  - Updated MCPToolResult.data docstring to document the normalisation behaviour, clarifying that MCP 1.4.0 list-format content is normalised to a dict with a "content" key.
  - Updated MCPToolAdapter.invoke() success path to normalise MCP 1.4.0 list-format content: when content is a list (as per MCP 1.4.0 spec), it is wrapped as {"content": [...]} so MCPToolResult.data is always dict[str, Any].
  - Updated MockMCPTransport.call() to return MCP 1.4.0-compliant list-format content: invoke_results are now wrapped as [{"type": "text", "text": json.dumps(payload)}] instead of the non-standard dict format.
  - Added json import to mock_mcp_transport.py to support JSON payload encoding.
  - Updated existing mcp_adapter.feature scenario "Invoke a discovered tool successfully" to check for "content" key instead of "id" (since mock now returns MCP 1.4.0 list format).
  - Added two new Behave scenarios: "Invoke tool returns MCP 1.4.0 list-format content normalised to dict" and "Invoke tool with MCP 1.4.0 content list stores content items".
  - Added corresponding step definitions for the new scenarios.
  - All 14,418 existing scenarios continue to pass; 2 new scenarios added; typecheck passes with 0 errors; lint passes.

- Why this approach
  - Design decision: Normalize to dict (Option B) to maintain a consistent MCPToolResult.data type of dict[str, Any] and avoid breaking downstream code that accesses result.data["key"].
  - Fallback path handles non-standard server responses gracefully, ensuring robustness when servers deviate from MCP 1.4.0 spec.

- Technical approach and affected components
  - Core: MCPToolResult data handling and MCPToolAdapter.invoke() logic
  - Mocks: mock_mcp_transport.py updated to emit MCP 1.4.0 list-format content
  - Tests: updated mcp_adapter.feature expectations; added two Behave scenarios with new step definitions
  - Dependencies: added import json to mock_mcp_transport.py

- Verification
  - Comprehensive test suites: 14,418 existing scenarios pass
  - 2 new scenarios added and pass
  - Typechecking: 0 errors
  - Linting: passes

ISSUES CLOSED: #2743
2026-04-05 07:48:02 +00:00
freemo 7b0533b34d fix(skills): add lowercase-only namespace/name pattern validation to SkillConfigSchema.name field
CI / lint (pull_request) Successful in 20s
CI / typecheck (pull_request) Successful in 56s
CI / security (pull_request) Successful in 1m0s
CI / quality (pull_request) Successful in 41s
CI / build (pull_request) Successful in 30s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 7m15s
CI / e2e_tests (pull_request) Successful in 16m28s
CI / integration_tests (pull_request) Successful in 22m39s
CI / docker (pull_request) Successful in 1m25s
CI / coverage (pull_request) Successful in 11m4s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m3s
Enforce lowercase-only namespace/name pattern in both SkillConfigSchema
and ActionConfigSchema by updating NAMESPACED_NAME_RE from the permissive
[a-zA-Z0-9] pattern to the strict [a-z0-9] pattern.

This fixes a UAT-identified bug where uppercase letters were incorrectly
accepted in the namespace/name fields of skill and action configurations,
violating the spec's naming convention (^[a-z0-9_-]+/[a-z0-9_-]+$).

Changes:
- src/cleveragents/skills/schema.py: Update NAMESPACED_NAME_RE to reject
  uppercase letters in namespace and name parts
- src/cleveragents/action/schema.py: Apply the same lowercase-only fix
- features/skill_schema.feature: Add BDD scenarios for uppercase namespace,
  uppercase name part, fully uppercase name, uppercase tool ref, and
  uppercase include name rejection
- features/consolidated_action.feature: Add BDD scenarios for uppercase
  namespace, uppercase name part, and fully uppercase name rejection

ISSUES CLOSED: #3029
2026-04-05 07:43:56 +00:00
freemo 2eaf9362a3 fix(tests): add missing Behave feature file for coverage_threshold
CI / lint (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 47s
CI / security (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 40s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m55s
CI / e2e_tests (pull_request) Successful in 17m13s
CI / integration_tests (pull_request) Successful in 23m21s
CI / coverage (pull_request) Successful in 11m3s
CI / docker (pull_request) Successful in 21s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m1s
- What was implemented
  - Created features/coverage_threshold_config.feature containing 11 BDD scenarios to exercise coverage threshold configurations.
  - All 15 step functions in features/steps/coverage_threshold_config_steps.py are now exercised by the new scenarios.
  - Scenarios cover:
    - pyproject.toml coverage config (7 scenarios)
    - noxfile.py coverage session (2 scenarios)
    - CI workflow (1 scenario)
    - nightly quality workflow (1 scenario)
  - All 11 scenarios verified to pass against actual project configuration values.

- Key design decisions
  - Used the exact step text from the step file to ensure proper Gherkin-to-step matching.
  - Nightly workflow threshold set to 85 (matching the actual --coverage-min 85 value in nightly-quality.yml).
  - Noxfile threshold set to 97 (matching COVERAGE_THRESHOLD = 97 constant).
  - Organized scenarios into logical groups with comments for readability.

- Modules/components affected
  - features/coverage_threshold_config.feature (new feature file)
  - features/steps/coverage_threshold_config_steps.py (all steps now exercised)

ISSUES CLOSED: #2767
2026-04-05 07:43:10 +00:00
freemo e0336379f5 fix(robot): correct dedent logic for try...except...finally in indentation_library
CI / lint (pull_request) Successful in 29s
CI / typecheck (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 33s
CI / security (pull_request) Successful in 1m2s
CI / build (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m48s
CI / e2e_tests (pull_request) Successful in 19m4s
CI / integration_tests (pull_request) Successful in 22m6s
CI / coverage (pull_request) Successful in 10m59s
CI / docker (pull_request) Successful in 22s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m5s
Rewrites the block_stack management in fix_python_indentation to correctly
handle try...except...finally blocks in all configurations:

- Single except clause
- Multiple except clauses for the same try
- try...except...finally
- Nested try blocks with outer except
- Nested try with inner finally followed by outer except (critical regression)

Root cause: The original implementation stored only keyword strings in
block_stack (e.g. 'try', 'class', 'other'). Two bugs existed:

1. When 'finally:' was encountered, the code popped the 'try' from the
   stack. This meant subsequent 'except:' clauses for an outer try could
   not find their matching try, producing syntactically invalid Python.

2. The dedent calculation for 'except'/'finally' counted all stack entries
   up to the first 'try', but did not account for nested try blocks where
   the inner try's except/finally had already been processed.

Fix: Replace the flat string stack with a tuple stack of
(keyword, base_indent, has_seen_except_finally). The new logic:

- 'finally:' always belongs to the innermost try. Pop non-try entries,
  set indent to that try's base_indent, then pop the try itself (finally
  closes the block). The outer try remains on the stack.

- 'except:' belongs to the innermost try. If the innermost try has already
  seen an except/finally AND there is an outer try, the inner try is done:
  pop it and use the outer try instead. Otherwise use the innermost try
  and mark it as having seen an except/finally clause.

Adds a Behave BDD feature (tdd_indentation_library_try_except.feature)
with 6 scenarios covering all acceptance criteria from issue #2845.

ISSUES CLOSED: #2845
2026-04-05 07:39:57 +00:00
freemo e4966021e9 fix(config): correct Settings.data_dir default from Path("data") to Path.home() / ".cleveragents"
CI / lint (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 48s
CI / security (pull_request) Successful in 1m0s
CI / quality (pull_request) Successful in 35s
CI / build (pull_request) Successful in 18s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m42s
CI / e2e_tests (pull_request) Successful in 16m55s
CI / integration_tests (pull_request) Successful in 23m3s
CI / coverage (pull_request) Successful in 10m44s
CI / docker (pull_request) Successful in 1m42s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m29s
The Settings class had data_dir defaulting to Path("data") — a relative
path — but the specification requires the default data directory to be
~/.cleveragents. This inconsistency caused any code reading Settings().data_dir
without setting CLEVERAGENTS_DATA_DIR to use a relative 'data/' directory
instead of the spec-required ~/.cleveragents, affecting log storage, database
location, cache, backups, and all persistent state.

Changes:
- Fix data_dir default_factory from Path("data") to Path.home() / ".cleveragents"
- Add Behave scenario: 'data_dir default is the spec-required home directory path'
- Add Behave scenario: 'data_dir env var override takes precedence over default'
- Add step definition: 'the data directory should equal the home cleveragents path'

Settings.data_dir is now consistent with ConfigService core.data-dir default
(~/.cleveragents). The CLEVERAGENTS_DATA_DIR env var override continues to work.

ISSUES CLOSED: #2851
2026-04-05 07:33:40 +00:00
freemo f373e3a527 fix(resources): register fs-mount built-in resource type at startup
CI / lint (pull_request) Successful in 31s
CI / typecheck (pull_request) Successful in 49s
CI / quality (pull_request) Successful in 48s
CI / security (pull_request) Successful in 56s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 25s
CI / unit_tests (pull_request) Successful in 6m44s
CI / e2e_tests (pull_request) Successful in 19m27s
CI / integration_tests (pull_request) Successful in 22m41s
CI / coverage (pull_request) Successful in 11m4s
CI / docker (pull_request) Successful in 1m24s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m3s
Add fs-mount ResourceTypeDefinition to _GIT_FS_CONTAINER_TYPES in
_resource_registry_data.py so that bootstrap_builtin_types() seeds it
into the registry at startup.

The fs-mount type was listed in BUILTIN_TYPE_NAMES (validation frozenset)
but had no corresponding type definition in BUILTIN_TYPES, causing:
- 'agents resource type list' to omit fs-mount
- 'agents resource add fs-mount ...' to fail with 'Resource type not found'
- fs-directory to be unable to reference fs-mount as a parent type

Changes:
- Add fs-mount definition to _GIT_FS_CONTAINER_TYPES with correct fields:
  name, description, resource_kind=physical, sandbox_strategy=copy_on_write,
  user_addable=True, cli_args=[path], parent_types=[], child_types=[fs-directory],
  auto_discovery with fs-directory rule, handler=fs_mount:FsMountHandler,
  capabilities (read/write/sandbox=True, checkpoint=False)
- Add fs-mount to fs-directory's parent_types so fs-directory can be
  nested under an fs-mount resource
- Add BDD scenarios in resource_type_bootstrap_fs_mount.feature covering
  registration, user_addable, child_types, parent_types, resource add,
  and fs-directory parent resolution
- Add Robot Framework integration tests in resource_type_bootstrap_fs_mount.robot
  covering all four acceptance criteria end-to-end

ISSUES CLOSED: #2911
2026-04-05 07:29:35 +00:00
freemo fc00834bd3 fix(cli): add missing _log.debug call to session export/import/tell DatabaseError handlers
CI / lint (pull_request) Successful in 27s
CI / typecheck (pull_request) Successful in 1m1s
CI / security (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 42s
CI / build (pull_request) Successful in 27s
CI / helm (pull_request) Successful in 24s
CI / unit_tests (pull_request) Successful in 6m58s
CI / e2e_tests (pull_request) Successful in 17m8s
CI / coverage (pull_request) Successful in 10m45s
CI / integration_tests (pull_request) Successful in 22m52s
CI / docker (pull_request) Successful in 1m23s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m12s
Add _log.debug("session export failed", exc_info=True),
_log.debug("session import failed", exc_info=True), and
_log.debug("session tell failed", exc_info=True) to the DatabaseError
handlers in export_session, import_session, and tell commands respectively.

This brings these handlers into consistency with the existing create, list,
show, and delete handlers which already include the _log.debug call for
diagnostic tracebacks when --log-level debug is used.

Also adds three new BDD scenarios and step implementations that verify
_log.debug is called in each of the three handlers, ensuring the pattern
is tested and cannot regress.

ISSUES CLOSED: #2788
2026-04-05 07:28:12 +00:00
freemo 3d8d8058c9 chore: remove stray 2n file accidentally committed
CI / lint (pull_request) Successful in 23s
CI / typecheck (pull_request) Successful in 51s
CI / security (pull_request) Successful in 49s
CI / quality (pull_request) Successful in 36s
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 29s
CI / unit_tests (pull_request) Successful in 6m43s
CI / e2e_tests (pull_request) Successful in 17m15s
CI / coverage (pull_request) Successful in 10m54s
CI / docker (pull_request) Successful in 12s
CI / integration_tests (pull_request) Failing after 23m8s
CI / status-check (pull_request) Failing after 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m25s
2026-04-05 07:18:40 +00:00
freemo a5d6f0c393 fix(a2a): add A2A Python SDK as project dependency
CI / lint (pull_request) Successful in 3m44s
CI / typecheck (pull_request) Successful in 3m58s
CI / build (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 24s
CI / security (pull_request) Successful in 4m3s
CI / quality (pull_request) Successful in 3m40s
CI / unit_tests (pull_request) Successful in 10m23s
CI / e2e_tests (pull_request) Successful in 17m10s
CI / integration_tests (pull_request) Successful in 25m25s
CI / coverage (pull_request) Successful in 14m4s
CI / docker (pull_request) Successful in 1m24s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m0s
Add a2a-sdk>=0.3.0 to [project.dependencies] in pyproject.toml.
The specification mandates that both local (stdio) and server (HTTP)
transports use the A2A Python SDK (ADR-047). Previously the package
was absent from pyproject.toml and uv.lock, making the project
non-compliant with the spec requirement.

Changes:
- Add 'a2a-sdk>=0.3.0' to [project.dependencies] in pyproject.toml
- Regenerate uv.lock to include a2a-sdk 0.3.25 and its transitive deps
- Add Behave scenarios confirming a2a is importable as a project dependency
- Add step definitions for the new TDD scenarios

ISSUES CLOSED: #2922
2026-04-05 07:18:27 +00:00
freemo da0c5f14b5 fix(config): add server_url, server_token, format, and default_estimation_actor fields to Settings
CI / lint (pull_request) Successful in 28s
CI / typecheck (pull_request) Successful in 47s
CI / quality (pull_request) Successful in 33s
CI / security (pull_request) Successful in 1m2s
CI / build (pull_request) Successful in 25s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m41s
CI / docker (pull_request) Successful in 1m23s
CI / e2e_tests (pull_request) Successful in 18m32s
CI / coverage (pull_request) Successful in 11m14s
CI / integration_tests (pull_request) Successful in 22m20s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m4s
Add four spec-required environment variable fields to the Settings class
that were previously missing, causing AttributeError when accessed:

- server_url: str | None — maps to CLEVERAGENTS_SERVER_URL (spec: server.url)
- server_token: str | None — maps to CLEVERAGENTS_SERVER_TOKEN (spec: server.token)
- format: str | None — maps to CLEVERAGENTS_FORMAT (spec: core.format)
- default_estimation_actor: str | None — maps to CLEVERAGENTS_DEFAULT_ESTIMATION_ACTOR
  (spec: core.default_estimation_actor)

All fields default to None when the corresponding env var is unset, and
are fully statically typed (no type: ignore). BDD scenarios cover env var
binding, default value, type validation, and model_fields presence for
each new field.

ISSUES CLOSED: #2866
2026-04-05 07:15:48 +00:00