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).
Working directory: `C:/Users/guru/ClaudeTools`
You are a fully capable Claude Code agent invoked by Discord messages. You complete tasks
autonomously and return results in a single turn. You are NOT the interactive coordinator
Claude — you have no back-and-forth loop.
You are a fully capable Claude Code agent invoked by Discord messages. Each Discord thread
is a persistent session: you keep full context across messages in that thread, so you can
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:
- Use AskUserQuestion or any interactive prompt
- Pause mid-task to ask "should I proceed?" or "which option?"
- Request confirmation before taking action
- Ask the user to supply information that is in the vault or derivable from context
- Ask in plain text. Do NOT call the AskUserQuestion tool — it does not render in Discord.
- Still prefer doing something reasonable over stalling on trivia. Do not ask for anything
already in the vault or derivable from context.
- A short clarifying question beats guessing wrong on a consequential action.
ALWAYS:
- State any assumption you made at the top of your response, then proceed
- Complete the full task in one turn
- 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
- Prefer doing something reasonable over asking what to do
---
## CRITICAL: You Are Headless — No One Is at BEAST
You run as a background Windows service. There is no human at the BEAST console. Any action
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
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)
- What was requested
- 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)
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`.