Skip to content

docs(observed): align documentation with the runtime contract - #710

Open
Evgenii (Vaiz) wants to merge 2 commits into
mainfrom
u/vaiz/2026/08/28/observed-docs-contract
Open

docs(observed): align documentation with the runtime contract#710
Evgenii (Vaiz) wants to merge 2 commits into
mainfrom
u/vaiz/2026/08/28/observed-docs-contract

Conversation

@Vaiz

Copy link
Copy Markdown
Contributor

🤖 Clawpilot here! Posted automatically by Clawpilot (an AI agent), not by a human. Please verify before acting.

Problem

Public documentation for observed states guarantees the implementation does not make. Each statement below was checked against the code on main and found to be wrong, not merely imprecise. A reader who trusts them writes a processor that pays costs it expects to avoid, or that relies on an invariant nothing enforces.

What changes

Only prose changes. No code, no public API, no test behavior.

  • Redaction. The docs said every event goes through one redaction-safe pipeline. In fact each processor supplies its own redactor at extraction time, and #[unredacted] fields plus unclassified enrichment values bypass it entirely. The guarantee is now scoped to classified values.
  • Routing. Sink::emit said it emits to every registered processor. It builds the event only when a processor is interested and dispatches only to interested processors.
  • Disabled events. Documented as suppressed unless a processor opts in. The sink has no such gate; the flag is metadata a processor reads in is_interested.
  • Severity. Documented as a single statement fixing both routing and the exported level. A processor may remap or drop it.
  • Laziness. "Zero cost for rejected fields" overstates the guarantee. Skipping a getter avoids evaluation, conversion, redaction and their allocations, but enumeration and visitor calls still happen. Now stated that way.
  • Enrichment scope. "Global enrichment" implied process-wide reach. Entries live in a sink's own slot; the real distinction is targeted vs untargeted.
  • Event identity. EventDescription was described as compile-time only. Dynamic events build it at runtime and then carry no Rust TypeId, so name matching is the portable choice.
  • Timestamps. EventView::timestamp was documented as captured at view creation; synthetic views supply their own.
  • Transfer ordering. The wrapper-order caveat claimed entries are dropped in every unsupported shape. Loss requires the enrichment and the transfer to overlap on the same captured slot.
  • Smaller corrections. Text::Static is not "almost every field"; the instrument-kind list omitted UpDownCounter; the log-body placeholder keys and brace grammar were undocumented; the INTERNAL_CRATES comment named the wrong consumer; the no-globals rule did not admit the recursion guard.

crates/observed/README.md is regenerated from src/lib.rs, not hand-edited.

Effects

  • Documentation matches observed behavior, so a processor author can rely on it.
  • The redaction wording no longer implies unclassified and #[unredacted] values are protected.
  • "Zero cost" no longer appears as an unqualified claim.
  • No behavior, API surface or test outcome changes.

Validation

just anvil-readme-check, just anvil-fmt, just anvil-clippy, cargo +1.96.1 doc --no-deps, and cargo +1.96.1 test -p observed -p observed_testing all pass.

Work items

Closes ADO 7757572, 7757577, 7757578, 7757584, 7757602, 7757605, 7757607, 7757608, 7757610, 7757611, 7757613, 7757614, 7757616, 7757618, 7757621 (feature 7757535).

Copilot AI lite review requested due to automatic review settings August 28, 2026 14:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates observed crate documentation to accurately reflect the runtime behavior and contracts around redaction, routing/interest checks, disabled events semantics, laziness costs, enrichment scoping/transfer ordering, event identity, timestamps, and the thread-wide recursion guard. Changes are prose-only (doc comments / markdown / comments), with crates/observed/README.md updated as a regeneration from src/lib.rs.

Changes:

  • Clarifies redaction guarantees and explicitly scopes what is (and is not) redacted by the library (e.g., #[unredacted], unclassified enrichment, dynamic adaptor values).
  • Aligns documented routing/interest behavior (event construction and dispatch only when processors are interested; disabled is processor-interpreted metadata).
  • Refines documentation of laziness costs, enrichment terminology (“untargeted” vs “global”), transfer-order caveats, and runtime-vs-compile-time event identity.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/observed/src/text.rs Refines Text variant documentation to match actual storage/clone tradeoffs.
crates/observed/src/sink/core.rs Updates Sink docs to reflect interest-gated construction/dispatch and “untargeted vs targeted” enrichment terminology.
crates/observed/src/processing/event_view.rs Clarifies laziness/overhead semantics and corrects timestamp/severity/description wording.
crates/observed/src/metadata/metric.rs Generalizes instrument-kind wording to match supported kinds.
crates/observed/src/metadata/event.rs Updates EventDescription docs to cover runtime-constructed descriptions and optional type identity; clarifies disabled-event semantics.
crates/observed/src/lib.rs Aligns crate-level docs and attribute-table semantics (redaction, disabled, log body placeholder rules).
crates/observed/src/event.rs Re-scopes the redaction “single pipeline” claim to match actual extraction/bypass behavior.
crates/observed/src/enrichment/entry.rs Clarifies classified vs unclassified enrichment handling and untargeted scoping semantics.
crates/observed/src/context/transferred.rs Refines wrapper-order caveat wording to describe when enrichment may be lost.
crates/observed/src/context/transfer.rs Renames “global” to “untargeted” in transfer enrichment docs and clarifies scope.
crates/observed/README.md Regenerated README content to reflect updated src/lib.rs documentation.
crates/observed/FEATURES.md Updates feature documentation for interest-based dispatch, enrichment scoping, and redaction bypasses.
crates/observed/DESIGN.md Aligns design document with actual behavior (redaction scope, disabled semantics, enrichment isolation/transfer caveats, recursion guard).
crates/observed_testing/tests/disabled_events.rs Updates test documentation to match processor-controlled disabled-event behavior.
crates/observed_testing/Cargo.toml Corrects comment about automation::INTERNAL_CRATES consumers (external-types + mutation orchestration).

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +8 to +10
//! they need. Skipped getters never evaluate, convert, or redact their values
//! and avoid the associated allocations, while field enumeration and visitor
//! work still occur.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Clawpilot here! Posted automatically by Clawpilot (an AI agent), not by a human. Please verify before acting.

Declining: the subject here is compound — "field enumeration and visitor work" — so the plural "occur" is the correct agreement. "occurs" would only be right if "visitor work" stood alone.

@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.0%. Comparing base (356dc63) to head (27f7759).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #710   +/-   ##
=======================================
  Coverage   100.0%   100.0%           
=======================================
  Files         563      563           
  Lines       61068    61068           
=======================================
  Hits        61068    61068           
Flag Coverage Δ
linux 64.2% <ø> (?)
linux-arm 67.8% <ø> (?)
windows 68.6% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Vaiz
Evgenii (Vaiz) marked this pull request as draft August 28, 2026 14:50
Evgenii (Vaiz) and others added 2 commits August 28, 2026 15:53
Public documentation described guarantees the implementation does not
make. Restate them as the code behaves:

- redaction is applied by the processor-supplied redactor at extraction
  time, and #[unredacted] fields and unclassified enrichments bypass it
- routing is decided by is_interested() before the event is built, so a
  sink dispatches only to interested processors
- the disabled flag is processor-controlled metadata, not sink-enforced
  suppression, and severity is metadata a processor may remap
- skipping a getter avoids value evaluation, conversion, redaction and
  their allocations, but enumeration still happens; drop "zero cost"
- enrichment entries are scoped to a sink slot; "global" only meant
  untargeted
- EventDescription may be built at runtime by dynamic events and then
  carries no Rust type identity
- timestamp() is the event-associated time, which synthetic views supply
- the transfer wrapper-order caveat applies to overlapping captured
  slots, not every sink combination
- Text::Static is not "almost every field", and the instrument-kind list
  was missing UpDownCounter
- document the log-body placeholder keys and brace grammar the macro
  actually validates
- correct the INTERNAL_CRATES consumer comment and the recursion-guard
  exception to the no-globals rule

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CI dictionary carries "adaptor" but not the plural inflection, so the
new wording tripped cargo spellcheck on two doc comments.
@Vaiz
Evgenii (Vaiz) force-pushed the u/vaiz/2026/08/28/observed-docs-contract branch from 3278ecd to 27f7759 Compare August 28, 2026 14:57
@github-actions

Copy link
Copy Markdown

⚠️ Potential breaking changes detected

cargo semver-checks flagged the following on this PR. This is informational -- breaking changes between commits are expected; the major-version bump happens at release time, not on every PR.

observed

     Cloning origin/main
    Building observed v0.25.0 (current)
       Built [   5.385s] (current)
     Parsing observed v0.25.0 (current)
error: unsupported rustdoc format v60 for file: /home/runner/work/oxidizer/oxidizer/target/semver-checks/local-observed-0_25_0-default-d7b8c5ec6ce39049/target/doc/observed.json
(supported formats are v55, v56, v57)

observed_testing

     Cloning origin/main
    Building observed_testing v0.0.0 (current)
       Built [   5.748s] (current)
     Parsing observed_testing v0.0.0 (current)
error: unsupported rustdoc format v60 for file: /home/runner/work/oxidizer/oxidizer/target/semver-checks/local-observed_testing-0_0_0-default-01666ec060466c14/target/doc/observed_testing.json
(supported formats are v55, v56, v57)

observed_utils

     Cloning origin/main
    Building observed_utils v0.2.0 (current)
       Built [   5.589s] (current)
     Parsing observed_utils v0.2.0 (current)
error: unsupported rustdoc format v60 for file: /home/runner/work/oxidizer/oxidizer/target/semver-checks/local-observed_utils-0_2_0-default-01666ec060466c14/target/doc/observed_utils.json
(supported formats are v55, v56, v57)

@Vaiz
Evgenii (Vaiz) marked this pull request as ready for review August 28, 2026 15:31
Copilot AI review requested due to automatic review settings August 28, 2026 15:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants