{"slug":"otel-weaver","title":"otel-weaver","summary":"OpenTelemetry Weaver registry authoring, codegen, and CI enforcement. Use when adopting Weaver, authoring or reviewing a registry (manifest, attributes, metrics, spans, events), writing Jinja2 templates against the resolved schema, migrating hand-maintained telemetry constants, w","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-10-16T16:29:05.619439Z","repo":{"url":"https://github.com/ollygarden/opentelemetry-agent-skills","stars":111,"forks":13,"license":"Apache-2.0","updatedAt":"2026-10-16T08:07:28Z"},"bodyHtml":"<hr>\n<h2>name: otel-weaver\ndescription: OpenTelemetry Weaver registry authoring, codegen, and CI enforcement. Use when adopting Weaver, authoring or reviewing a registry (manifest, attributes, metrics, spans, events), writing Jinja2 templates against the resolved schema, migrating hand-maintained telemetry constants, wiring <code>weaver registry check</code>/<code>generate</code>/<code>diff</code> into CI, or choosing a Weaver version for a semantic-conventions release.</h2>\n<h1>OpenTelemetry Weaver</h1>\n<p>Use this skill when an organization wants to define its own semantic conventions on top of upstream OTel and generate language bindings from them.</p>\n<p>Usage:</p>\n<ul>\n<li>pair with <code>otel-semantic-conventions</code> to decide which attributes already exist upstream and should not be redeclared in the local registry</li>\n<li>latest Weaver version: the <code>otel-sdk-versions</code> index if it lists Weaver, else <a href=\"https://github.com/open-telemetry/weaver/releases\">https://github.com/open-telemetry/weaver/releases</a>; <code>references/ci-integration.md</code> keeps a dated Weaver/semconv compatibility record for offline answers</li>\n</ul>\n<p>If a companion skill is unavailable:</p>\n<ul>\n<li>do not stop</li>\n<li>do not rely on memory alone when the guidance can be checked from official sources</li>\n<li>consult the Weaver repo, <code>schemas/semconv-syntax.v2.md</code>, and <code>docs/usage.md</code> / <code>docs/validate.md</code></li>\n<li>state which fallback you used and leave any unverified item unresolved</li>\n</ul>\n<h2>Mental Model</h2>\n<p>Three moving parts:</p>\n<ol>\n<li><strong>Registry</strong> — directory of YAML files. <code>manifest.yaml</code> is required; its <code>schema_url</code> (OTel schema URL format, <code>http[s]://host/path/&lt;version&gt;</code>) both names the registry and carries its version in the final path segment. Dependency entries also require <code>schema_url</code> plus optional <code>registry_path</code>. The rest declare <code>attributes</code>, <code>metrics</code>, <code>spans</code>, <code>events</code>, <code>entities</code>. The version segment of <code>schema_url</code> is yours to manage; bump it on changes. (<code>semconv_version</code> and <code>schema_base_url</code> are deprecated in favor of <code>schema_url</code>; top-level <code>name</code> is not a v0.26.1 manifest field.)</li>\n<li><strong>Templates</strong> — directory of MiniJinja files (Jinja2-compatible, not full Jinja2 — auto-escaping is off by default since v0.22.0 and loop <code>break</code>/<code>continue</code> are supported) plus a <code>weaver.yaml</code> per target language describing which templates to run, with what filter, in what <code>application_mode</code>, and with what output filename.</li>\n<li><strong>Policies</strong> — Rego rules evaluated by the Regorus (OPA-compatible) engine, in four packages: <code>before_resolution</code> (raw parsed groups; unsupported and skipped with <code>--v2</code>), <code>after_resolution</code> (resolved registry), <code>comparison_after_resolution</code> (only when <code>--baseline-registry</code> is passed), and <code>live_check_advice</code> (per-sample during <code>live-check</code>). Built-in OTel policies are the floor; custom policies layer on org rules.</li>\n</ol>\n<p>These three replace a hand-rolled <code>const.go</code> (or equivalent): const blocks become the registry, the act of writing them becomes codegen, and tribal knowledge becomes policies.</p>\n<h2>Non-Negotiable Rules</h2>\n<ul>\n<li>Install Weaver via one of the methods documented at <a href=\"https://github.com/open-telemetry/weaver#install\">https://github.com/open-telemetry/weaver#install</a> (release binary, <code>otel/weaver:vX.Y.Z</code> Docker image, or the <code>setup-weaver</code> GitHub Action). Never <code>brew install weaver</code> — that resolves to an unrelated Scribd tool.</li>\n<li>Reference upstream semconv attributes by <code>ref</code> rather than redeclaring them. Boundary domains (<code>http</code>, <code>db</code>, <code>messaging</code>, <code>rpc</code>, <code>network</code>, <code>gen-ai</code>, ...) belong in upstream OTel semconv, not in a local registry. Use the language SDK's semconv package for those at runtime.</li>\n<li>Every attribute and signal definition needs <code>stability</code>; include it on enum members too, as required by the v2 syntax guide. Weaver v0.26.1 rejects missing definition stability but reports missing enum-member stability only as a non-fatal warning in normal mode.</li>\n<li>In v2, an attribute reference may refine fields such as <code>brief</code>, <code>note</code>, <code>examples</code>, and <code>annotations</code>, but not <code>stability</code> or <code>deprecated</code>; those always come from the attribute definition.</li>\n<li>Use a domain prefix (e.g. <code>ecommerce.</code>, <code>acme.</code>) for org-local attributes, metrics, and spans.</li>\n<li>Run the language formatter (<code>gofmt -w</code>, <code>prettier</code>, <code>ruff format</code>, ...) on generated output. Jinja whitespace produces multiple blank lines; without formatting, the diff check in CI will fail spuriously.</li>\n<li>Confirm the resolved schema shape before writing a template. For a <code>definition/2</code> registry, call the grouped jq helpers with <code>{\"v2\": true}</code>; the v2 template <code>ctx</code> preserves fields such as attribute <code>key</code>, metric <code>name</code>, span <code>type</code>/<code>kind</code> and structured <code>span.name.note</code>, plus entity <code>type</code>/<code>identity</code>/<code>description</code>. See <code>references/template-authoring.md</code> for how to dump the exact shape.</li>\n</ul>\n<h2>Workflow</h2>\n<ol>\n<li><strong>Install or locate Weaver.</strong> Follow the upstream install instructions at <a href=\"https://github.com/open-telemetry/weaver#install\">https://github.com/open-telemetry/weaver#install</a> — pick a pinned release binary, the <code>otel/weaver:vX.Y.Z</code> Docker image, or the <code>setup-weaver</code> GitHub Action. Use Docker for CI and reproducible local runs.</li>\n<li><strong>Author the registry.</strong> Required: <code>manifest.yaml</code> plus one or more <code>definition/2</code> YAML files declaring attributes, attribute groups, metrics, spans, events, or entities. See <code>references/registry-authoring.md</code>.</li>\n<li><strong>Author templates.</strong> One target dir per language under <code>templates/registry/&lt;lang&gt;/</code> with <code>weaver.yaml</code> plus <code>*.j2</code>. See <code>references/template-authoring.md</code>.</li>\n<li><strong>Validate and generate.</strong> <code>weaver registry check --v2 -r ./telemetry/registry/</code> for fast feedback. <code>weaver registry generate --v2 --registry ./telemetry/registry/ --templates ./telemetry/templates/ &lt;lang&gt; &lt;output-dir&gt;</code> for codegen. Run the language formatter on the output.</li>\n<li><strong>Wire into CI.</strong> Three gates: <code>check</code> (schema), <code>generate</code> + <code>git diff --exit-code</code> (checked-in code is current), <code>diff</code> against the base branch (surfaces breaking changes). See <code>references/ci-integration.md</code>.</li>\n</ol>\n<p>The Weaver CLI has more subcommands than this workflow touches: <code>stats</code> and <code>json-schema</code> for quick registry sanity checks, <code>update-markdown</code> for keeping semconv snippets in docs current, <code>emit</code>/<code>live-check</code>/<code>infer</code> for working against live OTLP telemetry, <code>package</code> for writing a self-contained resolved registry artifact (the replacement for the deprecated <code>resolve</code>), <code>mcp</code> for exposing a registry to LLM tooling, and <code>serve</code> for an HTTP+UI mode. All are out of scope here (see below) but worth knowing exist before assuming <code>check</code>/<code>generate</code>/<code>diff</code> is the whole surface.</p>\n<h2>Gotchas</h2>\n<p>These cost time and are not obvious from the upstream docs:</p>\n<ol>\n<li><code>brew install weaver</code> installs the wrong tool. Use GitHub releases or Docker.</li>\n<li>Generated output is not formatter-clean. Always run the language formatter after <code>weaver registry generate</code>.</li>\n<li>Jq helper defaults target the legacy schema. For <code>definition/2</code>, pass <code>{\"v2\": true}</code> and use the preserved v2 fields: attribute <code>key</code>, metric <code>name</code>, span <code>type</code>/<code>kind</code> and <code>span.name.note</code>, plus entity <code>type</code>/<code>identity</code>/<code>description</code>. Always generate and inspect the filtered <code>ctx</code> before writing a template.</li>\n<li>The <code>comment</code> Jinja filter takes a keyword argument: <code>attr.brief | comment(format=\"go\")</code>. It already emits the <code>// </code> prefix; do not add another.</li>\n<li>Attributes, metrics, spans, events, and entities all have prebuilt grouped jq filters (<code>semconv_grouped_attributes</code>, <code>semconv_grouped_metrics</code>, <code>semconv_grouped_spans</code>, <code>semconv_grouped_events</code>, <code>semconv_grouped_entities</code>). For <code>definition/2</code>, use (for example) <code>semconv_grouped_spans({\"v2\": true})</code> as a folded YAML scalar; the bare helper defaults select the legacy schema.</li>\n<li><code>weaver registry check</code> emits \"File format <code>definition/2</code> is not yet stable\" (a warning) for custom v2 definition files (still so in the dated record in <code>references/ci-integration.md</code>). This is normal; do not treat it as a failure.</li>\n<li><code>--future</code> is opt-in but still elevates the <code>definition/2</code> instability warning to an error for a custom v2 registry. Leave it off until the format goes stable.</li>\n<li>CLI argument ordering for <code>generate</code>: target directory name is positional <strong>after</strong> <code>--registry</code> and <code>--templates</code>; the output directory follows. <code>--templates</code> points at the <strong>parent</strong> that contains target dirs, not at the language-specific subdir.</li>\n<li>Span name in registry vs. runtime: required schema fields are <code>type</code>, <code>kind</code> (<code>client</code>/<code>server</code>/<code>producer</code>/<code>consumer</code>/<code>internal</code>), <code>brief</code>, <code>stability</code>, and a structured <code>name: { note: \"...\" }</code>. For internal business spans, putting the dotted type identifier in <code>name.note</code> and rendering the resolved <code>span.name.note</code> string at runtime is clean.</li>\n<li><strong>What does NOT belong in your local registry.</strong> DB, HTTP, messaging, RPC, network, GenAI, and similar boundary spans/attributes follow upstream OTel semconv. Until upstream is pulled in as a manifest dependency, instrumentation for those should reference the language SDK's semconv package directly. This is the most common modeling mistake.</li>\n<li>Counter and UpDownCounter names should not append <code>_total</code>; this is the semconv v1.44.0 naming rule.</li>\n<li>Duration instruments should use seconds (<code>s</code>) under the semconv v1.44.0 unit guidance.</li>\n</ol>\n<h2>References To Load On Demand</h2>\n<ul>\n<li>registry YAML field reference: <code>references/registry-authoring.md</code></li>\n<li>Jinja2 patterns, jq filters, resolved-shape cheat sheet: <code>references/template-authoring.md</code></li>\n<li>ready-to-lift GitHub Actions example and the dated version-compatibility record: <code>references/ci-integration.md</code></li>\n<li>hand-maintained-constants → registry walkthrough: <code>references/migration-playbook.md</code></li>\n<li>semantic conventions skill: <code>otel-semantic-conventions</code></li>\n<li>manual instrumentation skill: <code>manual-instrumentation</code></li>\n</ul>\n<h2>Out Of Scope</h2>\n<p>These are natural follow-ups but not part of this skill:</p>\n<ul>\n<li>publishing the registry as a versioned artifact for downstream consumers (<code>weaver registry package</code>)</li>\n<li>declaring upstream semantic-conventions as a manifest dependency</li>\n<li><code>weaver registry live-check</code>/<code>emit</code>/<code>infer</code> against live OTLP telemetry</li>\n<li><code>weaver registry mcp</code> / <code>weaver serve</code></li>\n<li>custom Rego policies beyond the built-ins</li>\n<li>helper-function codegen (<code>MyMetricName(meter)</code> wrappers)</li>\n</ul>\n<h2>Verification Contract</h2>\n<p>If you authored or modified a Weaver registry, templates, or CI integration:</p>\n<ul>\n<li>re-open the changed files before finishing</li>\n<li>run <code>weaver registry check --v2</code> against the <code>definition/2</code> registry and capture the result</li>\n<li>run <code>weaver registry generate --v2</code> and the language formatter, then verify <code>git diff --exit-code</code> is clean</li>\n<li>confirm each applicable item with codebase evidence</li>\n</ul>\n<p>Report the final check with:</p>\n<ul>\n<li><code>[x]</code> completed</li>\n<li><code>[~]</code> not applicable, with a reason</li>\n<li><code>[ ]</code> unresolved</li>\n</ul>\n<p>Use these items:</p>\n<ul>\n<li>registry has <code>manifest.yaml</code> with a <code>schema_url</code> whose final path segment is the version</li>\n<li>every definition and enum member has <code>stability</code></li>\n<li>org-local attributes/metrics/spans use a domain prefix</li>\n<li>no boundary-domain (http/db/messaging/rpc/network/gen-ai) entries duplicated locally</li>\n<li>Counter and UpDownCounter names have no <code>_total</code> suffix</li>\n<li>duration histograms use <code>s</code> (seconds)</li>\n<li>templates use jq filters that match the resolved schema (for <code>definition/2</code>, call the prebuilt <code>semconv_grouped_*</code> helpers with <code>{\"v2\": true}</code>)</li>\n<li>generated output is formatter-clean</li>\n<li>CI runs <code>check</code>, <code>generate</code> + <code>git diff --exit-code</code>, and <code>diff</code> against the base branch</li>\n<li>changed files were re-read</li>\n<li>remaining risks or gaps are stated</li>\n</ul>\n","files":[{"path":"evals/evals.json","sizeBytes":1126,"isText":true},{"path":"references/ci-integration.md","sizeBytes":4728,"isText":true},{"path":"references/migration-playbook.md","sizeBytes":4359,"isText":true},{"path":"references/registry-authoring.md","sizeBytes":8050,"isText":true},{"path":"references/template-authoring.md","sizeBytes":8172,"isText":true},{"path":"scripts/inspect-resolved.sh","sizeBytes":1386,"isText":true},{"path":"SKILL.md","sizeBytes":11206,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-10-16T16:32:56.835526Z","sha256":"D07A85E72DDDA9960C2D14BA12D9C08EC7784CC056E13A462CDF21864FA4847A","sizeBytes":16597},"review":null,"source":{"repositoryUrl":"https://github.com/ollygarden/opentelemetry-agent-skills","path":"skills/otel-weaver","license":"Apache-2.0","commit":"967179521de5e8dac365ae6fbc4fc64f427259f5","subtreeSha":"BD7C5A0A0DC6C106077BA9902A5C31C450EAA4A95734DA24A95C0AADD8DEB77F","lastSyncedAt":"2026-10-16T16:29:03.891055Z"},"reviewedAt":"2026-10-16T16:40:43.192147Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/ollygarden/opentelemetry-agent-skills/tree/main/skills/otel-weaver"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ollygarden-opentelemetry-agent-skills@llmmart"},{"target":"git","command":"git clone https://github.com/ollygarden/opentelemetry-agent-skills.git"}]}