Test gap, not feature gap. `src/chat_sdk/plan.py` is ported; the TS test suite for it isn't.
What's missing
Upstream `thread.test.ts` has a `[post with Plan]` block with 20+ tests exercising `thread.post(plan)`, `plan.add_task()`, `plan.update_task()`, `plan.complete()`, and error paths. Python has `tests/test_plan.py` but doesn't faithfully mirror the TS test names.
Missing tests (from `verify_test_fidelity.py`):
```
[post with Plan] should post fallback text when adapter does not support plans
[post with Plan] should update via editMessage in fallback mode
[post with Plan] should complete plan via editMessage in fallback mode
[post with Plan] should call adapter postObject when supported
[post with Plan] should add tasks and call editObject
[post with Plan] should update current task with output
[post with Plan] should update a specific task by ID
[post with Plan] should return null when updating by non-existent ID
[post with Plan] should still update last in_progress task when no ID provided
[post with Plan] should complete plan and mark tasks done
[post with Plan] should reset plan and start fresh
[post with Plan] should handle various PlanContent formats in initialMessage
[post with Plan] should ensure sequential edits via queue
[post with Plan] should return null when calling addTask before post
[post with Plan] should return null when calling updateTask before post
[post with Plan] should return null when calling complete before post
[post with Plan] should propagate editObject errors from addTask
[post with Plan] should continue accepting edits after a failed edit
[post with Plan] should set error status via updateTask
```
Impact
We don't know if `plan.py` exercises all error paths correctly. For example, `addTask` / `updateTask` / `complete` called before `post()` — does Python return `None` like TS, or raise? `editObject` errors — do we propagate from `addTask` but continue accepting further edits (matching upstream invariant)?
Without these regression tests, Plan-related port drift happens silently.
Fix
Faithful line-by-line translation following the existing process in `docs/UPSTREAM_SYNC.md`:
- Map TS source file → Python test file (`chat.test.ts` "post with Plan" → `test_thread_faithful.py`)
- Run `verify_test_fidelity.py --fix` to scaffold stubs
- Translate each stub from TS line-by-line, preserving assertions
- Run `verify_test_fidelity.py` to confirm 0 missing under `[post with Plan]`
Acceptance
Test gap, not feature gap. `src/chat_sdk/plan.py` is ported; the TS test suite for it isn't.
What's missing
Upstream `thread.test.ts` has a `[post with Plan]` block with 20+ tests exercising `thread.post(plan)`, `plan.add_task()`, `plan.update_task()`, `plan.complete()`, and error paths. Python has `tests/test_plan.py` but doesn't faithfully mirror the TS test names.
Missing tests (from `verify_test_fidelity.py`):
```
[post with Plan] should post fallback text when adapter does not support plans
[post with Plan] should update via editMessage in fallback mode
[post with Plan] should complete plan via editMessage in fallback mode
[post with Plan] should call adapter postObject when supported
[post with Plan] should add tasks and call editObject
[post with Plan] should update current task with output
[post with Plan] should update a specific task by ID
[post with Plan] should return null when updating by non-existent ID
[post with Plan] should still update last in_progress task when no ID provided
[post with Plan] should complete plan and mark tasks done
[post with Plan] should reset plan and start fresh
[post with Plan] should handle various PlanContent formats in initialMessage
[post with Plan] should ensure sequential edits via queue
[post with Plan] should return null when calling addTask before post
[post with Plan] should return null when calling updateTask before post
[post with Plan] should return null when calling complete before post
[post with Plan] should propagate editObject errors from addTask
[post with Plan] should continue accepting edits after a failed edit
[post with Plan] should set error status via updateTask
```
Impact
We don't know if `plan.py` exercises all error paths correctly. For example, `addTask` / `updateTask` / `complete` called before `post()` — does Python return `None` like TS, or raise? `editObject` errors — do we propagate from `addTask` but continue accepting further edits (matching upstream invariant)?
Without these regression tests, Plan-related port drift happens silently.
Fix
Faithful line-by-line translation following the existing process in `docs/UPSTREAM_SYNC.md`:
Acceptance