polly-todos-suite
CleanQuery, summarize, and file work items in the Polly project TODO tracking database in Notion.
SKILL.md
---
name: polly-todos-suite
description: Query, summarize, and file work items in the Polly project TODO tracking database in Notion. Use when the user asks about bugs, features, or work items for the Polly project (e.g. "summarize the post v0.5 todos", "what bugs are in progress?", "what is Andrew working on?", "show me critical items"), OR when the user wants to log a bug, report an issue, request a feature, or file any work item (e.g. "file a bug", "log an issue", "create a TODO", "add a feature request", "report a problem with Polly", "file this as a ticket").
---
# Polly TODOs Suite
Query and file work items in the Polly TODOs Notion database.
**Collection:** `collection://30975c3d-57b7-8048-85a6-000b2ac32623`
> **Do not load `references/schema.md` for Mode A queries.** Load it only when filing (Mode B).
---
## Reporter
Check memory for `polly_todo_reporter` (`{"notion_user_id": "...", "name": "..."}`). If present, use it — no lookup needed.
If missing: call `notion-get-users` with `user_id: "self"`, save result to memory as `polly_todo_reporter`, then use it.
Always pass as: `["<notion_user_id>"]`
---
## Mode A — Query & Summarize
### Step 1 — Classify the query type
**Structural** — filtering by Status, Target Version, Assignee, Priority, or combinations of structured fields.
- `notion-search` is semantic, not a structured filter. Use it, but post-filter results against the requested criteria and drop anything that doesn't match. If results are clearly off, say so and suggest the user share a filtered Notion view URL for exact results.
**Semantic** — searching by topic, keyword, or natural language.
- `notion-search` is the right tool. No post-filtering needed beyond relevance.
**Both** — use structural term as primary query, post-filter by semantic term.
### Step 2 — Translate request to query string (no tool calls)
Pick the most selective dimension:
| Dimension | Example |
|---|---|
| Target version | `"v0.7"`, `"v0.8"` |
| Type | `"Issue"`, `"Feature"`, `"Security"` |
| Priority | `"Critical"` |
| Component | `"Web App"`, `"Agent Core"` |
| Person | `"Andrew"`, `"Dan"` |
| Status | `"Testing in Dev"`, `"In Prod"`, `"Merged Not Deployed"` |
**Status group translation** — expand before querying:
| User says | Maps to |
|---|---|
| "open" / "not started" | `Not started` |
| "in progress" / "active" / "wip" | all In progress group values |
| "in dev" / "testing" | `✏️ Testing in Dev` |
| "merged" / "not deployed" | `⬆️ Merged Not Deployed` |
| "done" / "complete" / "shipped" | all Complete group values |
| "in prod" / "live" / "deployed" | `🚀 In Prod` |
**Status groups (3 tiers):**
```
To-do → Not started | 🔖 Needs Clarity | ⏸️ Paused | Deferred
In progress → 🛠️ In progress | 🚦 Plan In Review | 👀 PR In Review | ⬆️ Merged Not Deployed | ✏️ Testing in Dev
Complete → 🚀 In Prod | ✅ Done | Duplicated | Closed (No Action)
```
**Default:** Exclude Complete group unless user asks for completed/shipped work.
Check memory for `polly_todos_last_query` — layer new dimensions on top for refinements.
### Step 3 — Search (1 tool call)
```
notion-search
query: <translated query string>
data_source_url: collection://30975c3d-57b7-8048-85a6-000b2ac32623
page_size: 10 (single-dimension or specific) / 25 (multi-dimension or "all"/"list")
max_highlight_length: 0 (listing) / 250 (content search)
```
Post-filter results for structural queries — discard items whose Status/Version/Type don't match the request.
### Step 4 — Resolve User Display Names (only if needed)
- Check memory for `polly_todos_user_cache` first
- Call `notion-get-users` only for IDs not in cache
- Merge and save to memory
Skip entirely if no user IDs appear in results.
### Step 5 — Summarize & Format
```
**[Title](notion_url)**
`TODO-ID` · Type · **Priority** · Status · Component · Target Version
Reported by: Name [· Assigned to: Name] [· brief note if relevant]
```
- Omit blank/unset fields
- No structured properties → title + link only, labeled `*(plan doc)*`
- Flat list, `---` separators between items
---
## Mode B — File a New Item
> Load `references/schema.md` now for property values, templates, and examples.
### Step 1 — Determine Type
Identify from context; ask if ambiguous. `Env` and `Reported Version` are **Issues only** — never set these for Features or other types.
### Step 2 — Pre-Flight (single pass — resolve everything before asking any questions)
Run all of the following simultaneously. If everything resolves from cache/hardcoded values, proceed to Step 3 with zero tool calls.
**Reporter:** Check memory for `polly_todo_reporter`. If present, use it. If missing, call `notion-get-users` with `user_id: "self"`, cache as `polly_todo_reporter`, then use it.
**Assignee (if user specifies one):**
- Check `polly_todos_user_cache` in memory first
- If not found: call `notion-get-users` with `query: "<name>"`, cache result
**Issues only — Env:** Auto-detect:
```bash
python3 -c "import os; url=os.environ.get('CONTROLLER_API_URL',''); print('dev' if '.dev.' in url else ('prod' if url else 'UNKNOWN'))"
```
If `UNKNOWN`, ask: `dev` or `prod`?
**Issues only — Reported Version:** Use `polly_todo_last_version` from memory if present; default `v0.7`.
**Target Version:** Use `polly_todo_last_target_version` from memory if present; otherwise present options from schema and ask.
### Step 3 — Gather Context (Issues only)
Ask in a single message (not one question at a time):
1. Short description
2. Steps to reproduce or triggering action
3. Error messages, frequency, or diagnostic details
### Step 4 — Duplicate Check (1 search call)
```
notion-search
query: <3-5 keywords from title> [+ Type term]
data_source_url: collection://30975c3d-57b7-8048-85a6-000b2ac32623
page_size: 5
max_highlight_length: 0
```
If 2+ keywords overlap with an existing title of the same Type:
> Possible duplicate: "[title]" (url) — file anyway?
Proceed silently if no match or different Type.
### Step 5 — Single-Turn Confirmation
Propose ALL fields at once in one message. Do not gather fields across multiple turns.
Format:
```
Here's what I'll file:
**Name:** <title>
**Type:** <type>
**Priority:** <priority> — <one-line rationale>
**Status:** Not started
**Target Version:** <version>
**Component:** <component>
**[Issues only] Env:** <env>
**[Issues only] Reported Version:** <version>
Confirm, or tell me what to change.
```
Wait for one user reply, then proceed to Step 6 immediately.
### Step 6 — Create & Update (back-to-back, no pause)
**Compose the full page content BEFORE calling `notion-create-pages`.** Both calls fire immediately, one after the other, with no intermediate reasoning turns.
1. `notion-create-pages` — `parent.data_source_id = "30975c3d-57b7-8048-85a6-000b2ac32623"` + confirmed properties + `template_id`
2. `notion-update-page` — use **`update_content`** with `old_str` anchors to fill in reporter-provided sections only, without disturbing engineer-owned sections:
- **Issues:** Target the template headings using `update_content`:
- `# Problem Description` — fill with the reporter's description, context, expected vs. actual behavior
- `# Reproduction` — fill with steps to reproduce, triggering action, error messages, frequency, diagnostics
- Leave `# RCA`, `# Fix Plan`, `# Testing & Verification`, `# PR's`, `# Next Steps` as empty stubs — **do not populate these** (engineer fills them in)
- Note: reporters are not expected to fill in engineer sections. Only Problem Description and Reproduction come from the reporter.
- **Features/other:** Use `replace_content` with `# Context` containing description, options/considerations, recommendation
- Always append at the end: `---\n*Filed by Polly on behalf of [reporter name from polly_todo_reporter] — YYYY-MM-DD*`
3. Save `Target Version` to memory as `polly_todo_last_target_version`
4. Report back the Notion page link
---
## Efficiency Rules
1. Scope all searches to the collection — never search the whole workspace
2. One search call per query — refine and retry once if needed; no chaining
3. No speculative fetches — only fetch individual items when explicitly asked
4. `max_highlight_length: 0` for listing; `250` for content searches
5. Cache user display names in `polly_todos_user_cache` — never re-fetch a known ID
6. Cache Target Version options in `polly_todos_target_versions` — refresh if user references an unknown version
7. Do not load `references/schema.md` for Mode A — Mode B only
8. Reporter is hardcoded — never look it up
9. Pre-flight is a single parallel pass — zero tool calls when cache is warm
10. Compose full page content before first Notion call — Steps 6.1 and 6.2 fire back-to-back
Version History
v1.2.0latest
Issues now use update_content to fill only reporter-owned sections (Problem Description, Reproduction) from the issue template, leaving engineer sections (RCA, Fix Plan, Testing & Verification, PRs, Next Steps) as empty stubs.
Apr 8, 2026
Clean.zip
v1.1.0
Improved query accuracy with status group hierarchy and structural vs semantic routing. Faster filing: single-turn confirmation, parallel pre-flight, back-to-back Notion calls. Auto-refresh schema cache. Reporter resolved via self-lookup and cached — no hardcoded IDs.
Apr 6, 2026
Clean.zip
v1.0.0
Initial release
Mar 26, 2026
Clean.zip
SHA-256 (latest)
6bae5b6e429754dc24843e188f1e9bee9710b8874d9c20b7333e380cb6dc7f30