Files
claudetools/session-logs/2026-07/2026-07-07-howard-ask-forum-skill.md
Howard Enos a7b2fae468 sync: auto-sync from HOWARD-HOME at 2026-07-08 17:00:10
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-07-08 17:00:10
2026-07-08 17:00:39 -07:00

170 lines
11 KiB
Markdown

## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech
## Session Summary
Built a human-in-the-loop question flow over the private `#ct-forum` Discord forum: a live
Claude session posts a question, blocks until a human (Mike/Winter/anyone with forum access)
replies, and receives the answer back in the same session to act on. The forum was confirmed
to be a Discord Forum channel (`type=15`, id `1522960388432465950`), not a regular text
channel, so posting requires creating a thread (`POST /channels/<forum>/threads`) rather than
a direct message-post. Correlation is automatic: each question is its own thread, and the
asking session reads only that `thread_id`, so answers route to whoever asked with no crossover.
Proved the round trip live (Mike's "test" and Howard's "9" both came back to this session),
then productionized it as `ask-forum.sh` with three modes: ask+block, `--read` (one-shot), and
`--wait` (resume blocking on an existing thread). Identified the root cause of the double-answer
noise: the BEAST bot triggers on any reply in a thread it owns, and because the bot token creates
the forum posts, the bot owns them. Patched `bot/main.py` to ignore all threads under `#ct-forum`.
Promoted the flow from a bare command to a full skill (`.claude/skills/ask-forum/SKILL.md`) and
wired it into the skill-first rules (`CLAUDE.md`, `SKILL_ROUTING.md`) so future sessions invoke
the skill instead of hand-rolling the Discord API — the exact footgun that caused a broken
background wait (a shell `&` on top of `run_in_background`, hit twice). Captured that as memory
`feedback_background_task_no_ampersand`.
Per Howard's request, audited the skill and probed the bot's capability boundary in the forum
(mapped exactly what it can/can't do), then ran a high-effort workflow-backed code review that
surfaced 7 real defects in the poll logic. Rewrote `ask-forum.sh` to fix all of them and
documented the capability/limit map and hardening notes in the skill. Finally scheduled seven
one-shot morning checks (5:00-8:00 AM AZ, every 30 min) to catch Mike's pending reply, and
committed/pushed everything.
## Key Decisions
- **Polling model over event-driven (model A, not B):** the blocking `--wait` runs the poll loop
in bash, so the model spends zero tokens while waiting and is notified on reply. Chosen as the
cheapest option that meets Howard's bar ("good enough while the session is open"). The
coord-backed registry / always-on bot router were deferred as unnecessary for now.
- **Forum-only, no DM replies** (Mike's call): answers stay team-visible.
- **Anyone can answer** — no code change; the script accepts any non-bot reply. Enabling more
answerers is purely a Discord permission grant (Techs role View on `#ct-forum`).
- **Did not force a SYSTEM-context deploy on BEAST:** git-as-SYSTEM can't auth to Gitea (GCM
OAuth) with no logged-in guru, and bash/vault aren't on SYSTEM's PATH. Avoided credential-in-
RMM-log hacks; the deploy needs guru context. (Another session subsequently deployed it.)
- **Skill deliberately never locks/renames threads:** the probe found locking is a one-way trap
without Manage Threads (can lock, then can't unlock). Thread lifecycle treated as off-limits.
- **Morning checks as 7 one-shot crons** (not recurring): precisely covers tomorrow's 5-8am
window and self-cleans; recurring would fire daily for 7 days.
## Problems Encountered
- **Double-answer noise:** BEAST bot auto-answered forum replies. Root cause = thread-ownership
trigger in `main.py`. Fixed with a `#ct-forum` parent-id guard (later found the remote also
added a `MONITOR_CHANNEL_IDS` feature; the guard sits before it and wins).
- **`&` on background task, twice:** appending a shell `&`/`disown` on top of
`run_in_background:true` forked the wait and exited 0 instantly, orphaning it — so replies were
never delivered and Howard had to prompt manually. Fixed (foreground the command; the harness
backgrounds it) and logged to errorlog + memory.
- **Thread deletion 403:** bot lacks Manage Threads on `#ct-forum` — can't delete the 3 test
threads. Needs Mike (owner) to grant it.
- **BEAST deploy blocked:** no logged-in guru + GCM auth failure + no bash/vault on SYSTEM PATH.
Left for guru context; folded into the request to Mike.
- **Code review found 7 poll-logic bugs** (window cap, permanent-error handling, overflow
fire-and-forget, `--read` overflow clamp, multibyte split, `--wait` re-delivery, DRY). All
fixed in the rewrite and verified (syntax, clamp, wait-race all pass).
## Configuration Changes
Created:
- `.claude/scripts/ask-forum.sh` — engine (ask / `--read` / `--wait`), hardened.
- `.claude/skills/ask-forum/SKILL.md` — full skill contract + capability map + robustness notes.
- `.claude/commands/ask-forum.md``/ask-forum` command entry.
- `.claude/memory/feedback_background_task_no_ampersand.md` — the `&`-on-background footgun.
Modified:
- `projects/discord-bot/bot/main.py` — ignore threads under `#ct-forum` (submodule commit `56938bb`).
- `.claude/CLAUDE.md` — added `ask-forum` to the skill-first covered-domains list.
- `.claude/SKILL_ROUTING.md` — added the `ask-forum` doing-skill row.
- `.claude/memory/MEMORY.md` — indexed the new memory + skill.
- `errorlog.md` — 3 entries (SYSTEM Gitea fetch friction, background-`&` friction x-ref).
## Credentials & Secrets
None created or rotated. Read-only use of existing vault entries:
- `projects/discord-bot/bot-token.sops.yaml` field `credentials.bot_token` (Discord bot token).
- `services/gitea.sops.yaml` — inspected field path `credentials.api.api-token` (username
`azcomputerguru`) for a possible SYSTEM deploy; NOT used (BEAST can't decrypt as SYSTEM).
- `infrastructure/gururmm-server.sops.yaml` — RMM API auth for BEAST recon.
## Infrastructure & Servers
- **#ct-forum** — Discord Forum channel, id `1522960388432465950`, guild `624663750603046913`
(Arizona Computer Guru). Private: `@everyone` View DENY; Howard (`624667664501178379`) + bot
(`1499868551601983652`) explicitly allowed; Mike (`264814939619721216`, owner) sees it. Bot
role `ClaudeTools` = `1499876554317107223`. Techs role = `624700808268611618`.
- **Bot capability map (tested):** CAN read/create-post/post-followup/edit-own/react/typing;
rename+lock a thread it owns (lock is one-way). CANNOT (403) delete/archive/unlock a thread
(Manage Threads) or pin (Manage Messages).
- **BEAST** = GURU-BEAST-ROG, RMM agent `5233d75b-f589-43c4-b96e-cfa75365a78d`. Repo at
`C:/Users/guru/ClaudeTools`; bot service `ClaudeToolsDiscordBot` (nssm; not on SYSTEM PATH —
use `Restart-Service`). git safe.directory added for SYSTEM this session.
- Forum thread IDs: 3-asks (pending Mike) `1524247667633426465`; proposal `1524238476520853664`;
test threads `1524232081444704266` (left locked+renamed "probe-rename" by the capability probe),
`1524237516792926278`; Mike's original "Howard" thread `1524230356478460034`.
## Commands & Outputs
- Post a forum question + block: `bash .claude/scripts/ask-forum.sh "Q" --tag @<id> --timeout 1800`
(run with `run_in_background:true`, NO shell `&`).
- Read a thread: `bash .claude/scripts/ask-forum.sh --read <thread_id> [limit]`.
- Resume a wait: `bash .claude/scripts/ask-forum.sh --wait <thread_id> [--after <msg_id>]`.
- Verified: `--read` clamp (500 and 20-digit overflow both -> 100), `--wait` returns existing
replies in ~2s (race fixed), `bash -n` clean.
- Code review: `Workflow({name:"code-review", args:"high ..."})` -> 7 findings (run `wf_6c0773f1-e93`).
## Pending / Incomplete Tasks
- **Mike's reply to the 3 asks is not visible** in thread `1524247667633426465` or his bot DM as
of session end. Howard said "mike replied" — location unknown; NOT acted on (did not fabricate
an answer). The 7 scheduled 5-8am checks will read the thread and act when it appears.
- **3 test threads not deleted** — pending the bot's Manage Threads grant from Mike.
- **Team access (Winter/anyone)** — pending Mike granting Techs role View on `#ct-forum`.
- **BEAST bot-silence:** commit `f379a82` (pulled during this session's rebase) indicates ANOTHER
session already deployed the `#ct-forum` guard on BEAST (submodule -> `56938bb`). Verify the bot
is actually silenced in the forum; if so, item is done.
- **BEAST housekeeping:** uncommitted `DISCORD_CLAUDE.md` edit (Winter's AZ-time rule, 2026-07-02)
should be committed.
- 7 one-shot cron jobs are **session-only** — if this terminal closes, they die and the morning
checks won't run.
## Reference Information
- Commits (this session): `8def189` (initial flow), `9340cde` (skill + routing), `f379a82` (BEAST
deploy, other session), `0a43892` (hardening). Submodule `acg-discord-bot` `56938bb`.
- Cron job IDs (5-8am AZ 2026-07-08): `cd807fa3` `5f8d46d4` `9cf6f669` `115e1145` `a2ffcb95`
`9102c157` `ee27ad63`.
- Skill: `/ask-forum` · engine `.claude/scripts/ask-forum.sh` · doc `.claude/skills/ask-forum/SKILL.md`.
- Discord API base `https://discord.com/api/v10`. RMM base `http://172.16.3.30:3001`.
## Update: 16:59 PT (2026-07-08) — overnight checks + Winter access probe
**Scheduled morning checks ran.** All 7 one-shot crons fired on schedule (5:00, 5:30, 6:00,
6:30, 7:00, 7:30, 8:00 AM AZ) and read the 3-asks thread `1524247667633426465`. Mike never
replied — every check returned no human message. The BEAST bot also stayed silent in the
thread across all checks, consistent with the `#ct-forum` guard (commit `f379a82`) being live.
The window elapsed with no answer; all one-shots auto-deleted.
**Midday sync (13:09) — no changes.** `sync.sh` reported no incoming/outgoing commits, no
pending to-dos, vault clean. Nothing changed on the repo since the overnight deploy commit.
**Winter access probe (a new capability-boundary finding).** Howard reported Winter can SEE
`#ct-forum` but couldn't open the posts. Decoded the live overwrites: still only bot + Howard
have explicit `View=allow`, `@everyone` `View=DENY`, and NO Winter/Techs overwrite — so Winter's
visibility comes from an admin-level role bypass (she holds Techs `624700808268611618` plus other
roles), while opening posts needs explicit Read History / thread perms. Howard asked me to grant
her access directly; the bot's `PUT /channels/<forum>/permissions/<winter>` returned
**403 Missing Permissions (code 50013)** — the bot lacks Manage Roles, so it cannot modify channel
permissions. This is another item on the "limit of control" list (alongside delete/archive/pin =
Manage Threads/Messages). Howard then resolved Winter's access on the Discord side ("never mind,
she can access it"), so no further action.
**Still pending on Mike (unchanged):** Manage Threads grant (to delete the 3 test threads),
formal Techs-role View overwrite on `#ct-forum` (currently relying on role bypass), and
confirmation of who owns the BEAST `/sync` + restart (guard appears already deployed).
**Skill name confirmed for reuse in other sessions:** `ask-forum` (`/ask-forum`); engine
`.claude/scripts/ask-forum.sh`; synced to global, available fleet-wide.