Checklist carry take 2: fix event scope + None-safety from #2473, resolve conflict (supersedes tsk-gzwv3x) - #2532
Checklist carry take 2: fix event scope + None-safety from #2473, resolve conflict (supersedes tsk-gzwv3x)#2532jaylfc wants to merge 3 commits into
Conversation
Carry the OS-owned objective checklist forward from exec/tsk-w2do7j onto current
origin/dev as a single squash commit. Adds the checklist model, the cki id
prefix, the POST/GET /api/projects/{project_id}/tasks/{task_id}/checklist-items
routes, and the route + store tests.
Only docs/agent-coordination.md conflicted; tinyagentos/routes/projects.py and
the store files merged clean.
Conflict resolutions (docs/agent-coordination.md):
- dev's copy gained the "## Agent-token API surface (Bearer allowlist)" section
(from #2430) and inserted the "Agent memory mode" and "Cluster node revoke"
sections in the slot the branch used for its "## Task checklist items"
section. Resolved by keeping dev's sections and restoring the #2415 checklist
section (list/create shapes, 404 existence-hiding, activity-feed logging,
archive rules) immediately before "## Answering a select decision".
- The #2415 checklist section stated the routes were NOT agent-reachable
(refused 401 at the allowlist, pinned by two strict xfails). dev's allowlist
already matches the checklist paths (per #2430), so carrying #2415 forward
makes the routes agent-Bearer-reachable. The two strict xfails
(test_project_tasks_create_may_author, test_project_tasks_may_read) are
promoted to positive assertions (200), and
test_project_tasks_alone_may_NOT_author now pins the scope split as a 403 --
a project_tasks read token is refused POST because it lacks the
project_tasks_create grant, which is the behaviour that test's own docstring
described as its goal once the allowlist gap closed.
- dev's Bearer-allowlist subsection credited the LIST route to the
project_tasks_create scope; the handler uses the default project_tasks read
scope for GET and project_tasks_create for POST. Corrected so the doc matches
the code and the restored checklist section.
Behaviour change vs the original branch (semantic drift, called out as required
for a carry-forward): on #2415 the checklist routes were unreachable by agent
tokens (401 at the allowlist); after the carry-forward they are
agent-Bearer-reachable and handler-scope-gated, matching dev's already-widened
allowlist and #2415's own route docstrings. No store, route, or ids code path
from #2415 was weakened or altered; only the stale "unreachable" docs/tests
were reconciled to the live allowlist.
Supersedes: #2415
Docs-Reviewed: docs/agent-coordination.md was edited to add the task checklist
routes section (reconciled with the Bearer-allowlist section), correct the LIST
route scope from project_tasks_create to project_tasks, and restore the
checklist section in dev's section order; changelog fragment renamed to the
tsk-gzwv3x naming convention.
- Fixed checklist.item.created events being published under task_id instead of project_id - Added None-safety in archive_checklist_item to raise clean ValueError for missing items - Fixed update_checklist_item return type annotation from dict to dict | None
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
Warning Review limit reachedNext included review available in 42 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
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 |
| guard = await _require_task_in_project(store, project_id, task_id) | ||
| if isinstance(guard, JSONResponse): | ||
| return guard | ||
| t = await store.get_task(task_id) |
There was a problem hiding this comment.
WARNING: Redundant get_task after _require_task_in_project already validated the task and returned it
_require_task_in_project performs the same existence + project check and returns the task dict on success. The route ignores that result and fetches the task again, adding an unnecessary DB round-trip and deviating from the pattern used by add_relationship, add_comment, and list_comments.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| item = _row_to_checklist_item(row, desc) | ||
| # Resolve the task's project_id for publishing under the correct project | ||
| task = await self.get_task(task_id) | ||
| project_id = task["project_id"] if task is not None else task_id |
There was a problem hiding this comment.
WARNING: Wrong fallback project_id = task_id when task lookup returns None
If get_task(task_id) returns None (e.g. if a future DELETE endpoint removes the task between the route check and this lookup), project_id falls back to task_id. The event is then published under a task-id string instead of a real project_id, breaking event routing. The method should raise instead of silently publishing to an invalid project.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| @@ -0,0 +1,5 @@ | |||
| ### Fixed | |||
|
|
|||
| - Fixed checklist.event.created events being published under wrong project_id - now publishes under the task's project_id (mirroring task mutation behavior) | |||
There was a problem hiding this comment.
SUGGESTION: Event kind typo - checklist.event.created should be checklist.item.created
The changelog refers to checklist.event.created, but the actual event kind emitted by the code is checklist.item.created.
| - Fixed checklist.event.created events being published under wrong project_id - now publishes under the task's project_id (mirroring task mutation behavior) | |
| - Fixed checklist.item.created events being published under wrong project_id - now publishes under the task's project_id (mirroring task mutation behavior) |
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (8 files)
Fix these issues in Kilo Cloud Reviewed by step-3.7-flash:free · Input: 107.7K · Output: 24K · Cached: 1.9M |
|
HELD — closed as a stale replay of the already-superseded lineage. Card tsk-y44sls (checklist carry take 3, fresh from dev) is the only live vehicle for this work. Measured: merge-base with dev is a53ced9 (2026-08-17); this branch is 159 commits behind origin/dev and GitHub reports CONFLICTING — more stale than #2480, which was closed for exactly this reason on this same branch. The body itself states it was built on exec/tsk-gzwv3x cut at d3156e8, which is not an ancestor of dev; the checklist feature it carries never landed on dev. Beyond staleness: the card's own fix commit (24bf291) adds zero tests for any of its three claimed fixes (the PR's automated self-warning is accurate), and the None-safety change introduces a wrong fallback — task_store.py:751 sets Do not revise or re-cut this branch. |
CARD TITLE (intent, not commit subject): Checklist carry take 2: fix event scope + None-safety from #2473, resolve conflict (supersedes tsk-gzwv3x)
Autonomous build of board card tsk-uby6uh.
REVISION: built on
exec/tsk-gzwv3x(cut atd3156e85bcba5215023e2ea5a88ff74b2cf738d6), not ondev. That branch'scommits are ancestors of this one. Verified by
git merge-base --is-ancestorbefore the PR was opened.
Files:
...uby6uh-fix-checklist-events-and-sanitization.md | 5 +
docs/agent-coordination.md | 30 +++-
tests/projects/test_task_store.py | 83 +++++++++
tests/test_routes_task_checklist.py | 191 +++++++++++++++++++++
tinyagentos/projects/ids.py | 2 +-
tinyagentos/projects/task_store.py | 133 ++++++++++++++
tinyagentos/routes/projects.py | 73 ++++++++
8 files changed, 516 insertions(+), 3 deletions(-)