From 361478dd66d5acaec2429c80e085e3c4cf02e093 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Tue, 7 Jul 2026 20:39:41 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-07-07 20:39:12 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-07-07 20:39:12 --- .../2026-07-07-howard-ask-forum-skill.md | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 session-logs/2026-07/2026-07-07-howard-ask-forum-skill.md diff --git a/session-logs/2026-07/2026-07-07-howard-ask-forum-skill.md b/session-logs/2026-07/2026-07-07-howard-ask-forum-skill.md new file mode 100644 index 00000000..a856bf1e --- /dev/null +++ b/session-logs/2026-07/2026-07-07-howard-ask-forum-skill.md @@ -0,0 +1,140 @@ +## 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//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 @ --timeout 1800` + (run with `run_in_background:true`, NO shell `&`). +- Read a thread: `bash .claude/scripts/ask-forum.sh --read [limit]`. +- Resume a wait: `bash .claude/scripts/ask-forum.sh --wait [--after ]`. +- 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`.