Skip to content

test(task-lifecycle): add regression coverage for interrupted-subtask resume (#566)#911

Open
edelauna wants to merge 1 commit into
mainfrom
issue/566
Open

test(task-lifecycle): add regression coverage for interrupted-subtask resume (#566)#911
edelauna wants to merge 1 commit into
mainfrom
issue/566

Conversation

@edelauna

@edelauna edelauna commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #566

Description

Adds regression coverage for issue #566 (subtask fails to return to parent after a manual pause/resume during an API hang). The production fix already shipped on main via #787 (Story 2.4 of #357): cancelTask now marks a cancelled delegated child "interrupted" instead of severing the parent link, and AttemptCompletionTool/reopenParentFromDelegation accept an "interrupted" child when reopening the parent. That fix had only isolated unit tests and a generic (non-hang) e2e interrupt/resume test — nothing exercised the full chain, and nothing specifically reproduced the issue's literal API-hang scenario.

This PR is test-only, no production code changes:

  • src/__tests__/history-resume-delegation.spec.ts — new unit test chaining cancelTask's interrupted-status write → resume → attempt_completion's parent reopen in one test.
  • apps/vscode-e2e/src/fixtures/subtasks.ts / apps/vscode-e2e/src/suite/subtasks.test.ts — new e2e test "API-hung interrupted child resumes and returns to parent" that simulates a hung provider request (15s latency fixture) matching the issue's exact repro, cancels it, resumes it, and asserts the parent regains control.

The e2e test's readiness gate polls the aimock server's /__aimock/journal endpoint to confirm the child's request has actually reached the mock before cancelling, rather than inferring readiness from local state.

Test Procedure

  • pnpm --filter zoo-code test history-resume-delegation (or vitest run history-resume-delegation from src/) — 20 tests pass.
  • e2e: pnpm test:ci:mock in apps/vscode-e2e runs the new "API-hung interrupted child resumes and returns to parent" test alongside the existing subtask suite.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.

Summary by CodeRabbit

  • New Features

    • Added end-to-end coverage for interrupting an in-flight API operation during a subtask and then resuming it successfully.
    • Improved delegated subtask resume behavior so completion correctly returns control to the parent task.
  • Bug Fixes

    • Fixed task history and delegation state transitions during stop/resume and completion flows.
    • Ensured completion and delegation events reflect correct parent-child relationships after resuming.
  • Tests

    • Added new API-interruption and delegation lifecycle tests to validate persisted history fields and emitted events.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds API-hang subtask fixtures and tests manual interruption, child resumption, completion, parent restoration, history transitions, and delegation telemetry.

Changes

Interrupted subtask resume

Layer / File(s) Summary
API-hang fixture routing
apps/vscode-e2e/src/fixtures/subtasks.ts
Adds API-hang markers, prompts, results, delayed child responses, sequential completion fixtures, and parent-resume matching.
End-to-end interruption and resume
apps/vscode-e2e/src/suite/subtasks.test.ts
Adds Aimock journal polling, cancels and resumes the child, and verifies completion results and parent-child history state.
Delegation history completion
src/__tests__/history-resume-delegation.spec.ts
Mocks completion telemetry and verifies resumed child completion restores the parent, clears delegation state, and emits lifecycle events.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: awaiting-review

Suggested reviewers: taltas

Sequence Diagram(s)

sequenceDiagram
  participant ParentTask
  participant Aimock
  participant ChildTask
  participant TaskHistory
  ParentTask->>Aimock: request API-hang child
  Aimock-->>ChildTask: keep provider request pending
  ChildTask->>TaskHistory: record interrupted status with parent link
  ParentTask->>ChildTask: resume interrupted child
  ChildTask->>TaskHistory: record completed child and clear awaitingChildId
  ChildTask->>ParentTask: restore parent control
  ParentTask->>TaskHistory: record parent completion
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: regression test coverage for interrupted-subtask resume.
Description check ✅ Passed The description includes the linked issue, change summary, test procedure, and checklist items required by the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/566

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@edelauna edelauna changed the title test(task-lifecycle): add regression coverage for issue #566 (interru… test(task-lifecycle): add regression coverage for interrupted-subtask resume (#566) Jul 17, 2026
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@edelauna
edelauna marked this pull request as ready for review July 17, 2026 02:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/vscode-e2e/src/suite/subtasks.test.ts`:
- Around line 44-57: Update waitForAimockRequestContaining to match only the
intended child request: require the child marker and exclude
SUBTASK_API_HANG_CHILD_MARKER’s parent prompt marker, or use an equivalent
child-only probe. Ensure the polling cannot succeed from older or parent journal
entries before the delayed child request reaches Aimock.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc9b3a62-8a2d-468c-967b-158aef16c7df

📥 Commits

Reviewing files that changed from the base of the PR and between 367013f and 2b26cac.

📒 Files selected for processing (3)
  • apps/vscode-e2e/src/fixtures/subtasks.ts
  • apps/vscode-e2e/src/suite/subtasks.test.ts
  • src/__tests__/history-resume-delegation.spec.ts

Comment thread apps/vscode-e2e/src/suite/subtasks.test.ts Outdated
@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 17, 2026
@github-actions github-actions Bot removed the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/vscode-e2e/src/fixtures/subtasks.ts (1)

199-231: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Use a predicate to exclude the parent marker to prevent unintended matches.

Because SUBTASK_API_HANG_PARENT_PROMPT embeds SUBTASK_API_HANG_CHILD_MARKER verbatim, checking for the child marker using userMessage: apiHangChildMatch risks intercepting the parent's turns (such as the parent resume request, which also has a sequenceIndex of 1). This is the exact same failure mode documented and fixed below for Issue #561.

Even if the current tests pass due to fixture ordering or sequence counting artifacts, this approach is fragile and violates the established pattern for handling embedded markers.

♻️ Proposed refactor

Replace userMessage with a predicate that explicitly excludes the parent marker, matching the pattern used in the XPROFILE and INTERRUPT fixtures:

 	mock.addFixture({
 		match: {
-			userMessage: apiHangChildMatch,
+			predicate: (req: ChatCompletionRequest) =>
+				requestContains(req, [SUBTASK_API_HANG_CHILD_MARKER]) &&
+				!requestContains(req, [SUBTASK_API_HANG_PARENT_MARKER]),
 			sequenceIndex: 0,
 		},
 		// Keep the first child response pending long enough for the e2e test to cancel an in-flight API request.
 		latency: 15_000,
 		response: {
 			toolCalls: [
 				{
 					name: "attempt_completion",
 					arguments: JSON.stringify({ result: SUBTASK_API_HANG_CHILD_RESULT }),
 					id: "call_api_hang_child_completion_002",
 				},
 			],
 		},
 	})

 	mock.addFixture({
 		match: {
-			userMessage: apiHangChildMatch,
+			predicate: (req: ChatCompletionRequest) =>
+				requestContains(req, [SUBTASK_API_HANG_CHILD_MARKER]) &&
+				!requestContains(req, [SUBTASK_API_HANG_PARENT_MARKER]),
 			sequenceIndex: 1,
 		},
 		response: {

You can then also safely remove the unused apiHangChildMatch regex definition on line 42.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/vscode-e2e/src/fixtures/subtasks.ts` around lines 199 - 231, Update both
fixtures using apiHangChildMatch in the subtasks fixture setup to use a
predicate that matches the child marker while explicitly excluding
SUBTASK_API_HANG_PARENT_PROMPT, following the existing XPROFILE and INTERRUPT
fixture pattern. Remove the now-unused apiHangChildMatch regex definition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/vscode-e2e/src/fixtures/subtasks.ts`:
- Around line 199-231: Update both fixtures using apiHangChildMatch in the
subtasks fixture setup to use a predicate that matches the child marker while
explicitly excluding SUBTASK_API_HANG_PARENT_PROMPT, following the existing
XPROFILE and INTERRUPT fixture pattern. Remove the now-unused apiHangChildMatch
regex definition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b10afc3e-3628-48aa-af0b-c6b16c7cdc78

📥 Commits

Reviewing files that changed from the base of the PR and between 2b26cac and ec44fd2.

📒 Files selected for processing (3)
  • apps/vscode-e2e/src/fixtures/subtasks.ts
  • apps/vscode-e2e/src/suite/subtasks.test.ts
  • src/__tests__/history-resume-delegation.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tests/history-resume-delegation.spec.ts
  • apps/vscode-e2e/src/suite/subtasks.test.ts

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Subtask fails to return to parent task after manual pause and resume during API hang

2 participants