fix-forward #2622: archive_checklist_item still publishes under task_id in its fallback, contradicting its own docstring (tsk-s5pif2) - #2788
Conversation
…s gone (tsk-s5pif2)
task_checklist_items.task_id declares REFERENCES project_tasks(id), but
ProjectTaskStore never issues PRAGMA foreign_keys = ON, so SQLite does not
enforce it and a checklist item can outlive its task. Both create and archive
then fell back to publishing their broker event under a topic that is not a
project_id, and since project subscribers subscribe at project scope only, the
event went to a channel nobody listens to and was silently lost.
Resolve the parent task before either path mutates and raise
ValueError("task not found: <task_id>") when it is missing, so a refusal
leaves neither an orphan row nor a half-applied archive, and the publish
topic is always the task's real project_id.
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughChecklist item creation and archiving now verify that the parent task exists before changing storage or publishing events. Tests cover missing tasks, unchanged archive state, absent orphan rows, and suppressed invalid-topic events. Documentation and changelog entries describe the behavior. ChangesChecklist orphan-task guards
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to Checklist creation and archiving now reject missing parent tasks before changing data and publish successful events under the task project. The covered missing-task behavior prevents orphaned changes and lost events, with no remaining merge-blocking risk identified. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. Comment |
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Reviewed all 4 changed files. The fix is well-scoped: parent task resolution is moved before the mutation in both Files Reviewed (4 files)
Reviewed by minimax-m3:free · Input: 26.7K · Output: 4.4K · Cached: 325.5K |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
CARD TITLE (intent, not commit subject): fix-forward #2622: archive_checklist_item still publishes under task_id in its fallback, contradicting its own docstring
Autonomous build of board card tsk-s5pif2.
BASE: exec/tsk-pa2zau
Supersedes #2622
Base correction (please read first)
The card's
BASE: exec/tsk-pa2zauis dead. PR #2622 was closed unmerged(
mergedAt: null), and its head237dcd37fis not an ancestor ofdev.The checklist feature reached
devthrough a different carry (#2674,79a5f12e5),so the create-path fix #2622 was cut to make never landed. Building on
exec/tsk-pa2zauwould have replayed a stale tree against a base that has moved147 commits on. This branch is therefore cut from
origin/dev(b8f7726ea).That changes what the defect looks like, but not that it is real:
exec/tsk-pa2zaudevcreate_checklist_itemfallbackproject_id = ... else ""archive_checklist_itemfallbackelse item["task_id"]else ""So on
devboth siblings still resolve the publish topic to something thatis not a
project_id. The card's premise ("create was fixed to raise, archivekept the fallback") does not hold on
dev— neither was fixed — and the card'sFIX ("make the archive path raise, exactly as create does") cannot be satisfied
by copying create, because create does not raise either. Both are fixed here.
The reachability the card asserts is confirmed verbatim on
dev:task_checklist_items.task_iddeclaresREFERENCES project_tasks(id), andProjectTaskStorenever issuesPRAGMA foreign_keys = ON(grep for the pragmahits
mcp/registry.py,shared_folders.py,relationships.py,library_store.py,secrets.py— neverprojects/task_store.py). A checklistitem can outlive its task, and
ProjectEventBrokerkeys one channel perproject_id, so the event lands where nobody is subscribed and is silently lost.What changed
tinyagentos/projects/task_store.pycreate_checklist_itemresolves the parent task before the INSERT andraises
ValueError: task not found: <task_id>when it is missing, so arefusal cannot leave an orphan row behind. The publish now uses
task["project_id"]unconditionally — theelse ""fallback is gone.archive_checklist_itemresolves the parent task before the UPDATE, withthe same raise, so a refusal leaves the item un-archived rather than
half-applying the mutation and then losing its event. Same fallback removal.
project_ida project subscriber can be reached at) instead of asserting aguarantee the code did not have.
tests/projects/test_task_store.pyunder a live, verified+reported checklist item (
_delete_task_row, which isonly possible because the FK is unenforced), then asserts no event reached
either dead topic —
""(thedevfallback) or thetask_id(thepre-fix-forward #2606: checklist create publishes under task_id in its fallback branch - the defect the PR closes, kept behind a comment saying it cannot happen #2622 one) — that the call raised, and that
archivedstayedFalse.The create one does the same against a task id that never existed and asserts
no row was inserted.
pytest.raiseson purpose: with
pytest.raisesfirst, the topic assertion is unreachable ona red run and the failure reads "DID NOT RAISE", which is exactly the
"asserting archive returns 200 cannot fail" shape the card rules out. In this
order the assertion that goes red is the one naming the wrong topic and the
event that went to it.
RED FIRST (pasted)
Run at the base source (
git checkout origin/dev -- tinyagentos/projects/task_store.py,new tests in place):
The failing assertion is the topic one, and it names the event and the channel
it was misrouted to — the mutation is what makes it fail, per the card's
"ACCEPTANCE MUST MUTATE".
GREEN
Also run on the fix:
Docs
docs/agent-coordination.md— the "Task checklist items" section under theBearer-allowlist surface documented the routes and the verified+reported
archive precondition but said nothing about the publish topic. It now records
that both
checklist.item.createdandchecklist.item.archivedgo out underthe task's
project_id, that the store raisestask not foundwhen the taskis gone, and why the unenforced foreign key makes that state reachable.
changelog.d/tsk-s5pif2-checklist-orphan-task-publish.md— new fragment.Summary by CodeRabbit
Bug Fixes
Documentation