mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(gateway): thread agent_team through all 27 lifecycle Context sites
Arms the team-match spec gate that sat in its permissive fallback since shipping: cell-scoped roles are now rejected on cross-team verbs at the gateway (a misrouted frontend PM blocked, escalated, and held a backend task live 2026-07-02). Org-wide roles remain exempt via the policy-side _ORG_WIDE_ROLES. Test mocks aligned to carry consistent teams.
This commit is contained in:
@@ -1437,6 +1437,7 @@ class Choreographer:
|
||||
plan=effective_plan,
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
ctx = _ClaimPlanStartContext(
|
||||
@@ -1680,6 +1681,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
if rejection := self._open_pr_preflight_rejection(
|
||||
@@ -1878,6 +1880,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=notes,
|
||||
)
|
||||
@@ -3295,6 +3298,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=reason,
|
||||
)
|
||||
@@ -3388,6 +3392,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "unclaim", t, spec_ctx)
|
||||
@@ -3543,6 +3548,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "reassign", t, spec_ctx)
|
||||
@@ -3630,6 +3636,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "resume", t, spec_ctx)
|
||||
@@ -3799,6 +3806,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "sync_branch", t, spec_ctx)
|
||||
if not decision.allowed:
|
||||
@@ -4293,6 +4301,7 @@ class Choreographer:
|
||||
plan=effective_plan,
|
||||
actor_id=pm_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
ctx = _ClaimPlanStartContext(
|
||||
@@ -4393,6 +4402,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=pm_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(parent),
|
||||
)
|
||||
soup = self._free_text_soup(
|
||||
@@ -5587,6 +5597,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=pm_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=notes,
|
||||
)
|
||||
@@ -6522,6 +6533,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=main_pm_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
notes=notes,
|
||||
)
|
||||
soup = self._free_text_soup(checks=(("notes", notes, 10),))
|
||||
@@ -6873,6 +6885,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
if soup := await self._guard_free_text(
|
||||
@@ -7011,6 +7024,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=pm_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=notes,
|
||||
issues=tuple(issues),
|
||||
@@ -7081,6 +7095,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=pm_agent_id,
|
||||
actor_slug=getattr(me, "slug", None) if me is not None else None,
|
||||
agent_team=str(me.team) if me is not None and me.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=reason,
|
||||
)
|
||||
@@ -7251,6 +7266,7 @@ class Choreographer:
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=agent_id,
|
||||
actor_slug=getattr(me, "slug", None) if me is not None else None,
|
||||
agent_team=str(me.team) if me is not None and me.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=reason,
|
||||
)
|
||||
|
||||
@@ -125,6 +125,7 @@ class DocMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=doc_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "claim_doc_task", t, spec_ctx)
|
||||
@@ -374,10 +375,21 @@ class DocMixin(_Base):
|
||||
task_id=task_id,
|
||||
verb="i_documented",
|
||||
)
|
||||
return rejection, agent, role_str, spec_module.Context(), briefing
|
||||
return (
|
||||
rejection,
|
||||
agent,
|
||||
role_str,
|
||||
spec_module.Context(
|
||||
agent_team=str(agent.team)
|
||||
if agent is not None and agent.team
|
||||
else None
|
||||
),
|
||||
briefing,
|
||||
)
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=doc_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(owned_task),
|
||||
notes=notes,
|
||||
files=tuple(files),
|
||||
|
||||
@@ -71,6 +71,7 @@ class PRGateMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=reviewer_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "claim_gate_review", t, spec_ctx)
|
||||
if not decision.allowed:
|
||||
@@ -207,6 +208,7 @@ class PRGateMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=reviewer_agent_id,
|
||||
actor_slug=str(reviewer_agent_id),
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=markers.get_original_developer(t),
|
||||
notes=notes,
|
||||
issues=issues,
|
||||
|
||||
@@ -74,6 +74,7 @@ class PRReviewerMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=reviewer_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "claim_pr_review", t, spec_ctx)
|
||||
if not decision.allowed:
|
||||
@@ -328,6 +329,7 @@ class PRReviewerMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=reviewer_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
notes=body,
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "post_pr_review", t, spec_ctx)
|
||||
|
||||
@@ -131,6 +131,7 @@ class QAMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=qa_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
)
|
||||
decision = spec_module.can_invoke_intent(role, "claim_review", t, spec_ctx)
|
||||
@@ -328,6 +329,7 @@ class QAMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=qa_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=inputs.notes,
|
||||
issues=inputs.issues,
|
||||
@@ -554,6 +556,7 @@ class QAMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=qa_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=self._merge_ac_verdicts_into_notes(notes, ac_verdicts),
|
||||
)
|
||||
@@ -648,6 +651,7 @@ class QAMixin(_Base):
|
||||
spec_ctx = spec_module.Context(
|
||||
actor_id=qa_agent_id,
|
||||
actor_slug=getattr(agent, "slug", None) if agent is not None else None,
|
||||
agent_team=str(agent.team) if agent is not None and agent.team else None,
|
||||
original_developer_slug=_extract_original_developer(t),
|
||||
notes=notes,
|
||||
issues=tuple(issues),
|
||||
|
||||
@@ -85,6 +85,7 @@ def _dev_task_svc(agent_id: object, task_id: object) -> AsyncMock:
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
task_type="code",
|
||||
|
||||
@@ -235,7 +235,7 @@ async def test_submit_up_blocks_when_subtask_pending() -> None:
|
||||
sub = MagicMock(id=sub_id, status="paused", title="Paused subtask")
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(role="cell_pm")
|
||||
task_svc.agent_for.return_value = MagicMock(role="cell_pm", team="backend")
|
||||
task_svc.all_subtasks_terminal.return_value = False
|
||||
task_svc.get_subtasks.return_value = [sub]
|
||||
journal_svc = AsyncMock()
|
||||
|
||||
@@ -109,6 +109,7 @@ async def test_delegate_blocks_when_parent_assigned_to_other_agent() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=other_pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
task_svc = AsyncMock()
|
||||
@@ -134,6 +135,7 @@ async def test_delegate_allows_when_parent_in_progress_and_owned() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
new_task = MagicMock(id=uuid4())
|
||||
@@ -162,6 +164,7 @@ async def test_delegate_blocks_when_subtask_cap_exceeded() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
too_many = [MagicMock(id=uuid4()) for _ in range(13)]
|
||||
@@ -189,6 +192,7 @@ async def test_delegate_allows_when_subtask_cap_within_soft_zone() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
many = [MagicMock(id=uuid4()) for _ in range(10)]
|
||||
@@ -217,6 +221,7 @@ async def test_delegate_allows_at_zero_subtasks() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
new_task = MagicMock(id=uuid4())
|
||||
@@ -243,6 +248,7 @@ async def test_delegate_blocks_at_exact_cap_plus_one() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
# Already 12 children — adding the 13th must be blocked.
|
||||
@@ -272,6 +278,7 @@ async def test_delegate_blocks_when_parent_quick_context_empty() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="",
|
||||
)
|
||||
task_svc = AsyncMock()
|
||||
@@ -304,6 +311,7 @@ async def test_delegate_past_max_depth_returns_invalid_state_not_500() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
depth_msg = (
|
||||
|
||||
@@ -136,6 +136,7 @@ async def test_i_will_work_on_pending_with_plan() -> None:
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
task_type="code",
|
||||
@@ -338,6 +339,7 @@ async def test_i_will_work_on_blocks_when_journal_note_at_claim_missing() -> Non
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
task_type="code",
|
||||
|
||||
@@ -632,6 +632,7 @@ async def test_delegate_parent_no_project_rejected() -> None:
|
||||
parent = MagicMock(
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
project_id=None,
|
||||
product_id=None,
|
||||
title="p",
|
||||
|
||||
@@ -757,7 +757,7 @@ async def test_complete_dispatches_cell_pm() -> None:
|
||||
after = MagicMock(**{**t.__dict__, "status": "completed"})
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(role="cell_pm")
|
||||
task_svc.agent_for.return_value = MagicMock(role="cell_pm", team="backend")
|
||||
task_svc.all_subtasks_terminal.return_value = True
|
||||
task_svc.cell_pm_complete.return_value = after
|
||||
git_svc = AsyncMock()
|
||||
|
||||
@@ -79,6 +79,7 @@ async def test_i_will_plan_claims_starts_and_sets_plan() -> None:
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
@@ -164,6 +165,7 @@ async def test_i_will_plan_blocks_when_journal_decision_at_claim_missing() -> No
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
@@ -715,6 +717,7 @@ async def test_delegate_cell_pm_to_team_dev_creates_subtask() -> None:
|
||||
project_id=project_id,
|
||||
status="in_progress",
|
||||
assigned_to=cell_pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
new_task = MagicMock(id=uuid4())
|
||||
@@ -862,6 +865,7 @@ async def test_delegate_invalid_team_enum_rejected() -> None:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
task_svc = AsyncMock()
|
||||
@@ -1013,7 +1017,7 @@ async def test_submit_up_blocks_without_journal_decision() -> None:
|
||||
async def test_submit_up_short_notes_rejected() -> None:
|
||||
pm_id = uuid4()
|
||||
task_id = uuid4()
|
||||
t = MagicMock(id=task_id, status="in_progress", assigned_to=pm_id)
|
||||
t = MagicMock(id=task_id, status="in_progress", assigned_to=pm_id, team="backend")
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(role="cell_pm", team="backend")
|
||||
|
||||
@@ -277,6 +277,7 @@ async def test_i_will_plan_calls_claim_and_start_with_task_id_first() -> None:
|
||||
status="pending",
|
||||
plan=None,
|
||||
assigned_to=None,
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
|
||||
@@ -61,6 +61,7 @@ def _parent_in_progress(pm_id: Any) -> MagicMock:
|
||||
project_id=uuid4(),
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
priority=2,
|
||||
# delegate obligates the PM's quick_context resumption section.
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
|
||||
@@ -60,6 +60,7 @@ def _parent(pm_id: object) -> MagicMock:
|
||||
product_id=None,
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
# delegate obligates the PM's quick_context resumption section.
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
|
||||
@@ -48,6 +48,7 @@ def _parent(pm_id: Any, product_id: Any = None, project_id: Any = None) -> Magic
|
||||
product_id=product_id,
|
||||
status="in_progress",
|
||||
assigned_to=pm_id,
|
||||
team="backend",
|
||||
# delegate obligates the PM's quick_context resumption section.
|
||||
quick_context="Decomposition planned; cells implement their slice next.",
|
||||
)
|
||||
|
||||
@@ -59,7 +59,7 @@ def _make_deps(**overrides: Any) -> ChoreographerDeps:
|
||||
async def test_resume_transitions_paused_to_in_progress() -> None:
|
||||
aid = uuid4()
|
||||
tid = uuid4()
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=aid)
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=aid, team="backend")
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(
|
||||
@@ -108,7 +108,7 @@ async def test_resume_rejects_when_not_claimant() -> None:
|
||||
aid = uuid4()
|
||||
other = uuid4()
|
||||
tid = uuid4()
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=other)
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=other, team="backend")
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(
|
||||
@@ -177,7 +177,7 @@ async def test_resume_success_writes_heartbeat() -> None:
|
||||
"""Heartbeat fires on success — agent is back to active work."""
|
||||
aid = uuid4()
|
||||
tid = uuid4()
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=aid)
|
||||
t = MagicMock(id=tid, status="paused", assigned_to=aid, team="backend")
|
||||
task_svc = AsyncMock()
|
||||
task_svc.get.return_value = t
|
||||
task_svc.agent_for.return_value = MagicMock(
|
||||
|
||||
@@ -182,7 +182,7 @@ async def test_i_will_plan_calls_ensure_work_session() -> None:
|
||||
commits=[],
|
||||
pr_number=None,
|
||||
quick_context=None,
|
||||
team="main_pm",
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
@@ -199,7 +199,7 @@ async def test_i_will_plan_calls_ensure_work_session() -> None:
|
||||
commits=[],
|
||||
pr_number=None,
|
||||
quick_context=None,
|
||||
team="main_pm",
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
parent_task_id=None,
|
||||
sequence=0,
|
||||
|
||||
Reference in New Issue
Block a user