# Changelog

All notable changes to this project will be documented in this file.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Fixed

- **TDD Non-AssertionError Guard Visibility** (#8294): `apply_tdd_inversion` in
  `features/environment.py` now emits its non-assertion exception guard warning to
  both the structured logger and `stderr` via a new `_warning_with_stderr` helper.
  This makes the guard firing visible in standard Behave console output and CI log
  snippets where the structured logging sink may not be displayed. BDD infrastructure
  coverage added: a new scenario in `tdd_expected_fail_infrastructure.feature`
  asserts that the warning is emitted to stderr when a non-AssertionError exception
  is encountered in an `@tdd_expected_fail` scenario, and a second scenario asserts
  the warning is NOT emitted when the exception is an `AssertionError`. The
  `CONTRIBUTING.md` now documents that `@tdd_expected_fail` step definitions must
  signal expected failures via `AssertionError`.

- **Parallel Behave Runner Log Noise Reduction** (#8351): The parallel behave
  runner now suppresses captured stdout/stderr for passing worker chunks and
  only replays diagnostics for failed, errored, or crashed chunks.  This makes
  failure output significantly easier to spot in CI and local runs.  A worker
  crash (unhandled exception) is detected via an all-zero summary and the
  captured traceback is always surfaced.

- **Automation Profile Silent Fallback** (#8232): `_resolve_profile_for_plan` in
  `PlanLifecycleService` now raises a clear `ValidationError` when a plan's
  automation profile name is not a known built-in profile, instead of silently
  falling back to `"manual"`. Users who configured custom automation profiles
  (e.g. `"semi-auto"`, `"acme/strict"`) will now receive an actionable error
  message listing available built-in profiles. The resolved profile name is also
  logged at debug level for observability.

### Added
- Wired `StrategyActor` into the real plan execution path: `_get_plan_executor`
  in `plan.py` now resolves the strategy actor via `resolve_strategy_actor()`
  (reading the `actor.default.strategy` config key) instead of always
  constructing `LLMStrategizeActor`.  `run_strategize` in `PlanExecutor` now
  passes `resources` (derived from `plan.project_links`) and `project_context`
  to the actor so the LLM prompt receives full project context.  Strategy
  decisions are serialised as JSON in `plan.error_details["strategy_decisions_json"]`
  so `_build_decisions` can reconstruct the full hierarchy (dependency ordering,
  parent/child structure) during Execute instead of rebuilding from
  `definition_of_done`.  `StrategizeStubActor.execute` accepts `**kwargs` for
  forward-compatibility.  Added BDD coverage for the stored-JSON path,
  corrupt-JSON fallback, resource-passing, and stub extra-kwargs scenarios.
  (#828)


- **TDD Issue-Capture Test Activation** (#7025): Replaced 234 bare `@skip` tags
  across 82 Behave feature files with the correct `@tdd_expected_fail @tdd_issue
  @tdd_issue_<N>` tag system. Scenarios whose referenced bugs were already fixed
  had `@tdd_expected_fail` removed and now run as permanent regression guards.
  Net result: 629 features active in CI (up from ~545), zero `@skip` tags remain.

- **Git Worktree Sandbox Apply** (#4454): The `plan apply` command now merges
  LLM-generated changes via `git merge` from an isolated worktree branch
  instead of flat `shutil.copy2`.  Displays spec-aligned Apply Summary
  (plan ID, artifacts, insertions/deletions, project, timestamp), Sandbox
  Cleanup panel, and `✓ OK Changes applied` footer.  Non-git projects fall
  back to the original flat file copy.

- **Context Hydration Fix** (#4454): Fixed `ContextFragment` metadata types
  (`detail_depth` and `relevance_score` must be strings, not int/float) that
  caused Pydantic validation errors during context assembly, resulting in the
  LLM receiving zero file context.

- **Automation Tracking System**: Replaced shared session state issue tracking with
  individual per-agent tracking issues. Each agent now creates its own `[AUTO-<PREFIX>]`
  titled issues with standardized headers, reporting intervals, and health indicators.
  Agents: `session-persister`, `implementation-orchestrator`, `system-watchdog`,
  `backlog-groomer`, `human-liaison`. Documentation at
  `docs/development/automation-tracking.md`.

- **Automated Health Monitoring and Recovery**: The `system-watchdog` now runs
  `audit_automation_tracking_health()` every 5 minutes, detecting stalled agents when
  tracking issues are >20% overdue from their declared reporting interval. On detection,
  it terminates stalled sessions via the OpenCode Server API, performs root-cause analysis,
  creates high-priority diagnostic issues, and closes stale tracking issues with recovery
  notes.

- **Centralized Label Management** (`forgejo-label-manager`): A new specialized subagent
  centralizes all Forgejo label operations across the agent system. Enforces the
  organization-level label system, prohibits label creation, and validates label compliance.
  Agents `backlog-groomer`, `human-liaison`, `project-owner`, `epic-planner`,
  `new-issue-creator`, and `issue-state-updater` now delegate all label operations to this
  subagent.

- **PR–Issue Label Synchronization**: PRs now inherit `Priority/`, `MoSCoW/`, `Points/`,
  and `State/` labels from their associated issues at creation time
  (`pr-api-creator`). The `backlog-groomer` adds a continuous Pass 19 for ongoing
  PR–issue label synchronization. The `issue-state-updater` syncs PR state labels whenever
  issue states change.

- **Automation Tracking Announcements**: Extended `automation-tracking-manager` with
  announcement issue support (`CREATE_ANNOUNCEMENT_ISSUE`, `CLOSE_ANNOUNCEMENT_ISSUE`,
  `LIST_TRACKING_ISSUES`, `READ_ANNOUNCEMENTS`, `REVIEW_OWN_ANNOUNCEMENTS`). Supervisors
  and workers now read critical announcements before each cycle for cross-agent awareness.
  Priority-based filtering (Critical/High/Medium/Low) reduces noise. Backlog-groomer
  performs intelligent cleanup with age thresholds by priority.

- **PR Agent Reorganization**: All PR-related agents renamed and reorganized to follow
  the `*-pool-supervisor` naming pattern. New agents added: `pr-editor` (safe PR editing
  with description preservation), `pr-manager` (unified PR interface), and
  `pr-merge-pool-supervisor` (automated PR merging supervisor). Renamed:
  `pr-api-creator` → `pr-creator`, `pr-checker` → `pr-ci-test-fixer`,
  `pr-status-checker` → `pr-status-analyzer`, `pr-self-reviewer` → `pr-reviewer`,
  `pr-fix-orchestrator` → `pr-fix-pool-supervisor`.

- **Automated PR Merging** (`pr-merge-pool-supervisor`): New supervisor continuously
  monitors for merge-ready PRs and merges them automatically when all criteria are met
  (approvals, CI passing, no conflicts). Supports both formal reviews and comment-based
  approvals (LGTM, ✅, "ready to merge", etc.).

- **Implementation Worker Workflow Completion**: `implementation-worker` now implements
  work claiming protocols with conflict detection, comprehensive review feedback handling
  with intelligent parsing, sophisticated merge conflict resolution with multiple
  strategies, and parallel subtask execution with wave-based dependency analysis.
  Pass rate improved from 48.15% to 84.8%.

- **Container Resource Stop Support**: `agents resource stop` now correctly stops
  `container-instance` and `devcontainer-instance` resource types.

- **Centralized Automation Tracking Manager** (`automation-tracking-manager`): The manager
  is now the single interface for all tracking issue operations (`CREATE_TRACKING_ISSUE`,
  `UPDATE_TRACKING_ISSUE`, `CLOSE_TRACKING_ISSUE`, `READ_TRACKING_STATE`,
  `GET_NEXT_CYCLE_NUMBER`). Agents delegate to the manager rather than calling the Forgejo
  API directly, ensuring sequential cycle numbers across restarts and preventing
  duplicate issues. Migrated agents include `system-watchdog`,
  `implementation-pool-supervisor`, `timeline-update-pool-supervisor`,
  `project-owner-pool-supervisor`, `product-builder`, and
  `backlog-grooming-pool-supervisor`. The legacy `shared/automation_tracking.md` module
  was removed.

- **Documentation Writer Tracking** (`docs-writer`): The documentation writer now
  participates in the automation tracking system by creating individual
  `[AUTO-DOCS] Documentation Report (Cycle N)` issues every 10 cycles (~3.3 hours).
  The manager applies the mandatory `Automation Tracking` label automatically, while
  teams may add additional workflow labels as needed. See
  `docs/development/automation-tracking.md` and the new
  `docs/development/docs-writer.md` reference.

- **ACMS / UKO API Documentation** (`docs/api/acms.md`): Added comprehensive API
  reference for the `cleveragents.acms` package covering the four-layer UKO ontology
  hierarchy, `VocabularyRegistry`, `ProvenanceInfo`, `UKOClass`, `UKOProperty`,
  `UKOVocabulary`, `Layer2Dependency`, `ParadigmVocabulary`, `DetailLevelMapBuilder`,
  and all Layer 3 language vocabulary types (Python, TypeScript, Rust, Java).
  The new page is linked from the API Reference index and the MkDocs navigation.

### Changed

- **Decision Tree Full ULID Display** (#5825): The `agents plan tree` command now
  displays full 26-character ULIDs for all decisions instead of truncating them to
  8 characters. This enables users to copy decision IDs directly from tree output
  and use them in follow-up CLI commands like `agents plan correct` without manual
  ID reconstruction. Added "Decision IDs (for correction)" section with human-readable
  labels for easy reference. Applies to both table and rich/plain text output formats.

- **Automation Tracking Format**: All automation tracking issues now use a standardized
  header format with mandatory `Reporting Interval: <interval> (Next report expected: <ts>)`
  declarations, enabling precise staleness detection.

- **PR Review Policy**: Reduced PR review requirement from 2 approvals to 1. Self-approval
  is now permitted including for automated bot PRs. Approval can be a formal review OR an
  approval comment (LGTM, Approved, ✅, "ready to merge").

- **Label Delegation Enforcement**: `automation-tracking-manager` now enforces delegation
  to `forgejo-label-manager` for all label operations, preventing "invalid label ID" errors
  and ensuring label application uses correct name-to-ID mapping.

- **Automation Tracking Label Guidance**: Documentation now clarifies that the manager
  automatically applies the `Automation Tracking` label and that additional labels such as
  `Type/Automation`, `State/In Progress`, or `Priority/Medium` remain optional workflow
  choices rather than mandatory.

- **Automation Tracking Agent Prefix Registry**: Expanded from 5 agents to 18 agents.
  New prefixes include `AUTO-DOCS`, `AUTO-REV-POOL`, `AUTO-UAT-POOL`, `AUTO-BUG-POOL`,
  `AUTO-INF-POOL`, `AUTO-ARCH`, `AUTO-EPIC`, `AUTO-EVLV`, `AUTO-GUARD`, `AUTO-SPEC`,
  `AUTO-TIME`, `AUTO-PROJ-OWN`, and `AUTO-PROD-BLDR`.

### Fixed

- **Plan Concurrency Race Condition** (#7989): Fixed critical race condition in `execute_plan()` and
  `apply_plan()` where concurrent CLI/worker sessions could simultaneously modify the same plan,
  corrupting plan state. `LockService` is now wired into the plan lifecycle with plan-level advisory
  locking. Each invocation generates a unique caller identity (UUID) to prevent re-entrant lock
  acquisition by concurrent sessions on the same plan. Concurrent attempts now raise `LockConflictError`
  instead of silently racing. Lock is acquired before phase transition and released in a `finally`
  block to ensure cleanup even on error.

- **`--format color` ANSI Output** (#7910): Fixed `format_output` routing the `color` format
  option to `_format_plain`, which produced plain uncoloured text instead of ANSI escape
  sequences. The `color` format is now routed to `format_output_session` which uses the
  `ColorMaterializer` to emit proper ANSI-coloured output. `--format plain` and all other
  formats remain unaffected.

- **ContextTierService Thread Safety** (#7547): Added `threading.RLock` to
  `ContextTierService` to prevent `RuntimeError: dictionary changed size during
  iteration` and data corruption under concurrent plan execution. All public
  methods (`store`, `get`, `promote`, `demote`, `evict_lru`, `enforce_staleness`,
  `get_metrics`, `get_all_fragments`, `get_hot_fragments`, `get_for_actor`,
  `get_scoped_view`, `get_scoped_by_resource`, `get_scoped_metrics`) now acquire
  the reentrant lock before accessing the hot/warm/cold tier dicts. The service
  was previously documented as single-threaded but registered as a DI Singleton,
  causing potential data corruption when parallel subplans shared the same
  instance. The `TierRuntimeMixin.enforce_staleness()` and
  `ScopedTierMixin.get_scoped_by_resource()` / `get_scoped_metrics()` methods
  are also protected. The DI container registration as `providers.Singleton`
  is now correct and safe.

- **Validation Gate Empty-Run Guard** (#7508): Fixed `ApplyValidationSummary.all_required_passed`
  returning `True` when zero validations were run, silently bypassing the apply gate. The property
  now returns `False` when the validation result set is empty (`is_empty` is `True`), ensuring
  that apply is blocked unless at least one validation was actually executed. Also added
  `required_total` property for completeness. Updated `consolidated_validation.feature` scenarios
  to reflect the corrected blocking behavior for empty summaries and no-attachment runs.

- **ACMS context tier hydration**: `ContextTierService` no longer starts empty
  on every CLI invocation. A new `context_tier_hydrator.py` reads files from
  linked project resources (via `git ls-files` or `os.walk`), creates
  `TieredFragment` objects, and stores them in the tier service before context
  assembly in `LLMExecuteActor.execute()`. The LLM now receives real file
  context during plan execution. Respects max file size (256 KB), total budget
  (10 MB), binary file exclusion, and `.git`/`node_modules`/`__pycache__`
  directory skipping. (#1028)

- **Sandbox root wiring**: `_get_plan_executor()` now passes
  `sandbox_root=.cleveragents/sandbox/`, so LLM file output (`FILE:` blocks)
  is written to disk during the execute phase. (#4222)

- **SubplanExecutionService fail_fast cancellation** (#7582): Fixed a race condition where
  already-running parallel subplans were not cancelled when `fail_fast` fired. Previously,
  `Future.cancel()` only prevented queued futures from starting but had no effect on
  in-flight futures that completed after `stop_flag` was set — their `COMPLETE` results
  were incorrectly included in the merge output. The fix adds a post-completion guard that
  overrides any non-`ERRORED`/non-`CANCELLED` result to `CANCELLED` when `stop_flag` is
  active, and clears the associated output to prevent it from entering the merge. Also
  replaces the O(n) linear `status` lookup in the `as_completed()` loop with an O(1)
  `status_map` dict pre-computed before the executor block.

- **Robot Framework TDD Listener Guards** (#5436): Added three guard conditions to the
  `tdd_expected_fail_listener` `end_test()` function to prevent blindly inverting ALL test
  failures to passes, which was masking infrastructure errors and causing flaky CI behavior.
  Guards: setup/teardown error detection, non-assertion failure detection (infrastructure
  errors), and dry-run mode detection. Also fixed `Variable Should Exist` syntax errors in
  e2e test files and removed `tdd_expected_fail` from 4 context assembly e2e tests where
  bugs were already fixed.

- **PluginLoader entry point prefix validation** (#7476): Parse entry point targets before
  import, enforce the module allowlist ahead of loading, and add Behave plus Robot Framework
  regression coverage to ensure disallowed prefixes never execute untrusted module-level code
  in either unit or integration flows.

- **`issue-state-updater` Bash Script Errors**: Removed problematic bash script examples
  that tried to invoke `task forgejo-label-manager` as a bash command (the Task tool cannot
  be invoked from bash). Replaced with clear step-by-step operational instructions and
  direct label management via API.

- **`automation-tracking-manager` Label Delegation Syntax**: Fixed incorrect delegation
  syntax when calling `forgejo-label-manager`. The manager now uses correct natural language
  requests (e.g., "Apply labels to issue #123: Automation Tracking") instead of structured
  parameters, ensuring tracking issues receive proper labels.

- **`product-builder` Missing Supervisors**: Added missing `pr-fix-pool-supervisor` and
  `pr-merge-pool-supervisor` to the product-builder's supervisor launch list (18 total
  supervisors). Updated all numeric references, pre-flight checklists, and validation logic.

- `ActionRepository.update()` now uses explicit bulk `sa_delete()` + `session.flush()`
  before re-inserting child rows for `action_arguments` and `action_invariants`, fixing
  a `sqlite3.IntegrityError: UNIQUE constraint failed` crash when `agents plan use` was
  called on an action that already had arguments registered via `action create`. (#4197)

---

## [3.8.0] — 2026-04-05

### Added

- Wired Invariant Reconciliation Actor auto-invocation into
  `PlanLifecycleService` phase transitions (`start_strategize`,
  `execute_plan`, `apply_plan`).  Reconciliation failures now block
  the transition with `ReconciliationBlockedError` and emit
  `INVARIANT_VIOLATED` events.  Post-correction reconciliation runs
  via `CORRECTION_APPLIED` event subscription (best-effort).  Added
  `InvariantService` Singleton provider in the DI container.
- **TUI — Shell danger detection**: The TUI shell mode (`!` prefix) now detects
  dangerous command patterns before execution. A configurable pattern registry
  classifies commands by danger level (warning, critical) and surfaces a user
  warning overlay before proceeding. Patterns cover destructive filesystem
  operations, privilege escalation, network exfiltration, and more. (#1003)

- **TUI — Permission Question Widget**: A new inline `PermissionQuestionWidget`
  renders permission requests directly in the conversation stream for single-file
  operations. Users can allow/reject with single-key shortcuts (`a`/`A`/`r`/`R`),
  navigate with arrow keys, confirm with `Enter`, or press `v` to open the full
