fix(cli): honour project-level execution-env-priority in resolution #1136
Merged
hamza.khyari
merged 1 commits from 2026-03-31 11:53:09 +00:00
bugfix/m8-exec-env-precedence-level2 into master
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Needs Feedback
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
Controller deferred this PR; awaiting Phase 6+ scope-evaluator or operator re-enablement.
Auto-agents controller manages this PR/issue (see tools/controller/deploy/RUNBOOK.md). Remove this label to abandon controller management.
PR blocked by an open issue dependency. Operator must close the dep (or remove the dependency link) before the merge driver can act. Auto-cleared by merge_drive when no open deps remain.
Most recent merge cycle hit CI timeout. Driver excludes this PR while last merge_cycle row is < 30 min old; label persists thereafter as visible history.
Currently being processed by an implementer worker.
Currently being processed by the merge driver.
Currently being processed by a reviewer worker.
Merge driver heartbeat stale; pipeline halted. Closed automatically on next clean tick.
Detected master commit violating the strict merge invariant. Tracked as an issue (not a PR label); kept here for label completeness.
In-cycle escalation: most recent attempt ran at the Tier 0 slot (`tier-0`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 1 slot (`tier-1`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 2 slot (`tier-2`). Slot's model defined in .opencode/models/tiers.yaml. Gated behind IMPLEMENTER_ESCALATION_TIER2_ENABLED.
In-cycle escalation: most recent attempt ran at the Tier -1 slot (`tier-min`). Slot's model defined in .opencode/models/tiers.yaml. Suffix is ``-min`` (not ``--1``) so the Forgejo UI reads naturally.
Tracking issues used by the AI Automation system for agents to communicate and report.
Rebase conflict needs LLM conflict-resolver.
Failing CI needs implementer attention.
Documenting a driver incident or rollback.
Reviewer has APPROVED this PR and no later REQUEST_CHANGES is outstanding. The merge driver requires this label to even consider a PR for merging. Set by the reviewer worker on APPROVE; cleared on REQUEST_CHANGES.
Train repeatedly lost master-tempo races. Driver excludes via merge_cycle until cooldown elapses; label persists as visible history.
Revert PR backing out an invariant violation. Fast-tracked through the merge driver.
Sentinel PR duplicated from upstream into a personal fork by tools/duplicate_prs_to_fork.py for pipeline testing. Lives only in the fork; the canonical pipeline never sees it.
No implementer activity for N days. Flagged for human review. Auto-cleared on next push to head branch.
Repeatedly fails on current master (>= 3 ci-fail-on-rebased-sha releases in 12 h). Excluded from driver until human triage.
A ticket in a blocked state and unable to complete until some other task is completed first.
Bounty
$100
A bounty of $100 for any open-source contributor who provides a MR that solves this issue
Bounty
$1000
A bounty of $1000 for any open-source contributor who provides a MR that solves this issue
Bounty
$10000
A bounty of $10000 for any open-source contributor who provides a MR that solves this issue
Bounty
$20
A bounty of $20 for any open-source contributor who provides a MR that solves this issue
Bounty
$2000
A bounty of $2000 for any open-source contributor who provides a MR that solves this issue
Bounty
$250
A bounty of $250 for any open-source contributor who provides a MR that solves this issue
Bounty
$50
A bounty of $50 for any open-source contributor who provides a MR that solves this issue
Bounty
$500
A bounty of $500 for any open-source contributor who provides a MR that solves this issue
Bounty
$5000
A bounty of $5000 for any open-source contributor who provides a MR that solves this issue
Bounty
$750
A bounty of $750 for any open-source contributor who provides a MR that solves this issue
MoSCoW
Could have
Could have feature in order to satisfy the epic/legendary.
MoSCoW
Must have
Must have feature in order to satisfy the epic/legendary.
MoSCoW
Should have
Should have feature in order to satisfy the epic/legendary.
There are questions in the ticket that can not be completed until the project owner provides clarity.
Points
1
1 man-hours worth of work for an expert with no learning curve.
Points
13
13 man-hours worth of work for an expert with no learning curve.
Points
2
2 man-hours worth of work for an expert with no learning curve.
Points
21
21 man-hours worth of work for an expert with no learning curve.
Points
3
3 man-hours worth of work for an expert with no learning curve.
Points
34
34 man-hours worth of work for an expert with no learning curve.
Points
5
5 man-hours worth of work for an expert with no learning curve.
Points
55
55 man-hours worth of work for an expert with no learning curve.
Points
8
8 man-hours worth of work for an expert with no learning curve.
Points
88
88 man-hours worth of work for an expert with no learning curve.
Priority
Backlog
This ticket has backlogged priority and is not to be worked on yet
Priority
CI Blocker
Critical priority issue that blocks CI/CD pipeline and prevents PR merges
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
A ticket for learning a tool or technology that is needed to be able to do future planning and design.
State
Completed
The ticket has been fully implemented, completed, and merged with the source code. This label should only be applied once a ticket is closed.
State
Duplicate
A ticket that represents the same content as an existing ticket.
State
In Progress
A ticket that is actively being developed.
State
In Review
A ticket that has had some code completed to implement but is waiting to pass peer review and is not yet merged in.
State
Paused
This ticket's work started but wasn't finished. It's on hold (likely in a feature branch) and will be resumed later, either due to a blocker or a delay.
State
Unverified
All new tickets start in this state. A developer may set it to show the ticket is unverified. This means we haven't agreed to work on it. It will either move to a verified state or be closed as wontdo.
State
Verified
The issue has been verified by a developer as legitimate. It will be worked on and verified tickets are now considered part of the backlog.
State
Wont Do
This ticket has been decided it wont be done. This may mean the bug has been determined to not be real (cant verify) or the feature is one we have decided we dont want to adopt.
Type
Automation
Any edits or discussion about the AI automated coding system.
Type
Bug
Something that doesnt work as intended.
Type
Discussion
Anytime a ticket represents a discussion about a subject and doesnt fall into one of the other categories.
Type
Documentation
An error or improvement needed in the documentation.
Type
Epic
Any first tier epic. That is, an epic which contains only issues as children and will not have sub-epics.
Type
Feature
Some new functionality not present.
Type
Legendary
A type of Epic which will contain other Epics.
Type
Refactor
A code change that restructures existing code without changing its external behavior.
Type
Support
Someone needs help using the project.
Type
Task
A generic task that doesnt fit into the other type categories.
Type
Testing
Work exclusively focusing on fixing or expanding testing.
Projects
Clear projects
No project
Assignees
aditya (Aditya Chhabra)
aleenaumair (Aleena Umair)
brent.edwards (Brent Edwards)
CoreRasurae (Luis Mendes)
drew (Drew Morris)
eugen.thaci (Eugen Thaci)
freemo (Jeffrey Phillips Freeman)
HAL9000 (HAL 9000)
HAL9001 (HAL9001)
hamza.khyari (Hamza Khyari)
hurui200320 (Rui Hu)
justin.morris
khird (Kyle Hird)
org.cleveragents
Clear assignees
No Assignees
hamza.khyari
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cleveragents/cleveragents-core#1136
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "bugfix/m8-exec-env-precedence-level2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
plan_envandproject_envthrough the tool execution chain so theExecutionEnvironmentResolverreceives project-level execution environment valuesproject_env— tools always fell through to the global HOST defaultCloses #1080
Dependency
Requires PR #1135 to be merged first. PR #1135 adds the CLI flag (
project context set --execution-env-priority) and persistence for project-level execution environment. This PR (#1136) threads the persisted value through the execution chain to the resolver.Root Cause
The bug is in the call chain, not the resolver.
ToolCallRouter.route(),ToolCallingRuntime._execute_tool_call(), andPlanExecutionContextnever threadedproject_envthrough toToolRunner.execute(). The resolver receivedproject_env=Nonefor every invocation, so precedence level 2 was always skipped.Changes
PlanExecutionContextplan_envandproject_envfields + propertiesToolCallRouterplan_env/project_envin constructor, pass torunner.execute()inroute()androute_streaming()ToolCallingRuntimeplan_env/project_env, pass torunner.execute()in the direct-runner fallback pathtool_router_steps.pyplan_env/project_envkeyword argumentsexec_env_project_override.featureCHANGELOG.mdTests
4 BDD scenarios (22 steps) verify the full chain:
project_env="container"reaches resolverplan_env="host"reaches resolverplan_envandproject_envreach resolver simultaneouslyNonefor bothAll 99 existing tool_router + execution_environment scenarios pass.
Note on E2E Test
The issue mentions removing
@tdd_expected_failfrom a WF17 precedence level 2 test case. No such test exists — the WF17 E2E suite has not been written yet.ISSUES CLOSED: #1080
Review: REQUEST CHANGES
The diff itself is clean, minimal, and well-structured — adding
plan_env/project_envparameters toPlanExecutionContext,ToolCallRouter, andToolCallingRuntime. The commit messages are excellent and the code follows existing patterns. However, there are two significant gaps.Blocking Issues
No production caller passes the new parameters. The PR adds
plan_env/project_envto the constructors ofPlanExecutionContext,ToolCallRouter, andToolCallingRuntime, but no production construction site is modified in this diff. All existing callers still instantiate these objects without passing env values. This means the plumbing is in place, but unless a companion change at the orchestration/CLI layer actually passes these values when constructing the router and runtime, the bug remains latent in production.If the top-level wiring occurs in a separate PR (layered approach) or via a DI container, please clarify this in the PR description and link to the companion PR.
No new behavioral tests. The only test change is a signature fixup to 2 existing monkey-patched stubs (adding
**_kwargs). There is no test that verifies the actual fix — e.g., constructing aToolCallRouter(plan_env="container")and asserting the runner receives it. For aPriority/Criticalbug fix, there must be at least one test proving the behavior change works end-to-end.Minor Issues
**_kwargsin test stubs is pragmatic but fragile — it silently swallows any future keyword changes without failing. Consider explicitly accepting the new params instead.No BDD scenario for the end-to-end project-level override path. Per CONTRIBUTING.md §Testing Philosophy: "Every coding task must include or update tests at multiple levels."
Action Items
ToolCallRouterwithproject_env="container"and asserts the runner'sexecute()receives it**_kwargswith explicit parameter names in test stubsReview: fix(cli): honour project-level execution-env-priority in resolution
Approved with comments. The code change is correct and minimal.
Issues to Address
1. Unrelated merge commits (Medium)
The branch contains 8 unrelated merge commits from master (LSP runtime, resource handler, plan lifecycle, etc.). Should be rebased to contain only the 2 relevant commits for a cleaner diff and review.
2. Missing integration tests (Medium)
The only test change fixes existing stubs to accept the new
**_kwargs. No new test scenarios verify the actual precedence behavior end-to-end. At least one test that confirms project-levelexecution-env-priorityis actually honored during tool execution would strengthen confidence.What's Good
plan_env/project_envthroughPlanExecutionContext→ToolCallingRuntime→ToolCallRouter→runner.execute().str | NonewithNonedefaults, consistent with existing patterns.Note
PRs #1135 and #1136 are related — #1135 adds the CLI flag and persistence, #1136 threads the value through execution. They should be merged in order: #1135 first, #1136 second.
Day 48 Planning Review — Bug Fix PR for #1080
The core fix (injecting
project_envinto the execution environment resolution chain) is architecturally correct. However, several issues must be resolved:Blocking issues:
Two commits — Must be squashed into one. Per CONTRIBUTING.md, each PR should contain exactly one atomic commit.
Merge conflicts (
mergeable: false) — Rebase required.No milestone assigned — Set to v3.5.0 to match linked bug #1080.
Closing keyword format — Uses
ISSUES CLOSED: #1080(custom trailer) instead ofCloses #1080. Forgejo may not auto-close the issue with the custom format. AddCloses #1080to the PR body.No new tests — As @freemo flagged in review #2706, no behavioral test proves the fix works. The only changes are fixing existing monkey-patched stubs. At minimum, add a test that verifies
project_envreaches the resolver.Dependency on #1135 — This PR requires #1135 to be merged first (confirmed by @freemo's review #2787). This should be documented as a blocking dependency in the PR description.
No
@tdd_expected_failremoval — Author acknowledges the WF17 test suite doesn't exist. Acceptable if no TDD test exists for this bug.Requested changes: Squash commits, rebase, set milestone, add
Closes #1080, add behavioral test, document #1135 dependency.Review: APPROVED
Well-written PR with clear root cause analysis and focused changes. The 5-file, 53-line change is surgically scoped.
Notes
project_env, not a resolver logic bug.**_kwargssignature in test mock overrides is unusual but pragmatic for forward compatibility.PlanExecutionContextadditions (plan_env,project_envproperties) are clean and well-documented.Updated Review (Deep Pass): REQUEST CHANGES
My initial review approved this PR. The deep review reveals a significant gap.
New Finding: Zero New Test Coverage
This PR threads
plan_envandproject_envparameters throughPlanExecutionContext->ToolCallingRuntime->ToolCallRouter->ToolRunner.execute(), but includes no new BDD scenarios or Robot tests proving the resolver actually uses these values. The only test changes update existing mock signatures to accept**_kwargsfor compatibility.Per CONTRIBUTING.md §Multi-Level Testing Mandate: "Every coding task must include or update tests at multiple levels." This PR adds production logic (6 call sites passing
plan_env/project_env) but zero new tests verifying the behavior. There should be at least:Previous finding still applies:
**_kwargssignature in test mocks is pragmatic for forward compatibilityrouter.pyat 909 lines is a pre-existing 500-line violationd709717105to11450c6e6711450c6e67to01400e8c43Self-Review: Production Path Analysis
Rebased onto master (
01400e8c). All 99 affected Behave scenarios pass.Critical Finding: Production Bypass
Deep trace of the production
plan executepath reveals it does not use the tool-calling pipeline:ToolRunner.execute(),ToolCallRouter,ToolCallingRuntime, andPlanExecutionContextare never instantiated in this path. The production execution goes throughLLMExecuteActorwhich sends a prompt directly to the LLM and parses text output with regex.What This Means for #1080
LLMExecuteActor)ToolCallRouter→ToolRunner)This PR correctly fixes the tool-calling pipeline's
project_envthreading. When the tool-calling pipeline becomes the production path (replacingLLMExecuteActor), the fix will be active. Currently, the productionplan executepath doesn't do tool calling or env resolution at all.Recommendation
This PR should be merged as-is — the fix is correct for the tool-calling pipeline. A separate issue should track migrating the production
plan executepath fromLLMExecuteActor(direct LLM invoke) to the tool-calling pipeline (ToolCallingRuntime→ToolCallRouter→ToolRunner), at which point this fix becomes production-active.01400e8c43tocef18b7a0bcef18b7a0bto2207f031502207f03150tocd9cb9e889