Skip to content

End-to-end group orchestration (tracer bullet) - #86

Open
hsubra89 wants to merge 4 commits into
rlph-77-taskgroup-type-github-sub-issue-detection-group-stfrom
rlph-78-end-to-end-group-orchestration-tracer-bullet
Open

End-to-end group orchestration (tracer bullet)#86
hsubra89 wants to merge 4 commits into
rlph-77-taskgroup-type-github-sub-issue-detection-group-stfrom
rlph-78-end-to-end-group-orchestration-tracer-bullet

Conversation

@hsubra89

Copy link
Copy Markdown
Owner

Resolves #78

Automated implementation by rlph.

- Orchestrator checks for in-progress group before fetching new tasks
- Groups create shared worktree, process one sub-issue per iteration
- Sub-issues marked done (new TaskSource::mark_done) after each commit
- Single PR submitted after all sub-issues complete with multi-resolve body
- Review pipeline runs once after all sub-issues, not after each one
- Parent label transitions: in-progress → in-review
- Sub-issue label transitions: in-progress → done
- Implement prompt includes parent_issue_body for group context
- Standalone issues continue through existing flow unchanged
- Integration tests: group lifecycle, label transitions, PR body,
  state resume, parent body in prompt, standalone regression

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hsubra89

hsubra89 commented Feb 26, 2026

Copy link
Copy Markdown
Owner Author

Review Summary

Overall the implementation is solid — security review is clean and the core group orchestration logic is correct. Two warnings and a handful of style/info items.

Warnings

  • src/orchestrator.rs L671run_group_iteration_start returns Err when no sub-issues are eligible in a brand-new group, but group state and worktree are already persisted at that point. On restart, run_group_iteration_resume handles the same scenario gracefully as Ok(NoEligibleTasks). This inconsistency means a group whose sub-issues are all externally blocked at creation time will crash the orchestrator once, then silently return NoEligibleTasks on every subsequent restart. Return Ok(NoEligibleTasks) in the start path too (or clean up group state on error).
  • src/orchestrator.rs L456 — Awkward clone: standalone_tasks.iter().map(|t| (*t).clone()).collect::<Vec<_>>() → use standalone_tasks.to_vec() or .iter().cloned().collect().

Info

  • src/sources/github.rs L219 — Simplify .map(|si| Self::parse_gql_sub(si)).map(Self::parse_gql_sub).
  • src/sources/github.rs L109 — is_eligible and is_gql_eligible duplicate label-exclusion logic. Extract to a shared const EXCLUSION_LABELS.
  • src/sources/github.rs L125 — parse_gql_issue and parse_gql_sub are near-identical. Consider a shared constructor or From impl.
  • src/sources/github.rs L145 — fetch_eligible_task_groups_impl is pub but only used via the trait. Restrict to pub(crate) or use #[cfg(test)] visibility.
  • src/sources/github.rs L181 — Unnecessary intermediate labeled_children collect — inline with child_ids.extend(...).
  • src/sources/mod.rs L61 — all_sub_issue_ids for Standalone returns vec![task.id.clone()], which is misleading. Consider renaming to all_resolvable_ids or returning empty vec.
  • src/sources/mod.rs L68 — is_complete unused outside tests. Consider #[cfg(test)] gating.
  • src/state.rs L217 — Shadow bindings before the closure are unnecessary; construct inline.
  • src/orchestrator.rs L836 — PR body construction: replace for-loop + vec + join with idiomatic iterator chain.
  • src/orchestrator.rs L710 — run_group_iteration_resume re-fetches get_task_details for ALL sub-issues (including completed) each iteration. Only the next eligible sub-issue details are needed.
  • src/orchestrator.rs L741 — Unnecessary borrow: &worktree_info creates &&WorktreeInfo; pass worktree_info directly.
  • tests/orchestrator_integration.rs L2503 — No integration test covers the NoEligibleTasks flow when sub-issues are blocked by external deps.

hsubra89 and others added 2 commits February 26, 2026 08:47
…cleanup

- Restore DependencyGraph filtering for standalone tasks in run_iteration
- Remove .rlph/config.toml from tracking and restore it in .gitignore
- Distinguish all-complete vs externally-blocked in group resume (no premature finalization)
- Make group finalization idempotent by checking for existing PR before submission
- Clean up imports: add HashSet, DependencyGraph, CurrentGroupState; remove fully-qualified paths
- Set current_task during group review and clean up worktree mapping in finalize_group

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cleanup

1. done_ids now includes externally closed issues at both group-start
   and group-resume sites, so external deps are recognized and
   sub-issues that depend on them become unblocked.
2. finalize_group removes worktree mappings for each sub-issue
   (not just the parent group mapping).
3. Simplified copied().cloned() to iter().map(|t| (*t).clone()).
4. Restored auto-select for single candidate — skips the choose
   agent when only one eligible task/group exists.
5. Updated 4 integration tests to account for auto-select behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hsubra89

Copy link
Copy Markdown
Owner Author

The comment about "auto-select optimization removed" (L508) is inaccurate. Auto-select for single-candidate is present at L486: if groups.len() == 1 { ... }. The choose agent is only invoked when there are 2+ candidates.

…cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant