Agent skill

Tracing Best Practices

by UniClipboard in UniClipboard/UniClipboard

TRIGGER when writing, modifying, or reviewing any Rust code that involves tracing, logging, spans, events,

AGPL-3.0Auto-check passed

Install Tracing Best Practices

skills CLI
$ npx skills add UniClipboard/UniClipboard --skill tracing-best-practices -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install UniClipboard/UniClipboard tracing-best-practices --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/UniClipboard/UniClipboard.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/tracing-best-practices .claude/skills/tracing-best-practices && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
tracing-best-practices
GitHub stars
1.9k
Token cost
~4k tokens
SKILL.md length
1,175 words
Files
1
Skills in repo
24
Repo updated
First seen
Licence
AGPL-3.0

At a glance

TRIGGER when writing, modifying, or reviewing any Rust code that involves tracing, logging, spans, events,

  • Works in 12 steps: Core Concepts → Where Spans Are REQUIRED → Where NOT to Use #[instrument] → …
  • Reviewing any Rust code that involves tracing
  • SKILL.md covers When to Apply, 1. Core Concepts, 2. Where Spans Are REQUIRED and 3. Where NOT to Use…, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Tracing Best Practices is an agent skill from UniClipboard/UniClipboard. TRIGGER when writing, modifying, or reviewing any Rust code that involves tracing, logging, spans, events,

Its SKILL.md is about 4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It works with Rust. The repository describes itself as: Real-time clipboard sync across all your devices — local-first, peer-to-peer, and end-to-end encrypted. No account. No cloud dependency. No central server. The licence is AGPL-3.0.

When your agent uses it

  • Reviewing any Rust code that involves tracing

Example prompts

  • “/tracing-best-practices”

Workflow steps

12 steps, taken from the step headings in SKILL.md.

  1. Core Concepts
  2. Where Spans Are REQUIRED
  3. Where NOT to Use #[instrument]
  4. #[instrument] Standard Template
  5. Event Standards
  6. Field Naming Convention
  7. Level Usage
  8. Error Handling + Tracing Rules
  9. State Machine Tracing (Project Priority)
  10. IPC / Daemon Tracing
  11. Subscriber Initialization
  12. Code Review Checklist

What it can do on your machine

Read from SKILL.md and the folder at commit add157e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are rust).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Tracing Best Practices loads about 4k tokens when it runs. Until then it costs about 32 tokens; SKILL.md has 1,175 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~32
When it runs · the whole SKILL.md, loaded when a task matches
~4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from UniClipboard/UniClipboard at commit add157e, republished under its AGPL-3.0 licence (© UniClipboard). 1,175 words, ~4,023 tokens.

Download SKILL.mdSave it as .claude/skills/tracing-best-practices/SKILL.md (or your agent's skills folder).
name
tracing-best-practices
description
TRIGGER when writing, modifying, or reviewing any Rust code that involves tracing, logging, spans, events,

Tracing Best Practices

When to Apply

This skill MUST be followed whenever you:

  • Add or modify #[instrument] attributes
  • Write tracing::info!, tracing::debug!, tracing::warn!, tracing::error!, tracing::trace! events
  • Create or modify spans (info_span!, debug_span!, etc.)
  • Write tokio::spawn or any async task spawning
  • Modify subscriber/tracing initialization code
  • Handle errors at boundary layers
  • Write state machine event handlers
  • Add IPC/daemon request handlers

1. Core Concepts

tracing records three types of structured data — NOT print text:

  • Span: A time range (request, usecase execution, state machine event handler)
  • Event: A discrete fact at a single moment ("received pairing proof", "db write failed")
  • Field: Structured key-value data (trace_id, device_id, session_id, state, elapsed_ms)
Design Principles
  • Spans = flow boundaries; Events = facts within flows
  • Every span MUST contain at least one event — #[instrument] alone only creates a span; tracing_subscriber::fmt only outputs events. A span with no events inside it produces zero log output, making the function invisible in logs.
  • Fields first, messages second
  • Stable field names over ad-hoc description strings
  • Record business context, never sensitive plaintext
  • Call chains connect via span hierarchy, not string search
  • Default to info/debug-safe for production

2. Where Spans Are REQUIRED

2.1 Entry Layer (MUST have top-level span)

Applies to: host command handlers, CLI handlers, HTTP/IPC handlers, background task entries, scheduled task entries.

rust
#[instrument(
    name = "cmd.get_clipboard_items",
    level = "info",
    skip(runtime),
    fields(trace_id = %uuid::Uuid::new_v4())
)]
pub async fn get_clipboard_items(runtime: State<'_, AppRuntime>) -> Result<Vec<Item>, String> {
    // ...
}

Requirements:

  • Every entry function MUST have a top-level span
  • MUST include trace_id or equivalent request identifier
  • MUST include business object IDs (session_id, device_id, space_id)
2.2 UseCase / Orchestrator Layer (MUST have span)

Applies to: start_join_space, submit_passphrase, persist_entry, handle_event, sync_once, etc.

rust
#[instrument(
    name = "space_access.submit_passphrase",
    level = "info",
    skip(self, passphrase),
    fields(session_id = %self.session_id, device_id = %self.device_id, state = ?self.state)
)]
async fn submit_passphrase(&mut self, passphrase: String) -> Result<()> {
    // Span name reflects business action, not technical detail
}
2.3 External Boundaries (at least event, preferably span)

Applies to: DB read/write, file I/O, network send/receive, subprocess calls, encryption boundaries, WebSocket/libp2p/relay/RPC.

  • MUST record: target object, result, elapsed time, error code/kind
  • Large payloads MUST NEVER be logged directly
2.4 Async Spawn (MUST propagate span)
rust
// CORRECT - Propagate current span
tokio::spawn(task().in_current_span());

// CORRECT - Create specific span for spawned work
let span = tracing::info_span!("pairing_session", session_id = %session_id);
tokio::spawn(task.instrument(span));

Long-lived background loops MUST create child spans or events per iteration. Channel/callback boundaries MUST re-attach message IDs into new span context.

2.5 Async Span Lifecycle — Three Correct Patterns
Core Rule: NEVER use .entered() in async functions

EnteredSpan contains *mut () → not Send → holding it across .await makes the future non-Send → tokio::spawn / JoinSet::spawn will fail to compile.

Pattern 1: Function-level — #[instrument] (preferred)

Best for: standalone async functions where parameters can be skipped.

rust
#[instrument(skip_all, fields(session_id = %session_id, peer_id = %peer_id))]
async fn handle_message(session_id: &str, peer_id: &str, msg: Message) -> Result<()> {
    info!("received message");  // automatically under the span
    do_something().await;       // await-safe
}
Pattern 2: Spawn-level — .instrument(span)

Best for: futures passed to tokio::spawn / JoinSet::spawn.

rust
let span = tracing::info_span!("pairing.action_loop");
tasks.spawn(run_action_loop(rx, cancel).instrument(span));
Pattern 3: Inline async block — async { }.instrument(span).await

Best for: match arms, if-branches, or other blocks that need a local span with .await inside.

rust
match event {
    Event::Succeeded { session_id } => {
        let span = info_span!("pairing.session", session_id = %session_id);
        async {
            info!(event = "succeeded");    // under the span
            notify_peer().await;           // await-safe
        }.instrument(span).await;
    }
}
FORBIDDEN Patterns
rust
// ❌ Compile error — EnteredSpan is not Send
let _guard = info_span!("my_span").entered();
something.await;  // _guard held across await

// ❌ Same problem, different syntax
let span = info_span!("my_span");
let _guard = span.enter();
something.await;  // _guard still held across await

3. Where NOT to Use #[instrument]

Pure utility functions — NO span

hash_bytes, normalize_path, parse_header, to_png — no business semantics, no span. Adds noise.

High-frequency hot paths — NO span

Tight loops, per-poll/tick functions, per-item iteration helpers. Use sampled events or aggregate stats instead.

Functions with sensitive/large parameters — MUST skip

#[instrument] records params via Debug by default. Passwords, tokens, ciphertext, large blobs WILL leak unless explicitly skip()-ed.


4. #[instrument] Standard Template

rust
#[instrument(
    name = "space_access.submit_passphrase",  // Stable name — survives refactors
    level = "info",                            // Explicit default level
    skip(self, passphrase),                    // Skip sensitive/large params
    fields(
        session_id = %self.session_id,         // Key business context
        device_id = %self.device_id,
        state = ?self.state
    )
)]
async fn submit_passphrase(&mut self, passphrase: String) -> Result<()> { ... }
skip Rules — ALWAYS skip:
  • self (unless Debug is very light and valuable)
  • All secrets: password, passphrase, token, secret
  • Large collections, binary data, raw request/response bodies
  • Sensitive DTOs, large Arc<AppState> / runtime / container
% vs ? Selection:
  • %field (Display): stable, short, search-friendly fields
  • ?field (Debug): enums, struct summaries, diagnostic detail
Return Values:

Do NOT automatically record full return values. Log key results as separate events:

rust
tracing::info!(session_id = %session_id, result = "accepted", "space access completed");
CRITICAL: #[instrument] Requires Events Inside the Function Body

#[instrument] generates a span, not an event. tracing_subscriber::fmt only writes events to log output (console/JSON file). A function with only #[instrument] and no event macros (info!, debug!, etc.) produces zero log output — the function is completely invisible in logs.

Every #[instrument]-annotated function MUST emit at least one tracing event. Minimum pattern:

rust
#[instrument(name = "api.search_query", level = "info", skip(state, params), fields(query = %params.query))]
async fn search_query_handler(state: State, params: Query) -> Result<Json<Response>, Error> {
    // ... business logic ...
    let result = do_search().await?;
    // At minimum, log the outcome — this makes the function visible in logs
    info!(total = result.total, "search completed");
    Ok(Json(result))
}

For thin delegation functions (usecases that just call a port), a single debug! after the call is sufficient:

rust
#[tracing::instrument(name = "usecase.index_entry.execute", skip(self, doc, postings), fields(entry_id = %doc.entry_id))]
pub async fn execute(&self, doc: SearchDocument, postings: Vec<SearchPosting>) -> Result<(), SearchError> {
    self.search_index.index_entry(doc, postings).await?;
    tracing::debug!("entry indexed successfully");
    Ok(())
}

5. Event Standards

Events record facts within a span. Message MUST be short; fields carry the data.

Success Event
rust
tracing::info!(
    session_id = %session_id,
    peer_id = %peer_id,
    attempt = retry_count,
    "relay connection established"
);
Failure Event

MUST include: error_kind (stable category), error or source = ?err, retryability flag, key context IDs.

rust
tracing::error!(
    session_id = %session_id,
    error_kind = "proof_verification_failed",
    retryable = false,
    error = %err,
    "space access failed"
);
State Machine Transition Event
rust
tracing::debug!(
    session_id = %session_id,
    event = "ReceivedProof",
    from_state = ?old_state,
    to_state = ?new_state,
    "state transition"
);

6. Field Naming Convention

Field names MUST be stable (once shipped, avoid renaming). Use snake_case.

Common Fields (use consistently):
FieldPurpose
trace_idCross-boundary request correlation
request_idPer-request identifier
session_idPairing/space session
task_idBackground task identifier
device_idDevice identifier
space_idSpace identifier
peer_idNetwork peer
user_actionWhat the user triggered
state / from_state / to_stateState machine context
elapsed_msDuration
retry_countRetry attempts
error_codeBusiness error code
error_kindStable error classification
Show full SKILL.md (468 more words)Show less
Error Field Breakdown — never log as single string blob:
  • error: human-readable summary
  • error_kind: stable classification
  • error_code: business error code
  • source: originating module
  • retryable: whether retry makes sense
FORBIDDEN as field values:
  • Plaintext passwords/tokens/secrets
  • Complete request/response bodies
  • Large binary content
  • User clipboard plaintext
  • Full configuration objects

When debugging, log: length, hash, summary, or object ID instead.


7. Level Usage

LevelMeaningExamples
ERRORUnrecoverable, or main flow result affectedDecryption failed, DB corruption, illegal state transition
WARNAbnormal but system continues, or fallback triggeredRelay failed -> switched backup, invalid config -> using default
INFOImportant business milestones (safe for production)Space join success, pairing established, sync start/complete
DEBUGDevelopment/troubleshooting contextState machine event received, branch selection, retry parameters
TRACEUltra-fine internal behavior (local debugging only)Per protocol frame, per loop iteration, per poll

8. Error Handling + Tracing Rules

Rule 1: Never "just return err" on critical failure paths

At least one error event MUST exist at the boundary where the error is discovered.

Rule 2: Don't repeat-bomb the same error up the stack
rust
// WRONG - Same error logged at 5 stack levels
error!("failed: {}", err);        // layer 1
error!("op failed: {}", err);     // layer 2
error!("handler failed: {}", err); // layer 3

// CORRECT - Full detail at boundary, summary at top
// At discovery boundary:
tracing::error!(error_kind = "db_write_failed", error = %err, entry_id = %id, "persist failed");
// Upper layer: just propagate via ? or log only business outcome
Rule 3: Timeout, cancel, and retry are distinct event types

Don't lump them with generic failures. They need separate classification for operational statistics.


9. State Machine Tracing (Project Priority)

State machines are the MOST important tracing target in this project.

Every event handling gets a span
rust
#[instrument(
    name = "space_access.handle_event",
    level = "debug",
    skip(self, event),
    fields(session_id = %self.session_id, state = ?self.state)
)]
async fn handle_event(&mut self, event: Event) -> Result<()> { ... }
Every state transition gets a structured event

Fields: event, from_state, to_state, reason, session_id.

Timeout / cancel / retry — separate event types

Never lump with generic failures.


10. IPC / Daemon Tracing

Request-level span REQUIRED

Fields: trace_id, request_id, route/command, client/source, session_id.

Cross-process trace_id

GUI sends trace_id with each daemon request; daemon creates span with same ID. Connects "frontend click -> IPC -> usecase -> infra" into one trace.

Never log sensitive body content

Record length, type, or object ID only.


11. Subscriber Initialization

Single initialization entry point ONLY

observability::init_tracing() / bootstrap::init_observability(). No module may independently initialize a subscriber.

Default filter

info baseline, own crates at debug, noisy third-party crates at warn. Uses EnvFilter with directives.

File output
  • Production MUST use non-blocking writer (tracing_appender::non_blocking)
  • WorkerGuard MUST be held for process lifetime
  • Rolling file strategy: daily (dev), daily/hourly with size limits (prod)

12. Code Review Checklist

When writing or reviewing tracing code, verify:

CheckRule
Entry function has span?MUST
Key usecase/orchestrator has span?MUST
#[instrument] function has at least one event inside?MUST
tokio::spawn propagates span?MUST
Sensitive params use skip()?MUST
Errors have structured fields (not just string)?MUST
Field names follow project convention?MUST
Subscriber init centralized?MUST
File output holds WorkerGuard?MUST
High-frequency function avoids needless #[instrument]?SHOULD
Span names stable and business-oriented?SHOULD
info level safe for long-term production?SHOULD
State machine transitions use structured events?SHOULD
Same error repeated across stack layers?FORBIDDEN
Secret/large payload in tracing output?FORBIDDEN
.entered() / .enter() held across .await in async?FORBIDDEN
#[instrument] with no events inside (silent span)?FORBIDDEN

© UniClipboard, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/tracing-best-practices of UniClipboard/UniClipboard.

Open the folder on GitHubat commit add157e

Compare with similar skills

Tracing Best Practices next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Tracing Best Practices compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Tracing Best Practices this skillUniClipboard/UniClipboard1.9k—~4kAutomated safety check: PassAGPL-3.0
Update V8 Versionopeninterpreter/openinterpreter69k2 repos~845Automated safety check: PassApache-2.0
Firecrawl Page Scrape Integrationfirecrawl/firecrawl190k1 repos~944Automated safety check: PassISC
Migrate Core Code to Submodulestinyhumansai/openhuman42k—~2.6kAutomated safety check: PassGPL-3.0
Rust TDD Workflowrtk-ai/rtk83k—~753Automated safety check: NotesApache-2.0
OpenLogi macOS Permissions TriageAprilNEA/OpenLogi23k—~2.5kAutomated safety check: NotesApache-2.0

Similar skills

  • Update V8 Version

    openinterpreter/openinterpreter

    Bumps the pinned v8 and rusty_v8 versions in Codex, validates the release-candidate path with the v8-canary check, and traces failures to upstream build changes.

    69k GitHub starsUsed in 2 repos~845 tokens
    DevOps & CloudAuto-check passed
  • Adds Firecrawl's /scrape endpoint to application code to pull markdown, HTML, links, screenshots or structured data from a single known URL.

    190k GitHub starsUsed in 1 repo~944 tokens
    Data & AnalyticsAuto-check passed
  • Migrate Core Code to Submodules

    tinyhumansai/openhuman

    Plans and carries out moving non-host-specific code and its tests from the OpenHuman core into vendored tiny submodule libraries, then releases the submodule and re-pins the host.

    42k GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Enforces red-green-refactor for Rust work, with idiomatic test patterns, a naming convention and a pre-commit gate of cargo fmt, clippy and test.

    83k GitHub stars~753 tokensUpdated today
    Testing & QAAuto-check: notes
  • Decides whether an OpenLogi device problem on macOS is a privacy-permission (TCC) problem, using agent log lines, and says which identity needs which grant.

    23k GitHub stars~2.5k tokensUpdated today
    DevelopmentAuto-check: notes
  • Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook.

    5.6k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed

More from UniClipboard/UniClipboard

All 24 skills in this repo
  • Beui

    UniClipboard/UniClipboard

    Pick and install beUI (@beui) animated React components from the shadcn registry.

    1.9k GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Create PR

    UniClipboard/UniClipboard

    Push the current branch and open a GitHub pull request against main.

    1.9k GitHub stars~4.6k tokensUpdated today
    Auto-check passed
  • Design Audit

    UniClipboard/UniClipboard

    定期审计代码库的工程设计问题(高心智复杂度、单一真相源被破坏、catch-all 胖接口、死代码、散落魔法字面量、泄漏抽象、资源生命周期靠环形缓冲)与可优化点,范围限定为自上次审计以来的 git churn,每条发现都落到 file:line 并对照本项目自己的 VISION.md / 各级 AGENTS.md / memory…

    1.9k GitHub stars~554 tokensUpdated today
    Auto-check passed
  • Dual Side Debug

    UniClipboard/UniClipboard

    Inspect uniclipboard logs from BOTH the macOS host and the mounted Windows peer when debugging cross-platform sync, pairing, transfer, or daemon issues.

    1.9k GitHub stars~2.6k tokensUpdated today
    Auto-check passed
  • E2E Test Thinker

    UniClipboard/UniClipboard

    Analyze the current branch's diff against main and determine which changes are testable via CLI-based end-to-end tests.

    1.9k GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • iOS Log Diagnose

    UniClipboard/UniClipboard

    Drive the UniClipboard iOS app in a simulator and read its OSLog yourself to diagnose a mobile-sync bug, instead of asking the user to paste logs.

    1.9k GitHub stars~1.1k tokensUpdated today
    Auto-check passed

Works with

Questions about Tracing Best Practices

What does Tracing Best Practices do?

TRIGGER when writing, modifying, or reviewing any Rust code that involves tracing, logging, spans, events,. Tracing Best Practices is an agent skill from UniClipboard/UniClipboard.

When should I use Tracing Best Practices?

Tracing Best Practices fits situations like: reviewing any Rust code that involves tracing.

How do I install Tracing Best Practices in Claude Code?

Run `npx skills add UniClipboard/UniClipboard --skill tracing-best-practices -a claude-code`. Or copy the skill folder (.agents/skills/tracing-best-practices in UniClipboard/UniClipboard) into .claude/skills/tracing-best-practices in your project. Claude Code loads it when a task matches its description.

How do I install Tracing Best Practices in Codex?

Run `npx skills add UniClipboard/UniClipboard --skill tracing-best-practices -a codex`. Or copy the skill folder (.agents/skills/tracing-best-practices in UniClipboard/UniClipboard) into .agents/skills/tracing-best-practices in your project. Codex loads it when a task matches its description.

Can I use Tracing Best Practices in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add UniClipboard/UniClipboard --skill tracing-best-practices -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/tracing-best-practices, .gemini/skills/tracing-best-practices, .github/skills/tracing-best-practices and .opencode/skills/tracing-best-practices in your project.

What does Tracing Best Practices need to run?

SKILL.md names no scripts, command-line tools or credentials: Tracing Best Practices is instructions for the agent only.

Does Tracing Best Practices access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Tracing Best Practices safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Tracing Best Practices use?

Tracing Best Practices is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Tracing Best Practices use?

About 4k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Tracing Best Practices?

Skills that share tags, products or a category with Tracing Best Practices: Update V8 Version (openinterpreter/openinterpreter, 69k stars), Firecrawl Page Scrape Integration (firecrawl/firecrawl, 190k stars), Migrate Core Code to Submodules (tinyhumansai/openhuman, 42k stars) and Rust TDD Workflow (rtk-ai/rtk, 83k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Tracing Best Practices?

UniClipboard (a GitHub organization) maintains it in UniClipboard/UniClipboard, which has 1,867 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 10, 2026.

Source: UniClipboard/UniClipboard on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.