ask-forum: harden per high-effort review + document capability limits

Fixes from the code-review workflow (7 findings): page the poll cursor past the
100-msg window (no false timeout behind bot/overflow messages); honor 429
retry_after and bail fast on permanent Discord errors (10003/50001/...) instead
of burning the timeout; status-check overflow follow-up chunks (warn, don't
silently truncate); clamp --read limit safely (guard >64-bit overflow); add
--wait --after for precise resumption; DRY the newline-trim; set LC_ALL=C.UTF-8
for codepoint-safe slicing. SKILL.md gains the tested bot capability/limit map
(can: post/read/edit-own/react; cannot without a grant: delete/archive/unlock/pin)
and a robustness section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-07 20:37:36 -07:00
parent f379a828e9
commit 0a438929d0
2 changed files with 114 additions and 71 deletions

View File

@@ -36,8 +36,27 @@ bash .claude/scripts/ask-forum.sh --read <thread_id>
# Resume blocking on an already-posted thread (e.g. after a timeout):
bash .claude/scripts/ask-forum.sh --wait <thread_id> --timeout 1800 --poll 10
# add --after <msg_id> to wait for replies STRICTLY AFTER a message you already
# consumed (default baseline catches any reply since the thread's starter).
```
## Robustness (hardened after the 2026-07-08 review)
- **Pages past the 100-message window:** the poll advances its `after` cursor each
cycle, so a reply is found even behind many bot/overflow messages (no false timeout).
- **Rate-limit aware:** a `429` is honored (sleeps `retry_after`); a permanent Discord
error (Unknown Channel 10003, Missing Access 50001, etc.) **bails immediately** instead
of burning the full timeout; only genuine transients keep polling.
- **Long questions** (>1900 chars) chunk into the starter + follow-up messages, and each
overflow POST is status-checked (warns if one drops, so the question isn't silently
truncated).
- **`--wait` baseline** is the thread's starter id (starter id == thread id for a forum
post), so a reply that arrived *before* the wait started is caught, not missed. Because
of this, `--wait` on a thread that already holds a consumed answer re-returns it — pass
`--after <msg_id>` when you only want the NEXT reply.
- Residual caveat: content slicing assumes a UTF-8 locale (the script sets
`LC_ALL=C.UTF-8`); a forced byte-counting `LC_ALL=C` could split a multibyte char at the
1900-char cut. Not an issue under the fleet default locale.
Flags: `--title "short title"` (forum post name; defaults to first 60 chars of the
question) · `--timeout SEC` (default 600) · `--poll SEC` (default 8) · `--tag @<id>`
(repeatable — pings that person). Discord IDs: mike `264814939619721216`,