fix(cli): add --execution-env-priority flag to plan use #972
Merged
hurui200320
merged 1 commits from 2026-03-18 08:13:56 +00:00
feature/m3-plan-use-env-priority into master
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.
No Label
Type
Task
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
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cleveragents/cleveragents-core#972
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 "feature/m3-plan-use-env-priority"
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
Adds the missing
--execution-env-priorityflag to theagents plan usecommand, aligning the CLI with the specification (spec line 12501). The flag acceptsfallback(default) oroverrideand controls execution environment routing precedence per ADR-043:override: The specified execution environment always wins, bypassing devcontainer auto-detection.fallback: The specified environment defers to auto-detected devcontainers or project-level overrides.Changes
cleveragents.domain.models.core.plan):ExecutionEnvPriorityStrEnum withFALLBACK/OVERRIDEvalues.execution_env_priorityfield type toExecutionEnvPriority | None(leverages Pydantic enum validation).@model_validatorenforcing thatexecution_env_priorityrequiresexecution_environment(domain-level fail-fast invariant). Verifiedvalidate_assignment=Trueis set onPlan.model_config.Plan.as_cli_dict()to includeexecution_environmentandexecution_env_priority, with fallback default of"fallback"for pre-migration data whereexecution_env_priorityisNone.cleveragents.cli.commands.plan):--execution-env-priorityparameter touse_action.--execution-environment, enum value validation, case-insensitive input."fallback"when--execution-environmentis set without explicit priority._print_lifecycle_planand_plan_spec_dictto display the priority, defaulting to"fallback"for pre-migration data._plan_spec_dictdocstring to mention new keys.ExecutionEnvPriorityimport to function-entry deferred imports in both_plan_spec_dictand_print_lifecycle_plan(no longer conditional on execution environment being set).service.save_plan(plan)withhas_overridesflag so it is only called when CLI overrides were actually applied.cleveragents.infrastructure.database):execution_environment(String(255), nullable) andexecution_env_priority(String(20), nullable) columns toLifecyclePlanModel.from_domain()/to_domain()for round-trip serialization includingExecutionEnvPriorityenum reconstruction. Uses direct attribute access (plan.execution_environment) instead of defensivegetattr— Plan fields always exist on the Pydantic BaseModel.LifecyclePlanRepository.update()to persist both fields using direct attribute access.m4_003_plan_env_columnsadding both columns to thev3_planstable. UsesString(255)forexecution_environmentto accommodate namespaced resource names. Descends fromm6_005_profile_guards_json.cleveragents.application.services.plan_lifecycle_service):save_plan()public convenience method for callers that need to re-persist after post-creation mutations.call_argsverification).ValueError; construction with both fields succeeds.ExecutionEnvPriorityenum: values verification,StrEnumsubclass assertion.Plan.as_cli_dict(): includes both fields when set, omits both whenNone, defaults priority to"fallback"for pre-migration data.from_domain()→to_domain()preserves both fields; preservesNonevalues.SimpleNamespace-based plan test fixtures indatabase_models_lifecycle_coverage_steps,database_models_new_coverage_steps,database_models_coverage_r2_steps, andrepositories_error_handling_coverage_stepsto includeexecution_environmentandexecution_env_priorityattributes.sys.pathpattern to standard approach.Review Fixes (Brent Edwards, Review #2384)
getattr: Replacedgetattr(plan, "execution_environment", None)with directplan.execution_environmentaccess in bothLifecyclePlanModel.from_domain()andLifecyclePlanRepository.update(). Plan is a Pydantic BaseModel withdefault=None, so the field always exists. Updated 4 pre-existingSimpleNamespace-based test fixtures to include the new attributes.ExecutionEnvPriorityimport from inside conditional blocks to function-entry deferred imports in both_plan_spec_dictand_print_lifecycle_plan.m4_003to descend fromm6_005_profile_guards_json(post-rebase chain fix).masterwith merge conflict inCHANGELOG.mdresolved.Deferred Items
save_plan()fails afteruse_action()succeeds, the plan exists in the DB without CLI overrides. This requires service-layer restructuring beyond the scope of this ticket.m4_003depends onm6_005, creating non-sequential naming. Renaming an existing migration risks breaking the chain for anyone who has already applied it.Quality Gates
Closes #886
Code Review — PR #972 (
fix(cli): add --execution-env-priority flag to plan use)Self-review by: @hurui200320
Ticket: #886
Branch:
feature/m3-plan-use-env-priorityVerdict: REQUEST CHANGES
The specification compliance of the flag implementation is strong — the flag name, allowed values, default behavior, validation, and output all exactly match the spec. The code is well-structured and follows existing patterns consistently. However, several issues need to be addressed before merge.
Blocking Issues
1. CHANGELOG.md not updated
CHANGELOG.mdhas no changes in this PR.--execution-env-priorityflag.2.
execution_env_priority(andexecution_environment) not persisted to databasesrc/cleveragents/cli/commands/plan.py:1571-1646,src/cleveragents/infrastructure/database/models.py(LifecyclePlanModel),src/cleveragents/application/services/plan_lifecycle_service.py:716-718use_actionCLI handler callsservice.use_action()at line 1571, which creates and persists the plan to the database. Theexecution_env_priority(and other overrides likeexecution_environment, actors, etc.) are set on the in-memory plan object after the persist call. No re-persist follows. Additionally,LifecyclePlanModelhas no columns forexecution_environmentorexecution_env_priority, so even a re-persist would not save them. This means the values are lost on process restart or any subsequentplan status/plan executecall.plan_lifecycle_service.pyplan creation," which implies the service should receive and persist this value.execution_env_priority(andexecution_environment) as columns toLifecyclePlanModel, updatefrom_domain()/to_domain()/update(), and add a re-persist call after mutations; or (b) pass the value as a parameter toservice.use_action()so it's set before the initial persist. If this is intentionally deferred to a future PR, the subtask and acceptance criteria should be updated to reflect that.3. Missing model-level validation for priority-without-environment invariant
src/cleveragents/domain/models/core/plan.py:694-697execution_env_priorityrequiresexecution_environmentis enforced only in the CLI layer (plan.py:1624-1629). There is no@model_validatoron thePlanclass. Any code path that creates aPlanoutside the CLI (service layer, API, tests, deserialization) can silently violate this invariant. CONTRIBUTING.md's "Fail-Fast" and "Argument Validation" principles require domain-level validation.@model_validator(mode="after")toPlan:Major Issues
4.
Plan.as_cli_dict()omitsexecution_environmentandexecution_env_prioritysrc/cleveragents/domain/models/core/plan.py:914-1014_plan_spec_dict()function in the CLI correctly includes both fields, but the model's ownas_cli_dict()method does not. Any code path that usesas_cli_dict()(programmatic API consumers, other CLI commands) will silently omit these fields.as_cli_dict():5. Robot Framework integration tests use mocks (CONTRIBUTING.md violation)
robot/helper_plan_use_env_priority.py(throughout)MagicMockandpatchextensively. This follows an established codebase-wide pattern (20+ existing helpers), but technically violates the guidelines.6. Tests do not verify
use_action()was actually calledfeatures/steps/plan_use_env_priority_steps.py:203-219Thensteps verify plan attribute values by readingcontext.mock_service.use_action.return_value, but no scenario asserts thatuse_action()was actually called or checks the arguments passed to it. If a refactor changed the CLI to skipuse_action(), these tests could still pass.mock_service.use_action.assert_called_once()and verifycall_argsin at least one scenario.Minor Issues
7. Model field typed as
str | Noneinstead ofExecutionEnvPriority | Nonesrc/cleveragents/domain/models/core/plan.py:694execution_environmentpattern but misses Pydantic's built-in enum validation.ExecutionEnvPriority | Noneor add a@field_validator.8. Naming inconsistency:
execution_env_priorityvsexecution_environmentenvinexecution_env_prioritybut fullenvironmentinexecution_environment. This flows through the model field, CLI flag, and enum class names.execution_environment_priority/--execution-environment-priorityfor consistency. This is easier to change now than later.9. No test for case-insensitive input handling
features/plan_use_env_priority.feature.lower(), soOVERRIDEandOverrideshould work, but no scenario tests this. If.lower()were removed, existing tests would still pass.10. Behave Scenario 6 output assertion is fragile
features/plan_use_env_priority.feature:41"Execution Env Priority"but not the value. The test could pass even if the priority value were missing.11. Robot helper uses aggressive
sys.path/sys.modulesmanipulationrobot/helper_plan_use_env_priority.py:14-26sys.path.insert(0, _SRC).Positive Observations
.lower()is applied to both validation and storage in single-threaded CLI code."plan env priority"prefix; no conflicts with existing steps.022e43f916to8df51f61d2Review Response — Commit
8df51f61Addressed all actionable items from the self-review. Force-pushed an amended commit. Here is the disposition of each item:
Blocking Issues
1. CHANGELOG.md not updated — FIXED
Added entry under
## Unreleaseddescribing the new--execution-env-priorityflag, domain model changes, and model validation. References(#886).2.
execution_env_prioritynot persisted to database — DEFERREDThis is a pre-existing architectural gap that affects all CLI overrides (
execution_environment, actor overrides, etc.). TheLifecyclePlanModelhas no columns for any of these fields. Fixing this requires:LifecyclePlanModelforexecution_environmentandexecution_env_priorityfrom_domain()/to_domain()/update()methodsuse_action()signatureThis is a cross-cutting concern that should be addressed as a separate issue covering all CLI overrides. The subtask "Pass priority value through to
plan_lifecycle_service.pyplan creation" is satisfied in that the value is correctly set on the Plan domain object returned by the service; the gap is that the service does not re-persist after CLI mutations (same as all other overrides).3. Missing model-level validation — FIXED
Added
@model_validator(mode="after")namedvalidate_env_priority_requires_environmentto thePlanclass. Enforces the invariant thatexecution_env_priorityrequiresexecution_environmentto be set. Withvalidate_assignment=Truein the model config, this fires on every field assignment, providing defense-in-depth for all code paths (CLI, service, API, deserialization).Major Issues
4.
Plan.as_cli_dict()omits fields — FIXEDAdded
execution_environmentandexecution_env_priority(with.valuefor stable string output) toas_cli_dict(), conditionally included when execution environment is set.5. Robot Framework integration tests use mocks — DEFERRED
This is a pre-existing codebase-wide pattern used by 20+ Robot helpers. Rewriting just this helper to use real services would be inconsistent with the rest of the test suite. This should be addressed as a comprehensive effort across all Robot helpers, not piecemeal per PR.
6. Tests do not verify
use_action()was called — FIXEDAdded
step_verify_use_action_calledstep definition withmock_service.use_action.assert_called_once(). Used in Scenario 1 ("Plan use with --execution-env-priority override and --execution-environment") to verify the service was actually invoked.Minor Issues
7. Model field typed as
str | None— FIXEDChanged
execution_env_priorityfield type fromstr | NonetoExecutionEnvPriority | None. This leverages Pydantic's built-in enum validation via coercion. Note: this is actually more consistent with the existing codebase pattern —phase: PlanPhaseandprocessing_state: ProcessingStateare both typed as their enum types, notstr. Theexecution_environment: str | Nonepattern is the outlier. Updated all output sites to use.valuefor explicit string serialization.8. Naming inconsistency — NOT CHANGED (spec-driven)
The CLI flag name
--execution-env-prioritycomes directly from the specification (CLI Synopsis line 331). The model field nameexecution_env_priorityfollows standard kebab-to-snake-case mapping. Changing this would deviate from the spec. If the naming should be aligned, that would require a spec amendment first.9. No test for case-insensitive input — FIXED
Added Scenario 8: "Plan use accepts uppercase --execution-env-priority value" that passes
"OVERRIDE"and verifies it normalizes to"override".10. Behave Scenario 6 output assertion fragile — FIXED
Strengthened Scenario 6 to assert both the label
"Execution Env Priority"AND the value"override"are present in the output.11. Robot helper aggressive sys.path manipulation — FIXED
Replaced the aggressive
sys.pathrebuild +sys.modulesflush pattern with the standard simpler approach:if _SRC not in sys.path: sys.path.insert(0, _SRC). This matches the pattern used byhelper_action_cli_spec.pyand others.Quality Gates (post-fix)
8df51f61d2toad3e4708c4Review Response — Commit
ad3e4708Addressed the remaining deferred item (issue 2: persistence) from the self-review. Force-pushed an amended commit. Here is the updated disposition:
Previously Deferred — Now Resolved
2.
execution_env_priority(andexecution_environment) not persisted to database — FIXEDThis was previously deferred as a pre-existing architectural gap, but the ticket's acceptance criterion explicitly states "Flag value is persisted on the Plan model when creating the plan." The persistence gap has now been fully addressed:
LifecyclePlanModel): Addedexecution_environmentandexecution_env_priorityasString(20)nullable columns.from_domain(): SerializesExecutionEnvPriorityenum to its.valuestring with null guard.to_domain(): ReconstructsExecutionEnvPriorityenum from stored string, with null handling.update(): Writes both fields during plan updates using the samegetattr+.valuepattern as other optional enum fields.PlanLifecycleService.save_plan(): New public convenience method that delegates to_commit_plan(), giving callers a clean API to re-persist after post-creation mutations. No-op in non-persisted (in-memory) mode.use_action: Callsservice.save_plan(plan)after applying all CLI overrides (environment, priority, actors, automation profile), ensuring the values survive across sessions.m4_003_plan_env_columns: Adds both columns tov3_planswith nullable constraint and batch-mode DDL for SQLite compatibility.Test coverage for persistence:
save_plan.assert_called_once()to verify the re-persist path.save_plan.assert_called_once()to verify persistence on the default path.Note: This approach (re-persist after mutation) is intentionally scoped to the fields introduced by this PR. The broader architectural gap (other CLI overrides like actor overrides also not being persisted) remains a separate concern — those fields were already not persisted before this PR, and this PR does not regress them. A separate issue should be created to address the remaining unpersisted CLI overrides.
Items Unchanged from Previous Response
All other items from the self-review remain as addressed in commit
8df51f6:@model_validatoradded.as_cli_dict()omissions — Both fields added.use_action()called — Step added.ExecutionEnvPriority | None.sys.path— Simplified.Quality Gates (post-fix)
PM Day 36 Triage: --execution-env-priority flag for plan use. Closes #886. Self-reviews identified and fixed Blocking issues (CHANGELOG, DB persistence gap, model validation). DB persistence now properly implemented with Alembic migration. Reviewer needed: @hamza.khyari. M4 scope.
ad3e4708c4to200365acbdSelf-QA Review — Verdict: ✅ Approve
This PR has been through an automated self-review and fix loop (2 cycles). The code is now ready for external review.
Loop Summary
Cycle 1 — Findings & Fixes
Major fixes applied:
String(20)→String(255)forexecution_environmentcolumn (DB model + Alembic migration) to accommodate future resource names likelocal/my-dev-container.@model_validatorindependently of CLI (priority without environment raisesValueError; both fields set succeeds).LifecyclePlanModel.from_domain()→to_domain()for both set andNonevalues.as_cli_dict()test coverage: Added 3 Behave scenarios (fields set, fieldsNone, pre-migration fallback default).save_plannow verified withcall_argsidentity check, not just call count.has_overridesguard sosave_plan()only fires when CLI overrides are actually applied.Minor fixes applied:
ExecutionEnvPriorityimport above conditional branches."fallback") inas_cli_dict(),_plan_spec_dict(), and_print_lifecycle_plan().ExecutionEnvPriorityenum test scenarios._plan_spec_dictdocstring.Deferred (documented, out of scope):
save_plan()— requires service-layer restructuring beyond #886.m4_003depends onm6_004) — renaming risks breaking migration chain; cosmetic only.Cycle 2 — Remaining Minor Items (Non-blocking)
Plan.effective_env_priorityproperty.except (ValueError, Exception).ExecutionEnvPriorityimport inuse_action()hoisted unconditionally — could be guarded.save_planassertion.update()path not independently tested for new fields._plan_spec_dict()/_print_lifecycle_plan()output paths.None of these affect functional correctness — they are code style and test quality refinements.
Quality Gates (All Passing)
nox -e lintnox -e typechecknox -e unit_testsnox -e integration_testsnox -e coverage_reportFull implementation notes posted to ticket #886.
200365acbdto55c7bc73f1PM Status — Day 37 — Rebase Required
This PR has merge conflicts and cannot be merged in its current state. 42% of all open PRs (21 of 50) have conflicts — this is a project-wide issue that must be resolved.
@hurui200320 — Please rebase this PR onto
masterby Day 39 EOD (2026-03-19). If you cannot rebase by then, please post a comment explaining the blocker.PM rebase request — Day 37
Code Review — PR #972
fix(cli): add --execution-env-priority to plan useReviewer: @brent.edwards | Size: L (+795, 11 files) | Focus: Domain model, CLI, migration, persistence
No P0 or P1 findings.
This is a well-structured feature implementation:
ExecutionEnvPriorityasStrEnumwith Pydantic model validator is the correct patternupgrade()/downgrade()withbatch_alter_tablefor SQLitehas_overridesflag avoids unnecessary DB writes — good optimizationsave_plan()public API onPlanLifecycleServiceis cleanP2:should-fix (2)
1. Defensive
getattron fields that always exist —repositories.py:1365:getattr(plan, "execution_environment", None). SincePlanis a Pydantic BaseModel withdefault=None, the field always exists. Useplan.execution_environmentdirectly — thegetattrcreates a false impression of optional attributes.2. Late conditional import of
ExecutionEnvPriorityinside_plan_spec_dictrendering function — fragile, import failure surfaces only when displaying a plan with an execution environment. Move to module-level.P3:nit (1)
3. Migration naming jumps from
m6_004tom4_003which is confusing. PR description acknowledges this as deferred — acceptable.Verdict: APPROVED with P2 comments. Both are minor and can be fixed in follow-up.
55c7bc73f1to3d2fc8b383New commits pushed, approval review dismissed automatically according to repository settings
Review Response — Brent Edwards Review #2384
Addressed both P2 items from @brent.edwards's review. Branch rebased onto latest
masterand force-pushed as commit3d2fc8b3.P2 #1 — Defensive
getattron always-present fields — FIXEDReplaced
getattr(plan, "execution_environment", None)with directplan.execution_environmentaccess in:LifecyclePlanModel.from_domain()(cleveragents.infrastructure.database.models)LifecyclePlanRepository.update()(cleveragents.infrastructure.database.repositories)Same for
execution_env_priority: replacedgetattr(plan, "execution_env_priority", None) is not Nonewithplan.execution_env_priority is not None.Since
Planis a PydanticBaseModelwithdefault=Nonefor both fields, they always exist. Thegetattrcreated a false impression of optional attributes.Ripple fix: Four pre-existing
SimpleNamespace-based test fixtures that simulatePlanobjects neededexecution_environment=Noneandexecution_env_priority=Noneadded:_make_plan_object()indatabase_models_new_coverage_steps.pyplan_domain_statelessindatabase_models_lifecycle_coverage_steps.py_base_plan_ns()indatabase_models_coverage_r2_steps.py_make_fake_plan()inrepositories_error_handling_coverage_steps.pyP2 #2 — Late conditional import of
ExecutionEnvPriority— FIXEDHoisted
ExecutionEnvPriorityimport from inside conditionalif plan.execution_environment:blocks to function-entry deferred imports in:_plan_spec_dict()— added to existingfrom cleveragents.domain.models.core.plan import ...deferred import_print_lifecycle_plan()— added to existingfrom cleveragents.domain.models.core.plan import ...deferred importThe imports are now eagerly resolved when the function is called, rather than lazily when a plan happens to have an execution environment. Import failures will now surface immediately, not only on specific code paths.
P3 — Migration naming — DEFERRED (acknowledged)
Migration
m4_003now descends fromm6_005_profile_guards_json(updated post-rebase to fix the Alembic multiple-heads issue). The non-sequential naming (m4_003depending onm6_005) remains cosmetic and is documented in the PR description.Rebase
Branch rebased onto latest
master(20efab90). One merge conflict inCHANGELOG.mdwas resolved (both master's new entries and our entry preserved).Quality Gates (All Passing)
nox -e lintnox -e typechecknox -e unit_testsnox -e integration_testsnox -e coverage_report3d2fc8b383toa1e6c63f5d