# Logging Standard

Anteroom debug logging is operational troubleshooting output. It is not an
audit log, transcript log, or retention mechanism.

## Where Logs Go

`--debug` and `AI_CHAT_LOG_LEVEL=DEBUG` enable Python debug logs on the
configured process logger, normally stderr. This issue does not add always-on
file logging. Redirect stderr only when you intentionally want a local capture:

```bash
aroom --debug chat 2>debug.log
AI_CHAT_LOG_LEVEL=DEBUG aroom web 2>server-debug.log
```

Future file-backed debug sinks must be bounded with rotation, retention,
maximum entry size, and maximum directory size.

## Levels

- `DEBUG`: sparse lifecycle breadcrumbs for troubleshooting one request, turn,
  tool call, workflow run, retry, timeout, degraded path, or cleanup path.
- `INFO`: user-meaningful operational state changes that are useful in normal
  process logs.
- `WARNING`: recoverable failures, degraded dependencies, policy denials, and
  retryable provider or workflow problems.
- `ERROR`: terminal failures that prevent the requested operation from
  completing.

## Lifecycle Vocabulary

Use these lifecycle values consistently:

- `start`: work accepted or an operation begins.
- `skip`: work intentionally bypassed, queued, suppressed, or not applicable.
- `retry`: another attempt will be made.
- `timeout`: a deadline or stall timer fired.
- `success`: operation completed as intended.
- `failure`: operation ended with an error or policy denial.
- `cleanup`: teardown, cancellation handling, stale-state cleanup, or sink
  isolation.

## Required Correlation Fields

Chat-turn logs should carry the shared diagnostic context when available:

- `interface`: `cli`, `web`, `workflow`, or another bounded interface name.
- `conversation_id`: conversation UUID when the event belongs to a conversation.
- `turn_id`: opaque per-turn id.
- `request_id`: upstream request id or generated request id.

Add operation-specific scalar fields only when useful: `phase`, `iteration`,
`provider`, `model`, `tool_name`, `run_id`, `step_id`, `status`,
`elapsed_ms`, `retry_count`, `timeout_type`, and `error_class`.

## Redaction Rules

Never log raw prompts, raw messages, streamed token text, raw tool arguments,
raw tool output, API keys, bearer tokens, passwords, or secrets. Prefer shape
metadata such as object keys, list length, text length, exit code, status, and
error class. If a field might contain external content, use the diagnostic
context helper's redaction or shape helpers before logging.

Bad:

```python
logger.debug("tool args=%r output=%r", arguments, result)
```

Good:

```python
log_debug(
    logger,
    "tool.dispatch.success",
    lifecycle="success",
    phase="tool_exec",
    tool_name=name,
    output_shape=lambda: shape_metadata(result),
    _started_at=started_at,
)
```

## Performance And Resilience

Debug instrumentation must be cheap when disabled:

- Use `log_debug()` or guard expensive work with
  `logger.isEnabledFor(logging.DEBUG)`.
- Pass callables for shape metadata that would otherwise inspect large values.
- Do not emit high-cardinality or high-frequency logs in token streams, tight
  polling loops, or per-row storage paths.
- Prefer one correlated lifecycle event over repeated breadcrumbs.
- Log sink failures must not change application behavior.
- If rate limiting or suppression is added, document it and prefer one summary
  warning over repeated noise.
