Skip to content
Back to skills

Logging Patterns

ASecurity

Use for changes under cli/src/infra/logging/, task result recording, status rows, progress lines, detail ordering, or final summaries. Not for generic error policy or task scheduling without output changes.

  • 3 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added August 31, 2026
businessshell

Works with

  • cursor
  • cli

Security analysis

A100/100

Scanned September 24, 2026

npx -y skills add sneivandt/dotfiles --skill logging-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Logging Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Logging Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sneivandt-logging-patterns/badge)](https://www.skillsdirectory.com/skills/sneivandt-logging-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: logging-patterns
description: >
  Use for changes under cli/src/infra/logging/, task result recording, status
  rows, progress lines, detail ordering, or final summaries. Not for generic
  error policy or task scheduling without output changes.
---

# Logging Patterns

## Ownership

- Startup initializes one shared `Logger`; task code uses `ctx.log()`.
- `engine::execute()` records task results. Tasks do not call
  `record_task()` directly.
- Records are keyed by `Task::log_key()`, never display name.
- `ExecutionSummary` controls success and later phases. Logger counters are
  presentation only.
- Keep status labels/styles together in `logger/summary/status.rs::presentation`.
  Raw tracing and UI messages share formatting through `ui_line_with_style`;
  raw DEBUG/TRACE remain hidden even when UI debug details are verbose-visible.
- Reuse `duplicates_task_message` for buffered replay and completed rows, and
  `progress_clear_sequence` for cursor clearing. Do not duplicate these pure
  decisions across sinks.

## Output contract

- Visible task rows stay in natural completion order.
- Separate visible task blocks by one blank line for mutation commands and in
  verbose output; compact consecutive one-line check rows. A check task with
  details keeps a blank line on both sides. Hidden tasks add no spacing.
- Task names, structured startup labels such as `CLI upgraded`, live `Running`,
  and the first summary outcome are bold. Action details, active task names, and
  transient self-update work use normal contrast. Startup metadata, progress
  counts, context, reasons, and timing stay dim. `No changes` is bold in the
  default foreground. Plain output preserves spacing without ANSI styling.
- Non-verbose mode shows reportable outcomes; verbose mode also shows current
  tasks plus elapsed time. Not-applicable tasks stay out of console output in
  both modes but remain in persistent run records and progress accounting.
- A task reason stays on its status row after ` · `. Indented lines are actions
  or planned actions and must not restate the row.
- Emit resource actions with `Output::action(verb, subject, planned, message)`.
  Supply the imperative console form in `message`, including contextual suffixes.
  Typed actions persist once before buffering. Sort only consecutive typed action
  runs and preserve warning/context barriers; never classify or rephrase messages
  by their text.
- Emit generated counters with `summary`, and mark generated task-result reasons
  with `with_summary_message`. Custom reasons remain visible even if they resemble
  counter text.
- Resource descriptions read `subject -> value`; symlinks are `target -> source`.
- Final summaries count tasks, not detail lines or parsed display text.
- Progress uses `Running · {remaining} remaining · {active}`. The count covers
  unfinished scheduled visible tasks within a phase. Non-applicable tasks reduce
  it when they finish but do not contribute to final totals.
- Keep skipped, blocked, and interrupted outcomes distinct in rows and totals.
  Typed cancellation is interrupted; dependency prevention is blocked.
- Transient status lines are always cleared and never replace durable logging.

## Message intent

| Intent | Use |
|---|---|
| `trace` | plumbing that never reaches the console |
| `debug` | diagnostic item detail |
| `context` | dim contextual block visible only in verbose output; caller owns indentation |
| `action` | applied or planned item detail with explicit verb and subject |
| `info` | informational detail, not an inferred action |
| `summary` | aggregate counters retained only in the run log |
| `warn` / `error` | visible problems |
| `dry_run` | planned mutation |
| `always` | output that must be visible |
| `startup` | a structured startup notice; label bold before ` · `, metadata dim |

## Persistent records

- Extend `records.rs::Record` for facts that consumers need to query. Keep schema
  versions explicit; preserve unknown records and legacy text in the viewer.
- Use stable task keys, not labels or `TypeId` debug text. Task decorators must
  forward `log_key()` and worker threads must inherit the owning task's context.
- Record run start, resolved context, and finish independently of console totals.
  Restarted and elevated children receive the parent ID through `child_args`.
  A missing finish record means unfinished, not necessarily crashed.
- Failure hints select the exact run with `--id` and diagnostics with `-v`.
  Do not offer a hint when the persistent sink is unavailable or degraded.
- Preserve multiline messages and command streams in storage. Normal log viewing
  includes failed command diagnostics and successful stderr. `--raw` reads stored
  records; `--task` filters by stable public selector or exact stored identity.
- Test lifecycle and parent linkage, stable selection after newer runs,
  task filtering, legacy/unknown records, output retention, and multiline parity.

Do not hardcode indentation, duplicate task recording, rephrase a task reason as
detail, or build task-local buffering.

Command arguments are logged by default. Use `CommandSpec::redact_arguments()`
when they contain sensitive values, and separately avoid exposing secrets in
stdout, stderr, resource descriptions, or errors. `OutputLog::Diagnostics`
retains failed streams and successful stderr; `Full` also retains successful
stdout. Use `OutputLog::Omit` for sensitive streams; it also removes streams
from checked-command errors. Successful and unchecked results remain available
to the caller, which must avoid logging them itself. Argument redaction is
independent. Use synthetic values in log fixtures and snapshots.

When summary semantics change, test statuses, visibility, details, progress
denominator, totals, both verbose modes, and `--no-symbols`. Preserve durable run
logs when changing console filtering or transient output. Start with
[summary rendering](../../../cli/src/infra/logging/logger/summary/) and
[subscriber tests](../../../cli/src/infra/logging/subscriber/tests.rs).
The summary and subscriber matrices own exact plain/ANSI presentation across
statuses, modes, verbosity, and symbols. [Buffered tests](../../../cli/src/infra/logging/buffered/tests.rs)
own direct/buffered persistence parity, completion order, and action barriers.
Wrapper style belongs in `shell-patterns`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.