| name | todo-gate |
| description | When QWEN.md // TODO: → docs/TODO.md tracking keeps failing, close the gap with a PreToolUse hook — same pattern as rendering_naming_guard for comment enforcement |
TODO Gate — Mechanical enforcement of // TODO: → docs/TODO.md
QWEN.md requires that every // TODO: in code also have an entry in
docs/TODO.md. When this rule is repeatedly violated, the fix is a
mechanical PreToolUse hook — the same pattern used by
rendering_naming_guard.py for the output gate.
Why this keeps failing without a hook
// TODO: is the fast path: type inline, move on
docs/TODO.md is a separate file in a separate directory — friction
- No mechanical check exists at Write/Edit time
- Session boundaries erase the memory of what was deferred
The hook pattern
Write a Python script in .qwen/local-scripts/ following the existing
guard convention:
- Trigger:
Write or Edit to .rs/.wgsl files
- Scan: extract newly-added
// TODO: lines from the diff against
old_string
- Cross-check: for each new TODO, verify
docs/TODO.md already
contains the file stem (e.g. vsm_mark) plus at least one
significant word from the TODO text
- Deny with message: if undocumented, block the write with the
exact file name and TODO text, plus a reminder to update TODO.md
- Fail-open: if TODO.md doesn't exist, allow — never block on
infrastructure error
- Pre-existing TODOs safe: lines present in
old_string are
skipped (only newly-added TODOs trigger)
When to apply
When a QWEN.md rule has no mechanical enforcement and the user reports
repeated violations. Write the hook, add tests, commit — the gap closes
at the next Write/Edit.
Existing implementation
C:\Dev\Titan\.qwen\local-scripts\todo_gate_guard.py — 11 tests,
test_todo_gate_guard.py. Qwen Code auto-discovers hooks in
.qwen/local-scripts/.
Edge cases
- Vague TODOs (
TODO: fix this): words < 4 chars or stopwords
(implement, should, would, need, needs, full, body) are stripped.
If no significant words remain, allow — too vague to check.
- Unrelated file-name mentions: the stem must appear in TODO.md
AND a significant word must also appear. This prevents false
positives where a file name coincidentally appears in an unrelated
TODO entry.
- Empty TODO.md: treated as no match (deny) — the file exists
but has no content, so no stem is present.