[AISOS-1977] [forge] take over tasks#112
Conversation
… Task Takeover Detailed description: - Modified src/forge/config.py to add TaskTakeoverLabels and TaskTakeoverSettings Pydantic models. - Added task_takeover field of type TaskTakeoverSettings to the Settings class. - Added unit tests in tests/unit/test_config_prd.py to verify default task takeover settings and custom overrides. Closes: AISOS-1984
Detailed description: - Added new TASK_TAKEOVER, TASK_TRIAGE_PENDING, TASK_PLAN_PENDING, and TASK_PLAN_APPROVED constants to the ForgeLabel enum in src/forge/models/workflow.py. - Added tests in tests/unit/models/test_workflow.py confirming these labels are properly defined and mapped. Closes: AISOS-1985
…heck bypass Detailed description: - Modified 'src/forge/api/routes/jira.py' to detect task-takeover trigger labels in either 'issue_labels' or 'changelog_items'. - Bypassed 'forge:parent' label requirements for standalone Epic/Task issues when any task-takeover trigger label is present. - Routed standalone task webhook events to the queue under their own identity as 'routing_ticket_key'. - Added unit tests in 'tests/unit/api/routes/test_jira_webhook.py' verifying the bypass logic and queue publishing parameters. Closes: AISOS-1986
Detailed description: - Created TaskTakeoverWorkflow class inheriting from BaseWorkflow. - Implemented state_schema property returning TaskTakeoverState. - Implemented .matches() method matching only when exact forge:managed label is present alongside exact takeover trigger labels (including custom settings label). - Ensured no prefix-matching on forge:managed is performed for trigger matching. - Added placeholder build_graph returning a mock StateGraph. - Registered TaskTakeoverWorkflow first in default router to ensure precedence. - Created unit tests validating TaskTakeoverWorkflow matches conditions, state schema, and routing precedence. Closes: AISOS-1987
…exact router matching Detailed description: - Updated WorkflowRouter.resolve inside src/forge/workflow/router.py to filter out any prefix-based triggers for the Task Takeover Workflow, ensuring that only exact matching is used for trigger resolution. - Verified priority registration where TaskTakeoverWorkflow is registered before BugWorkflow in src/forge/workflow/registry.py. - Added tests to tests/unit/workflow/test_router.py to verify that accidental prefix-based trigger labels do not trigger TaskTakeoverWorkflow. - Added tests to tests/unit/workflow/test_registry.py to verify that conflicting labels correctly prioritize TaskTakeoverWorkflow over BugWorkflow. Closes: AISOS-1988
…rchestrator Worker Detailed description: - Modify worker.py to handle planning-approval states for task_plan_approval_gate. - Recognize forge:task-plan-approved label addition and map task_plan_approval_gate to 'task_plan' stage. - Add task_plan_approval_gate to the _YOLO_GATES set to support automated bypass mode. - Update set_workflow_label in Jira client to preserve forge:managed:task and forge:managed:task-takeover labels during transitions. - Add unit tests verifying task plan approval, YOLO gate, and identity preservation. Closes: AISOS-1989
Detailed description: - Added triage_passed, triage_missing_fields, and plan_content fields to TaskTakeoverState in src/forge/workflow/task_takeover/state.py, and updated create_initial_task_takeover_state to set appropriate default values. - Implemented build_task_takeover_graph and route_entry in src/forge/workflow/task_takeover/graph.py to structure the StateGraph for Task Takeover workflow. - Updated TaskTakeoverWorkflow.build_graph in src/forge/workflow/task_takeover/__init__.py to import and construct the compiled StateGraph. - Added comprehensive unit tests in tests/unit/workflow/task_takeover/test_graph.py to validate the state defaults, route entry resume mapping, conditional triage checks, and correct StateGraph compilation. Closes: AISOS-1990
Detailed description: - Created task-takeover-triage.md to strictly evaluate Problem Statement, Proposed Solution/Approach, and Acceptance Criteria. - Created task-takeover-planning.md to direct agents to map solutions to repository files and test plans. - Created task-takeover-qa.md for answering clarifying questions during interactive planning gates. - Updated unit tests in tests/unit/prompts/test_prompt_templates.py to verify template loading and correctness. Closes: AISOS-1991
Detailed description: - Created the triage_task node under src/forge/workflow/nodes/task_takeover_triage.py to verify Problem Statement, Proposed Solution/Approach, and Acceptance Criteria for Task Takeover tickets. - Exported triage_task in src/forge/workflow/nodes/__init__.py. - Wired the state graph in src/forge/workflow/task_takeover/graph.py to route through the new triage_task node and handle transitioning. - Added comprehensive unit tests in tests/unit/workflow/nodes/test_task_takeover_triage.py verifying first-run comments, resume bypass, missing fields comments/label, and error retry escalation. Closes: AISOS-1992
Detailed description: - Implemented the generate_plan async node in src/forge/workflow/nodes/task_takeover_planning.py. It clones the target repository, gathers codebase file structure/metadata, and invokes a sandboxed ContainerRunner task utilizing the task-takeover-planning.md prompt. - Handled safely writing the generated plan to .forge/plan.md and posting a safely-truncated comment to Jira (with a truncation message if it exceeds 25,000 characters). - Applied the forge:task-plan-pending label to the ticket and transitioned to plan_approval_gate with is_paused=True. - Connected the generate_plan node, plan_approval_gate, and route_plan_approval router within the StateGraph in src/forge/workflow/task_takeover/graph.py. - Refined orchestrator worker's resume handling in src/forge/orchestrator/worker.py to support Task-level plan approval resumption and transition labels correctly. - Added 8 unit tests in tests/unit/workflow/nodes/test_task_takeover_planning.py to verify plan generation, comment truncation, retry policy, and comment revision/feedback parsing flows. Closes: AISOS-1993
Detailed description: - Created task_plan_approval_gate and route_task_plan_approval in task_plan_approval.py to handle human-in-the-loop plan reviews for Task Takeover workflow. - Integrated route_task_plan_approval with comment_classifier to route comment revision requests starting with '!' to regenerate_plan, questions starting with '?' or '@forge ask' to answer_question, and label change to 'forge:task-plan-approved' to setup_workspace. - Connected the new gate node, routing, and answer_question in task_takeover graph. - Enhanced qa_handler and agent to leverage the task-takeover-qa prompt template for task plan approval gate Q&A. - Added comprehensive unit tests for task plan approval gates and updated existing planning and Q&A tests. Closes: AISOS-1994
Detailed description: - Created unit and integration tests for task takeover triage logic in 'tests/workflow/test_task_takeover_triage.py' to cover all complete and incomplete mandatory sections permutations, mocking LLM outputs. - Created LangGraph path transitions and interactive gates routing tests in 'tests/workflow/test_task_takeover_graph.py'. - Verified that workflow identity labels 'forge:managed:task' and 'forge:managed:task-takeover' are preserved exactly during label state transitions. Closes: AISOS-1995
Detailed description: - Created the task execution node in src/forge/workflow/nodes/task_takeover_execution.py implementing execute_task_changes async function. - Integrated ContainerRunner to run task modifications and automated tests inside a sandboxed container. - Handled staging, committing, and recording of logs, execution results, and commit info in state using GitOperations. - Added comprehensive unit tests in tests/unit/workflow/nodes/test_task_takeover_execution.py and verified with full type-safety under mypy and ruff. Closes: AISOS-1996
Detailed description: - Created the task takeover qualitative review node `src/forge/workflow/nodes/task_takeover_review.py` with the `run_qualitative_review` function. - Added prompt template `src/forge/prompts/v1/task-takeover-review.md` implementing explicit assertions for Acceptance Criteria fulfillment and Automated Test Coverage. - Added fields `review_verdict`, `review_feedback`, `qualitative_review_retry_count`, and `qualitative_review_failed` to `TaskTakeoverState`. - Registered the new review node in `src/forge/workflow/nodes/__init__.py`. - Wrote 10 comprehensive unit and integration tests in `tests/unit/workflow/nodes/test_task_takeover_review.py` and registered the new template. Closes: AISOS-1997
Detailed description: - Created src/forge/workflow/nodes/task_takeover_pr.py implementing the create_task_takeover_pr node to push implementation branch changes, open a GitHub pull request, comment the markdown PR link on Jira, transition the issue to "In Review", and clean up workspace/container sandbox resources. - Registered and exported create_task_takeover_pr node in src/forge/workflow/nodes/__init__.py. - Integrated the new node along with setup_workspace, execute_task_changes, and run_qualitative_review into the task takeover StateGraph in src/forge/workflow/task_takeover/graph.py and updated route_entry routing. - Wrote unit and integration tests under tests/unit/workflow/nodes/test_task_takeover_pr.py validating all functionality. Closes: AISOS-1998
Detailed description: - Created 'tests/workflow/test_qualitative_review.py' containing comprehensive unit and integration tests. - Tested the qualitative reviewer verdict parsing and acceptance criteria extraction logic with various realistic LLM review outputs. - Validated state updates (verdict, feedback, retry counts, failed flag) for both passing (adequate) and failing (tests_incomplete) reviews. - Verified node behavior under valid vs invalid diff structures to assert proper validation of requirements and automated test coverage. - Aligned test patterns with nearby code structures in 'tests/unit/workflow/nodes/test_local_reviewer.py'. Closes: AISOS-1999
Detailed description: - Created tests/sandbox/test_task_execution.py with comprehensive integrated sandbox and workflow execution tests. - Verified successful container execution with ContainerRunner including command construction, memory and CPU limits, and workspace mounting. - Verified test-and-build recovery workflows by simulating compilation errors/test failures, asserting logs are captured back to the workflow state, and verifying successful self-correction and git commit on subsequent retry. - Added workspace and container lifecycle teardown/cleanup assertions evaluating cleanup_podman_containers and teardown_workspace to ensure secure resource management. Closes: AISOS-2000
Detailed description: - Connected execution flow nodes (setup_workspace, execute_task_changes, run_qualitative_review, create_task_takeover_pr) in Task Takeover StateGraph inside src/forge/workflow/task_takeover/graph.py. - Added _route_after_qualitative_review conditional routing logic which transitions back to execution on failed or incomplete verdicts up to the configured review_max_attempts limit, and routes to PR on adequate reviews or escalate_blocked when limit is reached. - Registered the new review_max_attempts configuration in TaskTakeoverSettings inside src/forge/config.py with a default of 2. - Updated execute_task_changes in src/forge/workflow/nodes/task_takeover_execution.py to inject previous qualitative review feedback into the agent prompt, establishing a smart self-correction loop. - Added comprehensive unit and integration tests to verify graph compilation, node mapping, and conditional routing logic. Closes: AISOS-2001
Detailed description: - Fixed ADF description parsing in src/forge/integrations/jira/models.py to handle empty docs correctly. - Added add_structured_comment to mock JiraClient in test_prd_rejected.py to fix PRD regeneration test failures. - Updated outdated comment and classification assertions in test_task_implementation_status.py and test_qa_mode.py. - Fixed imports in test_task_handoff.py and redundant execution of 3rd pass in test_local_review_status_comments.py. - Fixed unused imports in task_takeover_triage.py. Closes: AISOS-1977-review
Detailed description: - Updated CLAUDE.md to list new Task Takeover labels, identity preservation labels, and updated forge:yolo description. - Updated docs/guide/labels.md to document the 'Task Takeover Workflow' labels and trigger labels. - Updated docs/reference/config.md to document the task_takeover settings and Pydantic schema options. Closes: AISOS-1977-docs
| def matches(self, _ticket_type: TicketType, labels: list[str], _event: dict[str, Any]) -> bool: | ||
| """Return True only if forge:managed is in labels and any exact task-takeover trigger is present.""" | ||
| # Ensure 'forge:managed' is present exactly (no prefix matching like checking if a label startswith 'forge:managed') | ||
| if "forge:managed" not in labels: |
There was a problem hiding this comment.
This match condition makes the new workflow unreachable from the current worker path. OrchestratorWorker resolves new Jira events with labels=[], so even if the webhook accepted a Task/Epic with takeover labels, the router cannot choose task_takeover and the message is skipped as no workflow found. Please pass the Jira issue labels through the queued payload and into router.resolve() (and add an end-to-end worker test for a new Task takeover event).
| has_takeover_trigger = True | ||
| break | ||
|
|
||
| if not (has_forge_managed or has_takeover_trigger): |
There was a problem hiding this comment.
This accepts trigger-only takeover tickets, but TaskTakeoverWorkflow.matches() requires exact forge:managed plus a trigger. That creates an inconsistent entry path: the webhook queues events that the worker/router will later refuse. Either require forge:managed here too, or relax the workflow matcher and tests so both layers agree.
|
|
||
| # 2. Get Workspace and clone if needed | ||
| workspace_manager = WorkspaceManager(base_dir=settings.workspace_base_dir) | ||
| workspace = workspace_manager.create_workspace( |
There was a problem hiding this comment.
When workspace_base_dir is set, this creates the same deterministic workspace path that setup_workspace() later uses. Because the planning clone is not stored in state or torn down, the approved path reaches setup_workspace() and tries to git clone into an already-populated directory, blocking execution. Please either reuse this workspace by storing workspace_path/branch context, or clean it up before leaving planning.
| "decompose_epics": "plan", | ||
| "regenerate_all_epics": "plan", | ||
| "update_single_epic": "plan", | ||
| "task_plan_approval_gate": "task_plan", |
There was a problem hiding this comment.
Please also add task_plan_approval_gate to the retry approval-gate set below. Today forge:retry at this new gate takes the generic retry branch, clears revision_requested, unpauses, and the gate routes to setup_workspace as if the plan was approved instead of regenerating it.
| class TaskTakeoverSettings(BaseModel): | ||
| """Settings configuration for task takeover.""" | ||
|
|
||
| enabled: bool = False |
There was a problem hiding this comment.
This flag is currently documented as disabling Task Takeover by default, but none of the new webhook/router/workflow matching checks it. Once label routing is fixed, takeover can run even with task_takeover.enabled = False. Please enforce this setting at the entry points, or remove the flag/default-disabled behavior from the config/docs.
|
Forge is addressing PR review feedback now. This status update is informational. |
2 similar comments
|
Forge is addressing PR review feedback now. This status update is informational. |
|
Forge is addressing PR review feedback now. This status update is informational. |
Detailed description: - Extracted JIRA issue labels in worker and passed to router.resolve. - Aligned JIRA webhook route and TaskTakeoverWorkflow matcher to allow standalone trigger-only takeover tickets and enforce task_takeover.enabled setting. - Cleaned up clone workspace at the end of planning to prevent directory collision. - Added task_plan_approval_gate to retry approval gates set. Closes: AISOS-1977
…atch unit tests
Detailed description:
- Added an autouse 'mock_settings' fixture in 'TestDefaultRouter' ('tests/unit/workflow/test_registry.py') and 'TestWorkflowRouter' ('tests/unit/workflow/test_router.py').
- This enables the task takeover settings in those tests, since 'task_takeover.enabled' defaults to 'False' but must be 'True' for workflow matching and resolution tests to succeed.
- Verified that all unit tests, flow tests, and workflow tests pass cleanly.
Closes: AISOS-1977-review-review-impl
Summary
This pull request introduces the Task Takeover Workflow to the Forge SDLC Orchestrator, enabling autonomous, end-to-end task and epic-level code implementation directly from Jira. It extends the configuration schema, routing capabilities, and LangGraph workflow structure to support a human-in-the-loop triage and planning process followed by isolated sandbox execution, qualitative LLM code review, and automated PR creation. This workflow allows developers and product managers to seamlessly delegate standalone programming assignments to Forge with custom safety rails, automated test generation, and iterative self-correction loops.
Changes
Configuration, Models, and Routing
src/forge/config.py,tests/unit/test_config_prd.py): CreatedTaskTakeoverLabelsandTaskTakeoverSettingsPydantic models, and added a nestedtask_takeoversettings field supporting customized triggers, labels, and requirement checks, with the workflow disabled by default (enabled = False).src/forge/models/workflow.py,tests/unit/models/test_workflow.py): Defined new label constants in theForgeLabelenum (TASK_TAKEOVER,TASK_TRIAGE_PENDING,TASK_PLAN_PENDING,TASK_PLAN_APPROVED).src/forge/api/routes/jira.py,tests/unit/api/routes/test_jira_webhook.py): Updated the Jira webhook receiver to detect task-takeover triggers, enforce thetask_takeover.enabledsetting, and bypass parentless ticket checks for standalone tasks or epics, routing events under their own identity (routing_ticket_key).src/forge/workflow/router.py,src/forge/workflow/registry.py): RegisteredTaskTakeoverWorkflowwith exact label matching (avoiding prefix-matching triggers), enforcing thetask_takeover.enabledsetting, and ordered it beforeBugWorkflowto establish priority resolution.Task Takeover State and Graph Configuration
src/forge/workflow/task_takeover/state.py): ImplementedTaskTakeoverStateinheriting from Base and integration states, tracking fields liketriage_passed,triage_missing_fields,plan_content, and retry metrics.src/forge/workflow/task_takeover/graph.py): Constructed and compiled theStateGraphdefining the structured node sequence: triage check -> triage gate -> generate plan -> plan approval gate -> setup workspace -> execute task changes -> run qualitative review -> create PR.Prompt Templates
src/forge/prompts/v1/): Added specialized prompts for triage verification (task-takeover-triage.md), structured plan generation (task-takeover-planning.md), Q&A answers during planning (task-takeover-qa.md), and qualitative review validation (task-takeover-review.md).Workflow Nodes and Gate Logic
src/forge/workflow/nodes/task_takeover_triage.py): Verifies that tickets contain a Problem Statement, Proposed Solution/Approach, and Acceptance Criteria, applying the triage-pending label and commenting if fields are missing.src/forge/workflow/nodes/task_takeover_planning.py): Clones the repository, analyzes metadata, generates a file-mapped implementation plan, and posts it to Jira, safely truncating the comment with a warning message if it exceeds 25,000 characters. It also cleans up the cloned workspace at the end of planning to prevent directory collisions.src/forge/workflow/gates/task_plan_approval.py): Pauses workflow execution, routing comments starting with!to plan regeneration,?/@forge askto a Q&A responder node, and label transitions offorge:task-plan-approvedto execution setup. It is also registered in the worker's retry approval gates set.src/forge/workflow/nodes/task_takeover_execution.py): Spawns a secure Podman sandbox container usingContainerRunnerto run code modifications, compile, and run local test suites, feeding logs back to the LLM agent for iterative self-correction.src/forge/workflow/nodes/task_takeover_review.py): Invokes a read-only LLM reviewer to assess the git diff against acceptance criteria and assert that at least one automated test was added or updated.src/forge/workflow/nodes/task_takeover_pr.py): Pushes local branches to remote forks, creates a GitHub PR, posts the PR markdown link on Jira, transitions the Jira issue to "In Review", and tears down sandbox resources.Implementation Notes
forge:managed:taskandforge:managed:task-takeoverduring state transitions.review_max_attempts, defaulting to 2), injecting reviewer feedback directly into subsequent agent prompts. If the retry limit is reached without an adequate review, the workflow transitions to an escalation node (escalate_blocked) rather than creating a PR.forge:parentchecks only when designated trigger labels are present and thetask_takeover.enabledsetting is active, preventing accidental queue pollution or routing of untriggered issues.Testing
tests/unit/test_config_prd.py).tests/unit/api/routes/test_jira_webhook.py).tests/unit/workflow/test_router.py,tests/unit/workflow/test_registry.py).tests/workflow/test_task_takeover_triage.py).tests/workflow/test_task_takeover_graph.py).tests/workflow/test_qualitative_review.py).tests/sandbox/test_task_execution.py).Related Tickets
Generated by Forge SDLC Orchestrator