Skip to content

docs(telemetry): document the hook/plugin span-production rule and enforce it (Epic #929) #1464

Description

@planetf1

Parent epic: #929
Phase: cross-cutting (do before #1142 starts)
Depends on: nothing
Blocks: #1466

Problem

Mellea has a hard rule about how spans are produced — library code fires a hook,
and a plugin in mellea/telemetry/tracing_plugins.py turns that hook into a
span. Library code never opens spans itself. That rule is nowhere written down,
and nothing enforces it, so it keeps being broken by people acting in good faith.

The history matters, because it explains why "just read the docs" is not
currently an answer:

  1. Until refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181 (2026-06-10, refactor(telemetry)!), calling the span helpers
    directly from library code was the pattern. All five backends contained a
    bare span = start_generate_span(...), with the supporting machinery in
    mellea/telemetry/backend_instrumentation.py.
  2. refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181 moved span production onto hooks and plugins and deleted that module.
    This was the right change.
  3. refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181 rewrote around 97 lines of docs/docs/observability/tracing.md — and
    that page still contains no occurrence of the word "plugin". It documents
    which spans exist and what attributes they carry, never how a span comes to be
    produced.
  4. There is no import contract, so reintroducing the pre-refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181 pattern is
    invisible to CI.
  5. The only in-code example of importing telemetry.tracing is
    mellea/stdlib/session.py, which is a deliberate, documented exception
    (OTel Token attach/detach is task-affine). Anyone using it as a template
    copies the exception rather than the pattern.
  6. Six weeks after refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181, docs/dev/adapter_observability.md was written and
    describes the pre-refactor(telemetry)!: move backend tracing onto plugin/hook pattern #1181 approach, naming start_backend_span /
    start_action_span as the model to mirror.
  7. feat(backends): LocalFileBinding implements verbs (PEFT/aLoRA path) + from_catalog() (Epic #929 Phase 2) #1141 followed that document, and produced spans inline inside
    mellea/backends/. They are being removed in PR feat(backends): LocalFileBinding implements verbs (PEFT/aLoRA path) + from_catalog() (Epic #929 Phase 2) #1454.

Two live consequences:

There is also a structural gap that makes the rule impossible to follow for
adapter functions specifically. ADAPTER_FUNCTION_INVOCATION_COMPLETE and
ADAPTER_FUNCTION_PHASE_COMPLETE are the only HookType family with no
pre/start sibling, so there is no event at which a plugin could open those spans.
Documenting the rule without noting this would set an unmeetable expectation.

Scope

Out of scope

Adding the missing start hooks, and emitting adapter-function spans — both belong
to #1466, which this issue blocks.

Acceptance criteria

  • docs/docs/observability/tracing.md states the hook-fires/plugin-emits rule
    and contains at least one worked reference to tracing_plugins.py
  • The mellea/stdlib/session.py exception is documented as such
  • docs/dev/adapter_observability.md no longer instructs implementers to call
    start_*_span from library code
  • A CI check fails on a new telemetry.tracing import under
    mellea/backends/, with session.py allowlisted
  • The check is verified to fail by temporarily reintroducing such an import
    (evidence in the PR description; the temporary change is not committed)
  • feat(backends): EmbeddedBinding implements apply_activation (Granite Switch path); remove render_controls + set_request_adapter (Epic #929 Phase 2) #1142's telemetry acceptance criteria updated
  • npx markdownlint-cli2 passes on every page touched

References

Metadata

Metadata

Assignees

Labels

area/adapter-functionsGranite adapter functions: framework and adaptiers including RAG, Guardian, Corearea/telemetryOTel spans, metrics, tracing, semconvdocumentationImprovements or additions to documentationp1High: important bugs (workaround exists) or high-value core features. Do soon, not on fire.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions