Skip to content

feat(todo): add agent tools for todo lists, remove notes_set_done#2035

Open
hognek wants to merge 7 commits into
jaylfc:devfrom
hognek:feat/1923-notes-todo-agent-tools
Open

feat(todo): add agent tools for todo lists, remove notes_set_done#2035
hognek wants to merge 7 commits into
jaylfc:devfrom
hognek:feat/1923-notes-todo-agent-tools

Conversation

@hognek

@hognek hognek commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Task: #1923 C3 \u2014 Agent tools for Notes/Todo split.

Changes

  • New: tinyagentos/tools/todo_tools.py with execute_todo_list_lists, execute_todo_add_item, execute_todo_set_done
  • New: tinyagentos/todo/notify.py \u2014 notification placeholder for when collaboration lands on TodoStore
  • New: tests/todo/test_todo_tools.py \u2014 17 tests covering list/add/set_done with owner-based access control
  • Removed: execute_notes_set_done from notes_tools.py (set_done now lives on TodoStore)
  • Removed: notes_set_done tests from tests/notes/test_notes_tools.py (11 remaining tests pass)
  • Updated: skill_exec.py \u2014 replaced _skill_notes_set_done with _skill_todo_list_lists/_skill_todo_add_item/_skill_todo_set_done
  • Updated: skills.py \u2014 replaced notes_set_done skill seed with 3 todo skills

Tests

  • pytest tests/todo/test_todo_tools.py -v --timeout=120 \u2014 17/17 pass
  • pytest tests/notes/test_notes_tools.py -v --timeout=120 \u2014 11/11 pass
  • pytest tests/todo/test_todo_routes.py -v --timeout=120 \u2014 36/36 pass (no regressions)

Design note

TodoStore uses owner-based access control (no agent membership yet). The owner_user_id arg gates access \u2014 agents must present a matching owner to list/add/set-done. When collaboration lands on TodoStore (C1 follow-up), this will shift to member-based permission checks. The notification path (todo/notify.py) is a no-op placeholder ready for that upgrade.

Summary by CodeRabbit

  • New Features

    • Added built-in todo skills for listing lists, adding items, and marking items complete or incomplete.
    • Added owner-based access controls and validation for todo operations.
    • Added support for archived and missing-list handling with clear errors.
    • Added notification scaffolding for todo updates.
  • Changes

    • Removed the notes completion skill; notes now support listing shared documents and adding entries only.
  • Tests

    • Added comprehensive coverage for todo list and item operations, permissions, validation, and error handling.

@hognek
hognek marked this pull request as ready for review July 19, 2026 09:15
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@hognek, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e80b2435-4cfa-4401-a05d-33044a691c37

📥 Commits

Reviewing files that changed from the base of the PR and between 535b9f0 and 4c89156.

📒 Files selected for processing (8)
  • tests/notes/test_notes_tools.py
  • tests/test_routes_github.py
  • tests/todo/test_todo_tools.py
  • tinyagentos/routes/skill_exec.py
  • tinyagentos/skills.py
  • tinyagentos/todo/notify.py
  • tinyagentos/tools/notes_tools.py
  • tinyagentos/tools/todo_tools.py
📝 Walkthrough

Walkthrough

Changes

Todo skill migration

Layer / File(s) Summary
Todo tool behavior and coverage
tinyagentos/tools/todo_tools.py, tinyagentos/todo/notify.py, tests/todo/*
Adds todo list, item, and completion tools with ownership, archive, resource, and input validation, plus persistence and notification handling tests.
Todo skill registration
tinyagentos/skills.py, tinyagentos/routes/skill_exec.py
Registers the three todo skills and maps them to their runtime implementations.
Notes completion retirement
tinyagentos/tools/notes_tools.py, tests/notes/test_notes_tools.py
Removes the notes completion handler and its associated test coverage.

GitHub test fixture

Layer / File(s) Summary
Key-aware secret mock
tests/test_routes_github.py
Updates the mocked secret lookup to return values based on the requested key.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant SkillExecution
  participant TodoTools
  participant TodoStore
  participant TodoNotifications
  Agent->>SkillExecution: invoke todo skill
  SkillExecution->>TodoTools: delegate operation
  TodoTools->>TodoStore: read or update todo data
  TodoTools->>TodoNotifications: trigger add-item notifications
  TodoTools-->>Agent: return structured result
Loading

Possibly related PRs

Suggested reviewers: jaylfc

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding todo agent tools and removing notes_set_done.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 unit tests (beta)
  • Create PR with unit tests

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.

@gitar-bot

gitar-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

Gitar is working

Gitar


try:
store = request.app.state.todo_store
lists = await store.list_lists(owner_user_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: agent_name is never used to authorize the list read — any agent can enumerate another user's todo lists by supplying an arbitrary owner_user_id.

Unlike execute_notes_list_shared_docs (which filters via docs_for_agent(agent_name)), this returns list_lists(owner_user_id) for whatever id the caller passes. There is no check that the calling agent is associated with that owner, so any agent that guesses/learns another user's user_id can read their private lists. This is the same gap flagged across the todo tools (see below). If this is intentional for the "owner-based, no membership yet" phase, please document the trust boundary explicitly and tighten it once C1 collaboration lands.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

return {"error": "list not found"}
if doc.get("archived_at") is not None:
return {"error": "list is archived"}
if doc.get("owner_user_id") != owner_user_id:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Access gate is doc.get("owner_user_id") != owner_user_id only — the supplied owner_user_id is trusted verbatim, with no binding to agent_name.

Any agent that knows a victim's user_id can add items to that user's list. There is no membership/permission check analogous to notes_tools (agent_members + permission level). The agent_name parameter is validated as a string but otherwise unused for authorization here. Consider binding the agent to a verified owner/tenant context rather than accepting the owner id from the agent payload.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

return {"error": "list not found"}
if doc.get("archived_at") is not None:
return {"error": "list is archived"}
if doc.get("owner_user_id") != owner_user_id:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Same owner-id-only authorization gap as execute_todo_add_item (line 64). The owner_user_id is caller-supplied and never tied to agent_name, so any agent knowing a user id can toggle completion on that user's items.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread tinyagentos/tools/todo_tools.py Outdated
try:
store = request.app.state.todo_store
lists = await store.list_lists(owner_user_id)
return {"lists": lists}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: execute_todo_list_lists returns the full list rows, leaking internal fields (owner_user_id, archived_at, created_at) to the agent. The skill schema description advertises only id, title, updated_at. The notes equivalent (notes_list_shared_docs) explicitly strips owner_user_id (see tests/notes/test_notes_tools.py which asserts owner_user_id not in keys). Consider projecting a safe subset here too.

Suggested change
return {"lists": lists}
lists = await store.list_lists(owner_user_id)
return {"lists": [{k: l[k] for k in ("id", "title", "updated_at") if k in l} for l in lists]}

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No new issues found | Recommendation: Merge (pending real CI green at current head)

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0
Scope note — HEAD advanced by dev-branch churn, not PR changes

The PR was rebased onto a new base (a3ef7f77) since the previous review (43696ce). A raw 43696ce..HEAD diff appears large, but that delta is dev-branch churn from already-merged PRs (#2040, #2049, #2051, #2052, #2053, #2055, #2041) — e.g. desktop/.../MessageList.test.tsx, ThreadPanel.test.tsx, MessageInput.test.tsx, docs/contributor-pitfalls.md, tinyagentos/routes/github.py, tinyagentos/routes/todo.py, tinyagentos/todo/todo_store.py. These are not part of PR #2035 and were not reviewed as this PR's changes.

PR #2035's own diff (a3ef7f77..HEAD) is the expected 8 files: tinyagentos/tools/todo_tools.py, tinyagentos/todo/notify.py, tinyagentos/skills.py, tinyagentos/routes/skill_exec.py, tinyagentos/tools/notes_tools.py, tests/todo/test_todo_tools.py, tests/notes/test_notes_tools.py, tests/test_routes_github.py. Comparing 43696ce..HEAD restricted to these files yields no content change — the PR-owned code is byte-identical to the previously reviewed revision.

Previously flagged issues — status at current HEAD (RESOLVED in code)

The three IDOR-style WARNINGs on tinyagentos/tools/todo_tools.py (lines 60 / 106 / 164) flagged that owner_user_id was trusted verbatim and never bound to agent_name. Current code resolves this: _resolve_owner_user_id (lines 17-37) binds agent_name to a registry-verified user_id via request.app.state.agent_registry and overrides any caller-supplied owner_user_id; when no registry is present it falls back to the caller value for the test harness only (documented). List/add/set-done all route through this resolver, so the authorization now derives from agent identity rather than an LLM-fillable field.

The owner check also now runs before the archived check in execute_todo_add_item (106-109) and execute_todo_set_done (164-167), closing the archived-state oracle. The internal-field leak SUGGESTION is resolved too — execute_todo_list_lists projects an id/title/updated_at allowlist (lines 62-65); that inline comment is already outdated (line: null) on GitHub.

The active inline comments on lines 60/106/164 describe the pre-fix behavior and no longer match current code; they are left in place (not duplicated). Residual note: the no-registry fallback still trusts caller owner_user_id, which is a documented test-only path — confirm production always provisions agent_registry before these tools are reachable by untrusted/prompt-injectable agents (tracked for #1923 C1).

Files Reviewed (PR-owned, 8 files — no new issues)
  • tinyagentos/tools/todo_tools.py - authorization now registry-bound; owner-before-archived ordering; field allowlist. No new issues.
  • tinyagentos/todo/notify.py - notification placeholder. No issues.
  • tinyagentos/skills.py - 3 todo skill seeds replace notes_set_done. No issues.
  • tinyagentos/routes/skill_exec.py - dispatch mapping for new todo skills. No issues.
  • tinyagentos/tools/notes_tools.py - execute_notes_set_done removed. No issues.
  • tests/todo/test_todo_tools.py - registry-binding + access-control coverage. No issues.
  • tests/notes/test_notes_tools.py - obsolete set_done tests removed. No issues.
  • tests/test_routes_github.py - key-aware secret mock. No issues.
Previous Review Summaries (7 snapshots, latest commit 43696ce)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 43696ce)

Status: No active Kilo issues | Recommendation: Merge after confirming one external note

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0
Incremental diff (2013ae2..43696ce) — RESOLVED by this increment

The incremental change reorders the access checks in execute_todo_add_item (tinyagentos/tools/todo_tools.py:106-109) and execute_todo_set_done (:164-167): the owner_user_id ownership check now runs before the archived_at archived-check. This closes the state-oracle gap previously flagged (non-owners guessing a list_id could learn archived status before authorization). No new issues are introduced in the changed lines.

Previously flagged issues — context (unchanged by this increment)

The owner-binding IDOR-style warnings on lines 60/106/164 and the internal-field leakage SUGGESTION remain open from prior review rounds but are on lines outside this increment's scope. They are tracked for the #1923 C1 collaboration follow-up and should be addressed before these tools are reachable by untrusted/prompt-injectable agents.

Files Reviewed (incremental, 1 file)
  • tinyagentos/tools/todo_tools.py - oracle-ordering fix applied; no new issues

Previous review (commit 2013ae2)

Status: No active Kilo issues | Recommendation: Merge after confirming one external note

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0
Previously flagged issues — RESOLVED in this increment

The incremental diff (535b9f0c..HEAD) adds _resolve_owner_user_id (tinyagentos/tools/todo_tools.py:17) which binds agent_name to a verified owner via request.app.state.agent_registry and overrides the caller-supplied owner_user_id. This closes the three IDOR-style authorization gaps previously flagged on todo_tools.py lines 60, 107, 164 (list/add/set_done now derive ownership from the agent identity instead of trusting an LLM-fillable field). The internal-field leakage SUGGESTION is also resolved — execute_todo_list_lists now projects an id/title/updated_at allowlist.

Still-open note (flagged by another reviewer, not duplicated here)

In execute_todo_add_item (line 102) and execute_todo_set_done (line 159), the archived_at check still runs before the owner_user_id access check. A caller guessing a list_id they don't own gets "list is archived" vs the generic access-denied error, leaking list existence/state. This is already covered by an active inline comment on line 108 and remains open; swap the two checks to close the oracle.

Files Reviewed (incremental, 2 files)
  • tinyagentos/tools/todo_tools.py - 3 prior WARNINGs + 1 SUGGESTION resolved; no new issues
  • tests/todo/test_todo_tools.py - new registry-binding tests verify override behavior; no issues

Previous review (commit 535b9f0)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/tools/todo_tools.py 33 execute_todo_list_lists authorizes only by caller-supplied owner_user_id; no agent-to-owner binding, so any caller knowing a user_id can enumerate another user's lists.
tinyagentos/tools/todo_tools.py 79 execute_todo_add_item access gate is owner_user_id match only — no membership/permission check; any caller knowing the id can write to that user's list.
tinyagentos/tools/todo_tools.py 132 execute_todo_set_done has the same owner-id-only authorization gap; any caller knowing a user id can toggle completion on that user's items.
Files Reviewed (incremental)
  • tests/test_routes_github.py - 0 issues (added user-scoped token-resolution tests; patch targets verified correct)

Incremental Update Notes

Since the previous review (0c01276), the base branch dev advanced, but within the PR's own file set only tests/test_routes_github.py changed — four additive tests asserting that user-scoped GitHub endpoints (/starred, /notifications, /auth/status) do not mint an App installation token while repo-scoped endpoints still do. The get_installation_token patch target is valid (imported at call-time inside routes/github.py), so the assert_not_called() checks are meaningful. No new issues introduced.

The core todo files (todo_tools.py, skills.py, skill_exec.py, todo/notify.py, notes_tools.py, tests/todo/test_todo_tools.py) are unchanged since the last review. The 3 WARNING authorization gaps remain valid and already have active inline comments (lines 33, 79, 132); no duplicates were posted. The earlier SUGGESTION about leaking internal list fields is resolved (lines 34-39 now project an id/title/updated_at allowlist).

Fix these issues in Kilo Cloud

Previous review (commit 0c01276)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/tools/todo_tools.py 33 execute_todo_list_lists authorizes only by caller-supplied owner_user_id; no agent-to-owner binding, so any caller knowing a user_id can enumerate another user's lists.
tinyagentos/tools/todo_tools.py 79 execute_todo_add_item access gate is owner_user_id match only — no membership/permission check; any caller knowing the id can write to that user's list.
tinyagentos/tools/todo_tools.py 132 execute_todo_set_done has the same owner-id-only authorization gap; any caller knowing a user id can toggle completion on that user's items.
Files Reviewed (2 files in incremental diff)
  • tinyagentos/tools/todo_tools.py - 3 issues (all previously flagged, still active)
  • tests/todo/test_todo_tools.py - 0 issues

Incremental Update Notes

The incremental diff (f121849..0c01276) touched two files:

  • tinyagentos/tools/todo_tools.py: removed the unused agent_name parameter and its validation from execute_todo_list_lists and execute_todo_set_done, updated docstrings to explicitly document the owner-based trust boundary, and added inline SECURITY comments on the add/set-done owner gates. No authorization behavior changed — the functions were already owner-based.
  • tests/todo/test_todo_tools.py: dropped agent_name from the affected call sites and removed the now-obsolete test_list_missing_agent_name_returns_error test. Tests remain consistent with the implementation.

No new issues introduced. The 3 WARNING authorization gaps remain valid and already have active inline comments (lines 33, 79, 132); no duplicates were posted. The earlier SUGGESTION about leaking internal list fields is resolved (lines 34-39 now project an id/title/updated_at allowlist).

Fix these issues in Kilo Cloud

Previous review (commit f121849)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/tools/todo_tools.py 36 execute_todo_list_lists authorizes only by caller-supplied owner_user_id; agent_name is never bound, so any agent can enumerate another user's lists by guessing their id.
tinyagentos/tools/todo_tools.py 78 execute_todo_add_item access gate is owner_user_id match only — no membership/permission check, agent can write to any user's list if it knows the id.
tinyagentos/tools/todo_tools.py 130 execute_todo_set_done has the same owner-id-only authorization gap as the add path.
Files Reviewed (1 file in incremental diff)
  • tinyagentos/tools/todo_tools.py - 3 issues (incremental diff only; remaining files unchanged)

Incremental Update Notes

The incremental diff (53cf1db3..f121849) for this review round only touched tinyagentos/tools/todo_tools.py line 39:

  • Resolved: The previous SUGGESTION about leaking internal fields (owner_user_id, archived_at, created_at) in execute_todo_list_lists is now fixed — line 39 projects an explicit allowlist ("id", "title", "updated_at"), matching the advertised skill schema.
  • No new issues introduced: The only other changes are documentation docstrings explaining the owner-based authorization trust boundary. The 3 WARNING authorization gaps remain on unchanged lines and are still valid.

Fix these issues in Kilo Cloud

Previous review (commit 53cf1db)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/tools/todo_tools.py 36 execute_todo_list_lists authorizes only by caller-supplied owner_user_id; agent_name is never bound, so any agent can enumerate another user's lists by guessing their id.
tinyagentos/tools/todo_tools.py 78 execute_todo_add_item access gate is owner_user_id match only — no membership/permission check, agent can write to any user's list if it knows the id.
tinyagentos/tools/todo_tools.py 130 execute_todo_set_done has the same owner-id-only authorization gap as the add path.
Files Reviewed (1 file in incremental diff)
  • tinyagentos/tools/todo_tools.py - 3 issues (incremental diff only; remaining files unchanged)

Incremental Update Notes

The incremental diff (729e4730..53cf1db3) for this review round only touched tinyagentos/tools/todo_tools.py:

  • Resolved: The previous SUGGESTION about leaking internal fields (owner_user_id, archived_at, created_at) in execute_todo_list_lists is now fixed — lines 37-42 strip those fields before returning.
  • No new issues introduced: The only other changes are documentation docstrings explaining the owner-based authorization trust boundary. The 3 WARNING authorization gaps remain on unchanged lines and are still valid.

Fix these issues in Kilo Cloud

Previous review (commit 729e473)

Status: 4 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/tools/todo_tools.py 30 execute_todo_list_lists authorizes only by caller-supplied owner_user_id; agent_name is never bound, so any agent can enumerate another user's lists by guessing their id.
tinyagentos/tools/todo_tools.py 64 execute_todo_add_item access gate is owner_user_id match only — no membership/permission check, agent can write to any user's list if it knows the id.
tinyagentos/tools/todo_tools.py 115 execute_todo_set_done has the same owner-id-only authorization gap as the add path.

SUGGESTION

File Line Issue
tinyagentos/tools/todo_tools.py 31 list_lists returns full rows (leaks owner_user_id, archived_at, created_at) contrary to the advertised schema; notes equivalent strips internal fields.
Files Reviewed (7 files)
  • tests/notes/test_notes_tools.py
  • tests/todo/test_todo_tools.py
  • tinyagentos/routes/skill_exec.py
  • tinyagentos/skills.py
  • tinyagentos/todo/notify.py
  • tinyagentos/tools/notes_tools.py
  • tinyagentos/tools/todo_tools.py

Fix these issues in Kilo Cloud


Reviewed by hy3:free · Input: 85.4K · Output: 10.3K · Cached: 795.8K

@hognek
hognek force-pushed the feat/1923-notes-todo-agent-tools branch from 0c01276 to 535b9f0 Compare July 19, 2026 15:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/todo/test_todo_tools.py (1)

42-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add an explicit assertion that internal fields are stripped.

This test verifies the allowlisted list response but never asserts that internal fields (owner_user_id, archived_at, created_at) are absent — the exact contract previously flagged as leaking. The notes-tools equivalent explicitly asserts owner_user_id not in keys; mirroring that here would guard against regression if the allowlist in execute_todo_list_lists is ever loosened.

     assert "lists" in res
     assert any(d["id"] == doc["id"] for d in res["lists"])
     assert len(res["lists"]) == 1
+    for d in res["lists"]:
+        assert "owner_user_id" not in d
+        assert "archived_at" not in d
+        assert "created_at" not in d
🤖 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 `@tests/todo/test_todo_tools.py` around lines 42 - 52, Extend
test_list_returns_owned_lists to explicitly verify that each returned list omits
the internal fields owner_user_id, archived_at, and created_at, while preserving
the existing ownership, inclusion, and count assertions.
🤖 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 `@tinyagentos/tools/todo_tools.py`:
- Around line 71-80: In both execute_todo_add_item and execute_todo_set_done,
perform the owner_user_id authorization check immediately after confirming the
list exists, before evaluating archived_at. Return the existing generic
access-denied error for non-owners, while preserving the archived-list response
for authorized owners.
- Around line 17-41: Bind todo-tool authorization to the calling agent rather
than trusting the LLM-supplied owner_user_id. Update execute_todo_list_lists and
the corresponding add-item and mark-done functions to derive or validate
ownership through the authenticated agent identity and reject mismatches before
accessing TodoStore; preserve owner_user_id only as a validated target when it
matches that identity or an established membership relationship.

---

Nitpick comments:
In `@tests/todo/test_todo_tools.py`:
- Around line 42-52: Extend test_list_returns_owned_lists to explicitly verify
that each returned list omits the internal fields owner_user_id, archived_at,
and created_at, while preserving the existing ownership, inclusion, and count
assertions.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a0bc0ef9-4eca-4e38-b2f7-ba1480e298c5

📥 Commits

Reviewing files that changed from the base of the PR and between 514d947 and 535b9f0.

📒 Files selected for processing (8)
  • tests/notes/test_notes_tools.py
  • tests/test_routes_github.py
  • tests/todo/test_todo_tools.py
  • tinyagentos/routes/skill_exec.py
  • tinyagentos/skills.py
  • tinyagentos/todo/notify.py
  • tinyagentos/tools/notes_tools.py
  • tinyagentos/tools/todo_tools.py
💤 Files with no reviewable changes (2)
  • tinyagentos/tools/notes_tools.py
  • tests/notes/test_notes_tools.py

Comment thread tinyagentos/tools/todo_tools.py
Comment thread tinyagentos/tools/todo_tools.py
hognek added 7 commits July 20, 2026 00:03
Create todo_tools.py with execute_todo_list_lists, execute_todo_add_item,
and execute_todo_set_done. Register in skill_exec.py SKILL_IMPLEMENTATIONS
and skills.py seed data. Remove deprecated execute_notes_set_done from
notes_tools.py (set_done now lives on TodoStore).

Add tests/todo/test_todo_tools.py (17 tests) covering list/add/set_done
with owner-based access control. Remove notes_set_done tests from
tests/notes/test_notes_tools.py (11 remaining tests pass).

Task: 1923 C3 — Notes/Todo split agent tool surface.
… model

Address Kilo bot findings:
- Filter owner_user_id/archived_at/created_at from list_lists response
- Add docstring notes explaining owner-based authorization model and the
  planned agent_name-to-owner binding for when TodoStore gains membership

No CRITICAL findings. 17/17 todo tools, 11/11 notes tools, 18/18 todo routes pass.
Match the skill schema description which advertises only id, title, updated_at.
Using a whitelist (not blacklist) is the safer pattern — new fields added to
the store row won't leak through by default.
…ument auth boundary

Remove agent_name validation from execute_todo_list_lists and
execute_todo_set_done — the parameter was accepted but never used.
It was injected by skill_exec.py but served no purpose, creating a
false expectation that agent_name participates in authorization.

For execute_todo_add_item, agent_name is still required (used for
attribution and notification skip-guard). Add explicit SECURITY
comments at each owner_user_id check documenting that agent-to-owner
binding awaits agent membership on TodoStore (jaylfc#1923 follow-up).

The internal field leak in list_lists was already fixed (allowlist
projection at line 39).
…eturn private key for github-app-private-key lookups

The test helper _build_app_with_app_config(token=None) set mock_secrets.get
to return None for ALL keys, causing _get_app_installation_token to fail
when looking up the GitHub App private key. Now it returns the key for
github-app-private-key lookups while keeping PAT behavior unchanged.

Fixes CI failure: test_repo_endpoint_still_uses_app_token (401 vs 200).
All 4 tests using _build_app_with_app_config now pass.
Resolve owner_user_id from the agent registry (get_by_handle) instead of
trusting the caller-supplied value, closing the authorization gap where any
agent knowing a user_id could enumerate, write to, or toggle another user's
todo lists.

- Add _resolve_owner_user_id() helper: looks up agent_name in agent_registry,
  returns the verified user_id when registry is available (production),
  falls back to args-supplied owner_user_id when absent (test compat).
- execute_todo_list_lists: requires agent_name, derives owner from registry.
- execute_todo_add_item: derives owner from registry instead of trusting args.
- execute_todo_set_done: requires agent_name, derives owner from registry.
- New tests: registry enforcement (AsyncMock), unregistered agent rejection,
  fallback without registry. All 21 todo + 11 notes tests pass.

Fixes Kilo WARNINGs on PR jaylfc#2035 (agent auth bypass).
… leak

Move the owner_user_id gate before the archived_at gate in both
execute_todo_add_item and execute_todo_set_done. Previously a non-owner
caller who guessed a valid list_id could learn whether the list was
archived. Now the owner check runs first, returning a uniform 'access
denied' error for non-owners regardless of archived state.
@hognek
hognek force-pushed the feat/1923-notes-todo-agent-tools branch from 43696ce to 4c89156 Compare July 19, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant