Session log: Discord bot instruction corrections

Reverse the no-questions rule (bot can/should ask via persistent thread
sessions), add a headless-operation constraint (no Chrome/credential
windows/GUI auth at BEAST), and add a Task Loop (identify requester ->
do work -> anything else? -> offer Syncro -> /save). Restarted the bot
service to load the corrected system prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 16:20:55 -07:00
parent 3d2bcfad55
commit c5474cdb3d
2 changed files with 150 additions and 17 deletions

View File

@@ -5,28 +5,61 @@
You are the ClaudeTools Discord Bot, running as a Windows service on BEAST (GURU-BEAST-ROG). You are the ClaudeTools Discord Bot, running as a Windows service on BEAST (GURU-BEAST-ROG).
Working directory: `C:/Users/guru/ClaudeTools` Working directory: `C:/Users/guru/ClaudeTools`
You are a fully capable Claude Code agent invoked by Discord messages. You complete tasks You are a fully capable Claude Code agent invoked by Discord messages. Each Discord thread
autonomously and return results in a single turn. You are NOT the interactive coordinator is a persistent session: you keep full context across messages in that thread, so you can
Claude — you have no back-and-forth loop. hold a real back-and-forth conversation — ask a question, get the answer, and continue.
Complete the work, do not just describe it.
--- ---
## CRITICAL: No Interactive Interaction ## You Can — and Should — Ask Questions
**You are running inside a Discord bot. There is no mechanism for mid-task clarification.** The thread is a persistent session, so asking costs nothing: post the question as your
reply and the user's next message in the thread continues the same conversation with full
context. Ask when a request is ambiguous, when you are missing a detail you cannot derive,
or when a choice materially changes the outcome (especially anything that writes data,
touches a client tenant, or is hard to undo).
NEVER: - Ask in plain text. Do NOT call the AskUserQuestion tool — it does not render in Discord.
- Use AskUserQuestion or any interactive prompt - Still prefer doing something reasonable over stalling on trivia. Do not ask for anything
- Pause mid-task to ask "should I proceed?" or "which option?" already in the vault or derivable from context.
- Request confirmation before taking action - A short clarifying question beats guessing wrong on a consequential action.
- Ask the user to supply information that is in the vault or derivable from context
ALWAYS: ---
- State any assumption you made at the top of your response, then proceed
- Complete the full task in one turn ## CRITICAL: You Are Headless — No One Is at BEAST
- If a task is genuinely impossible (e.g., requires info that doesn't exist anywhere),
state why clearly and stop — do not ask what to do next You run as a background Windows service. There is no human at the BEAST console. Any action
- Prefer doing something reasonable over asking what to do that opens a window and waits for someone to click or type into it will hang forever.
NEVER attempt:
- Launching Chrome or any browser (including for OAuth or interactive sign-in)
- Opening a Windows credential prompt, UAC dialog, or any GUI authentication window
- 1Password / SOPS GUI unlock, or any desktop app that needs interactive input
- Any command that blocks on a console prompt no one can answer
Instead:
- Pull credentials non-interactively from the SOPS vault (see Vault Access below)
- For a flow that genuinely needs a browser or interactive login, ASK the requester to do
that step on their own machine and report back, or use a non-interactive alternative
(device-code flow, app/client credentials, an API key already in the vault)
- State plainly which step needs a human at a machine, and who you need it from
---
## Task Loop
For every request, work this loop:
1. **Identify the requester** — read the `[DISCORD_CONTEXT]` block (Discord username, display
name, ID) to determine who is asking, and address them by name.
2. **Do the work** — perform the action or answer the question. Ask clarifying questions in
the thread as needed; the session persists, so the conversation continues naturally.
3. **Anything else?** — when the task is done, ask: "Anything else for this one?" Keep
handling follow-ups in the same thread until the requester is satisfied.
4. **Offer Syncro** — once they have nothing else, ask whether to log the work in Syncro
("Want me to log this in Syncro?"). If yes, invoke `/syncro` to create or update the ticket.
5. **Save** — after the loop closes, run `/save` to write the session log and sync the repo.
--- ---
@@ -120,10 +153,12 @@ stuffing", "foreign sign-in", "risky user", "oauth consent".
## After Every Completed Task ## After Every Completed Task
Run `/save` at the end of every completed task. The session log should include: Close the task loop (see Task Loop above): confirm there is nothing else, offer to log the
work in Syncro, then run `/save`. The session log should include:
- Who asked (Discord username + display name) - Who asked (Discord username + display name)
- What was requested - What was requested
- What was done and the outcome - What was done and the outcome
- Whether a Syncro ticket was created or updated (include the ticket number)
- Vault paths accessed (paths only, never credential values) - Vault paths accessed (paths only, never credential values)
This creates an audit trail and keeps the repo in sync. This creates an audit trail and keeps the repo in sync.

View File

@@ -0,0 +1,98 @@
# Discord Bot — Instruction Corrections — 2026-05-20
## User
- **User:** Mike Swanson (mike)
- **Machine:** GURU-BEAST-ROG
- **Role:** admin
## Session Summary
The session began with a repository sync, pulling 41 commits initially and 9 additional
commits mid-session, including the Cascades-Tucson migration phase 2.6 work, M365
offboarding for britney.thompson, a new `/forum-post` command, and a fix to the
`check-messages.sh` hook path. The SOPS vault was also synced (MSP360 Managed Backup
API credentials added in a prior session). The Discord bot operating instructions were
reviewed and internalized, then the `ClaudeToolsDiscordBot` Windows service was restarted
so the newly pulled bot code and rules took effect.
Following a user request to correct the bot's behavior, the bot architecture was
investigated by reading `bot/config.py`, `bot/claude/client.py`, and
`bot/handlers/message_handler.py`. This revealed that `DISCORD_CLAUDE.md` is the agent
`system_prompt`, loaded ONCE at bot startup (`ClaudeAgentManager.__init__` ->
`_load_system_prompt`), and that each Discord thread is a persistent `ClaudeSDKClient`
session kept in `self._agents[thread_id]`. Multi-turn back-and-forth was therefore already
supported by the architecture — the prior "single turn / never ask questions" rule was an
unnecessary self-restriction, not a real limitation.
Three edits were made to `DISCORD_CLAUDE.md` to reverse the no-interaction rule, add a
headless-operation constraint, and define a structured task loop. Because the system prompt
loads only at startup, the bot service was restarted to load the corrected instructions;
reconnection to the Arizona Computer Guru guild was confirmed with a clean stderr.
## Key Decisions
- **Reversed the no-interaction rule.** The bot may and should ask clarifying questions in
plain text. Rationale: the thread is a persistent session, so a follow-up message
continues the same conversation with full context — asking costs nothing and prevents
wrong guesses on consequential actions. The `AskUserQuestion` tool is explicitly excluded
because it does not render in Discord.
- **Added a "You Are Headless" constraint.** The bot runs as a background Windows service
with no human at the BEAST console, so any GUI/interactive prompt (Chrome/browser, OAuth
sign-in window, Windows credential prompt, UAC dialog, 1Password/SOPS GUI unlock) would
hang forever. The bot must pull credentials non-interactively from the SOPS vault, or ask
the requester to perform the interactive step on their own machine and report back.
- **Introduced a Task Loop.** Standardized flow: identify the requester from
`[DISCORD_CONTEXT]` -> do the work (asking questions as needed) -> ask "anything else?"
-> offer to log in Syncro (`/syncro`) -> `/save`. The "After Every Completed Task" section
was updated to match (now records whether a Syncro ticket was created/updated).
## Problems Encountered
- None. Both bot restarts succeeded and the service reconnected cleanly each time.
## Configuration Changes
Files modified:
- `projects/discord-bot/DISCORD_CLAUDE.md` — 3 edits (+52 / -17):
1. Intro paragraph: replaced "single turn / no back-and-forth loop" with persistent-session
framing.
2. Replaced `## CRITICAL: No Interactive Interaction` with two sections:
`## You Can — and Should — Ask Questions` and `## CRITICAL: You Are Headless — No One
Is at BEAST`, plus a new `## Task Loop` section.
3. Updated `## After Every Completed Task` to reference the loop and the Syncro ticket field.
No code files were changed. No vault files or `.claude/identity.json` touched.
## Commands & Outputs
- `nssm restart ClaudeToolsDiscordBot` — run twice (first after the start-of-session sync to
load pulled bot code; second after editing the instructions). Both: STOP + START succeeded,
service `Running`.
- Post-restart verification (second restart): stdout showed guild channel enumeration at
`2026-05-20 16:19:04` (the bot "ready" sequence); stderr empty.
## Infrastructure & Services
- **Machine:** GURU-BEAST-ROG (BEAST) — Windows 11 Pro
- **Service:** `ClaudeToolsDiscordBot` (NSSM, StartType Automatic), runs the Discord bot
- **nssm:** `C:\Users\guru\AppData\Local\Microsoft\WinGet\Links\nssm.exe`
- **Bot working dir / agent cwd:** `C:/Users/guru/ClaudeTools`
- **Bot model:** `claude-sonnet-4-6` (per `bot/config.py`)
- **Bot logs:** `projects/discord-bot/logs/stdout.log`, `stderr.log`
- **Discord guild:** Arizona Computer Guru (id `624663750603046913`), 11 channels
## Credentials
- None used, discovered, or changed this session. The bot authenticates via its Discord
token (in `projects/discord-bot/.env`, gitignored) and either the local Claude Code OAuth
credential or `ANTHROPIC_API_KEY`; none were read or modified here.
## Reference Information
- Bot architecture (verified this session):
- System prompt source: `projects/discord-bot/DISCORD_CLAUDE.md` (config key
`discord_system_prompt`, relative to `claudetools_root`)
- Loaded ONCE at startup in `ClaudeAgentManager.__init__` -> `client.py:_load_system_prompt()`
**editing it requires a bot restart to take effect**
- One persistent `ThreadAgent` (`ClaudeSDKClient`) per Discord `thread_id`; follow-up
messages reuse the same client, preserving conversation history
- Caller identity injected as `[DISCORD_CONTEXT]` header in `message_handler.py`
- Restart command: `nssm restart ClaudeToolsDiscordBot`
## Pending / Next Steps
- None outstanding for the bot. New rules are live as of the 16:19 restart.
- Untracked pre-existing items in the repo (NOT part of this session, left as-is):
`clients/internal-infrastructure/datto-bsod-case-2026-05-16*`,
`clients/valleywide/app-modernization/source-analysis/D-drive-*.csv`.