Add opt-in diagnostic logging behind -v/--verbose flag#125
Conversation
| _MASK = "[redacted]" | ||
|
|
||
| _verbosity = 0 | ||
| _secrets: set[str] = set() |
There was a problem hiding this comment.
_secrets is a module-level mutable set that stores per-session/API secrets; it persists for the process lifetime and can leak sensitive values between requests or sessions.
Details
✨ AI Reasoning
A mutable module-level set is being used to hold sensitive values that are registered during normal command execution. In long-running processes or servers, that state will persist across independent requests or sessions and can accumulate or leak secrets between contexts, causing data leakage and cross-request coupling. The concern focuses on request/session-scoped secrets being stored in process-global mutable state.
🔧 How do I fix it?
Avoid storing request-specific data in module-level variables. Use request-scoped variables or explicitly mark shared caches as intentional.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
There was a problem hiding this comment.
@AikidoSec ignore: This is a short-lived single-user CLI process, not a long-running server — there are no cross-request or cross-session contexts to leak between. The set holds only the current invocation's own credentials (API key, session JWT), registered precisely so the logging formatter can redact them from -v/--verbose diagnostic output, and it dies with the process. The process-global scope is intentional and mirrors the existing environments.py pattern in this codebase.
Generated by Claude Code
There was a problem hiding this comment.
✅ Based on your feedback, we ignored this issue because of the following reason:
This is a short-lived single-user CLI process, not a long-running server — there are no cross-request or cross-session contexts to leak between. The set holds only the current invocation's own credentials (API key, session JWT), registered precisely so the logging formatter can redact them from
-v/--verbosediagnostic output, and it dies with the process. The process-global scope is intentional and mirrors the existingenvironments.pypattern in this codebase.
Generated by Claude Code
The CLI had no way to see what it was doing on the wire: library loggers were actively silenced so stderr stayed clean next to normalized errors, and diagnosing an auth or connectivity problem meant reading code. A new root flag closes that gap (counted, gh/speechmatics style): - `-v` surfaces request-level logs (httpx and friends at INFO) - `-vv` adds wire-level detail (websockets frames, httpcore events at DEBUG) aai_cli/debuglog.py installs one stderr handler with a redacting formatter; config.resolve_api_key and AppState.resolve_session register the API key and session JWT at their resolution choke points so verbose output can never print them in clear (websockets logs the raw Authorization header at DEBUG during the handshake). The realtime silencers (aai_cli.ws, streaming/diagnostics) stand down while verbose mode is active, and the root callback logs the resolved environment. https://claude.ai/code/session_01Q6KZYc7FPWhyJkbQLUtq36
149bf02 to
fafed7b
Compare
Adds a new
debuglogmodule that provides opt-in diagnostic logging to stderr, controlled by the root-v/--verboseflag. This allows users to diagnose auth/connectivity issues without guessing.Summary
Introduces a diagnostic logging system that:
-vto show request-level diagnostics (HTTP requests, statuses)-vvto show wire-level detail (WebSocket frames, connection events)Key Changes
New
aai_cli/debuglog.py: Core module providing:enable(verbosity)to install stderr handler at startupregister_secret(value)to record sensitive values for redaction_RedactingFormatterthat masks secrets in every log recordactive()to check if verbose mode is onUpdated
aai_cli/main.py:--verbose/-voption (count-based, supports-vand-vv)debuglog.enable(verbose)before any other initializationUpdated
aai_cli/config.py:resolve_api_key()to register the key with debuglog before returning_resolve_api_key()to keep registration at the public API boundaryUpdated
aai_cli/context.py:AppState.resolve_session()now registers the JWT with debuglog for redactionUpdated logging silencers (
aai_cli/ws.py,aai_cli/streaming/diagnostics.py):debuglog.active()and skip silencing when verbose mode is on-v/-vvis requestedComprehensive test coverage (
tests/test_debuglog.py):-vand-vvflagsDocumentation updates:
aai_cli/skills/aai-cli/SKILL.mdwith diagnostics usage guideAGENTS.mdwith debuglog module descriptionImplementation Details
config(a Rich-free library layer) registers secrets hereenvironments.py), with a test fixture to snapshot/restore between tests-vvcan show the wire-level frames it exists to displayhttps://claude.ai/code/session_01Q6KZYc7FPWhyJkbQLUtq36