Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions .agents/commands/evaluate-repository.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
description: Static, read-only quality & health review of this OpenTelemetry NuGet library
argument-hint: "[path or focus area, e.g. src/... or infrastructure/helm]"
---

# Repository Evaluation · OpenTelemetryExtension.Configuration

## Context

You are reviewing **this** repository: a NuGet package that wires up
OpenTelemetry (tracing, metrics, logging) for .NET apps via a single
`AddTelemetry()` call and `appsettings.json`. `AGENTS.md` is the canonical
source of truth for layout, conventions, build/test commands and the release
process — read it first and treat any deviation between it and the code as a
finding.

The shipped surface is small (the library targets `netstandard2.0`, `net8.0`,
`net10.0`); most risk is in **multi-targeting correctness, telemetry wiring,
test gating, and release/packaging hygiene** — not in third-party trust.

## Instructions

Perform a **static, read-only** review. Do not run code, install packages, or
execute scripts. Base every claim on repository contents; cite concrete files
and lines. Prefer explicit uncertainty over confident speculation, and separate
confirmed findings from speculation.

Scope: if `$ARGUMENTS` is non-empty, focus the review on that path or area;
otherwise evaluate the whole repository.

## Evaluation criteria

For each category: assign a score 1–10, justify concisely with file/line
evidence, and note uncertainty.

### 1. .NET code quality & conventions
- Adherence to `AGENTS.md` / `CLAUDE.md` conventions: file-scoped namespaces,
`_camelCase`/`s_camelCase` fields, `is null`/`is not null`,
`ArgumentNullException.ThrowIfNull`, expression-bodied members, no `#region`.
- `src/Directory.Build.props` invariants actually hold: nullable enabled,
`TreatWarningsAsErrors`, `EnforceCodeStyleInBuild`, implicit usings.
- Readability, correctness, internal consistency.

### 2. Multi-targeting correctness
- `netstandard2.0` does not use net5.0+ APIs without `#if NET5_0_OR_GREATER` /
`#if !NETSTANDARD2_0` guards.
- ASP.NET Core instrumentation is referenced only where valid (not on
`netstandard2.0`); any `!`-suppression carries the documented justification.

### 3. Telemetry wiring
- `TelemetryServiceCollectionExtensions` / `TelemetryOptions`: OTLP exporter
configured correctly per signal (gRPC posts to base endpoint; HttpProtobuf
appends `v1/traces|metrics|logs`), sampler, resource/service attributes,
validation of required options.
- Config binding (`Telemetry` section) matches the documented options and
defaults.

### 4. Tests
- Unit tests carry `[Trait("Category", "Unit")]` (untagged tests are silently
skipped by CI); integration tests carry `[Trait("Category", "Integration")]`.
- Unit tests avoid `Thread.Sleep`/network; integration tests (`OpenObserve`,
`SigNoz`, SQL Server) are isolated from CI and self-contained.
- Coverage of the public surface and meaningful assertions (not smoke-only).

### 5. Public API & packaging
- Public surface is minimal and intentional; XML `<summary>` docs present on
public members, absent on internal/private.
- NuGet metadata, SemVer discipline, and that `<Version>` is managed only via
the `prepare-release` skill (never bumped manually).

### 6. Build, CI & automation surface
- `ci.yml` builds + runs `Category=Unit`; `deploy-nuget.yml` is manual-only and
builds only library + unit-test projects.
- Local-execution surface under `infrastructure/helm/` (install `.cmd`/`.sh`
scripts, the `signoz.bootstrap-admin` Job) and `.agents/` (skills, commands,
`settings.local.json`): note anything that runs implicitly or with elevated
trust, and confirm it is documented.

## Checklist (answer each explicitly)

- Builds clean under `TreatWarningsAsErrors` (no evidence of suppressed/ignored
warnings)
- `netstandard2.0` API guards present where required
- Every unit-test class is `Category=Unit`
- OTLP per-signal endpoint logic is correct
- Public members documented; internals not over-documented
- `<Version>` not hand-edited outside the release skill
- Scripts / Jobs that execute locally are documented and scoped
- Secrets/credentials: none committed **except** clearly local-only dev
defaults (e.g. the SigNoz/OpenObserve dev login used by integration tests) —
flag any real secret

Briefly explain any item that fails.

## Findings format

### A. Confirmed issues
File · line · description · suggested minimal fix.

### B. Likely issues / needs manual check
Mark each as *likely* or *unclear*.

### C. Convention drift vs AGENTS.md
List mismatches between documented rules and the code.

## Overall assessment

- **Score:** X / 10
- **Recommendation:** one of — *Healthy* · *Healthy with caveats* ·
*Needs cleanup before release* · *Blocking issues*
- If *Blocking*, name the blocker(s).

## Suggested improvements

Specific, minimal changes that would raise quality or unblock a release
(convention fixes, missing guards, test gaps, doc/packaging clarifications).

---

FOCUS: <FOCUS>$ARGUMENTS</FOCUS>
(empty = evaluate the whole repository)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This skill must only be run by the admin (auto-opening PRs is admin-only).
## Workflow

1. **Check whether there is anything to release**
- Run the helper: `bash .claude/skills/prepare-release/scripts/check-otel-updates.sh`
- Run the helper: `bash .agents/skills/prepare-release/scripts/check-otel-updates.sh`
- The helper only inspects the **shipped library project** (`src/OpenTelemetryExtension.Configuration/...csproj`). Dependency updates in the Sample or Tests projects are ignored — they are never published and must not trigger a new version.
- Exit code **3** = nothing to release (no library dependency updates *and* no new commits since the last tag) → **stop**.
- Exit code **0** = library dependency updates and/or new commits exist → continue.
Expand Down Expand Up @@ -49,15 +49,15 @@ This skill must only be run by the admin (auto-opening PRs is admin-only).
OpenObserve is used because it has a real query API, so the test can
positively confirm ingested data. The helper starts OpenObserve via its Helm
chart, runs the sample, generates traffic and queries the API for records:
- `bash .claude/skills/prepare-release/scripts/smoke-test.sh`
- `bash .agents/skills/prepare-release/scripts/smoke-test.sh`
- Exit 0 = telemetry confirmed → continue. Non-zero = stop and report; do not
release if telemetry does not arrive.

9. **Bump `<Version>`** in the csproj.

10. **Extend docs** — update `README.md` etc. for the changes/new dep versions.

11. **Release notes** — copy `.claude/skills/prepare-release/assets/release-notes.md` to
11. **Release notes** — copy `.agents/skills/prepare-release/assets/release-notes.md` to
`release-notes/v<version>.md`, fill in the `{{VERSION}}`/`{{DATE}}` placeholders
and the **Added / Changed / Fixed / Removed** sections (omit empty ones).
Add the new file to `OpenTelemetryExtension.slnx` (it tracks loose files
Expand Down
29 changes: 23 additions & 6 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@

root = true

# Generated EF Core migrations — skip style rules
# MSBuild project files
[*.{csproj,props,targets}]
indent_style = space
indent_size = 2
tab_width = 2
charset = utf-8
insert_final_newline = true

# YAML
[*.{yaml,yml}]
indent_style = space
indent_size = 2
tab_width = 2
insert_final_newline = true

# Windows batch scripts
[*.{bat,cmd}]
indent_style = space
indent_size = 2
tab_width = 2
end_of_line = crlf
insert_final_newline = true

[src/**/Migrations/*.cs]
generated_code = true
dotnet_analyzer_diagnostic.severity = none

# [*.{xml,yaml,yml,json}]
# indent_style = space
# indent_size = 2
# tab_width = 2
[*.{cs,vb}]

indent_size = 4
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

- name: Install .NET Tools (local)
run: |
dotnet new tool-manifest
dotnet new tool-manifest --force
dotnet tool install dotnet-reportgenerator-globaltool

- name: Restore
Expand All @@ -58,8 +58,8 @@ jobs:
dotnet tool run reportgenerator `
-reports:TestResults/**/coverage.cobertura.xml `
-targetdir:TestResults/Reports `
-reporttypes:"Html;lcov;Cobertura" `
-reporttypes:"Html;lcov;Cobertura"

- name: Upload Coverage to Coveralls
uses: coverallsapp/github-action@v2
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ yarn-error.log*
/logs
/archiv
/_archiv
/.agents/settings.local.json

**/TestResult/
/test.html.lnk
Expand Down
36 changes: 22 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,24 @@ API to confirm the data was ingested.

- Needs the OpenObserve Helm chart (`infrastructure/helm/helm-install-openobserve.cmd`);
the SQL Server chart (`helm-install-sqlserver.cmd`) is required only for the SQL test.
- Tests use `[IntegrationFact]` / `[SqlIntegrationFact]` (in `Utils/`) instead
of `[Fact]` — they **auto-skip** when OpenObserve (`localhost:30117`) or SQL
Server (`localhost:31433`) is unreachable, so the suite stays green without
the stack.
- Tests use plain `[Fact]` with `[Trait("Category", "Integration")]` at the
class level. They do **not** auto-skip — they fail if the backend
(OpenObserve `localhost:30117`, SQL Server `localhost:31433`, SigNoz
`localhost:30318`/`30111`) is unreachable — and are excluded from CI by the
`Category=Unit` filter, so the suite only runs with the stack up.
- `SigNozIntegrationTests` exercises the same export path against a running
**SigNoz** stack (`infrastructure/helm/helm-install-signoz.cmd`): it exports
via OTLP HTTP to `localhost:30318` and queries SigNoz's `query_range` API
(`localhost:30111`) to confirm ingestion. The dev admin login
(`admin@web.de`) is created automatically on first boot by the
`signoz.bootstrap-admin.yaml` Job that the install script applies; the org id
is resolved at runtime. Credentials are the local dev defaults in
`IntegrationConfig`.
- Shared helpers live in `Utils/`: `IntegrationConfig` (endpoints/credentials),
`OpenObserveClient` (`_search` queries), `OtelTestHost`, `Reachability`.
- Endpoints/credentials default to the Helm chart values; override via env vars:
`OTEL_IT_OPENOBSERVE_URL`, `OTEL_IT_OPENOBSERVE_USER`,
`OTEL_IT_OPENOBSERVE_PASSWORD`, `OTEL_IT_OTLP_HEADERS`, `OTEL_IT_SQL_CONNECTION`.
`OpenObserveClient` (`_search` queries), `SigNozClient` (`query_range`),
`OtelTestHost`.
- Endpoints/credentials are hardcoded local-dev defaults in `IntegrationConfig`
(matching the Helm chart values); they are dev-only and not real secrets.
- Run: `dotnet test src/OpenTelemetryExtension.Configuration.IntegrationTests -c Release`.

## Language & framework
Expand Down Expand Up @@ -176,8 +185,8 @@ API to confirm the data was ingested.
- **Every unit test class must carry `[Trait("Category", "Unit")]`** (class
level). CI and the deploy workflow filter on `Category=Unit` — an untagged
test is silently never run in CI.
- Integration test classes carry `[Trait("Category", "Integration")]` and use
`[IntegrationFact]` / `[SqlIntegrationFact]` instead of `[Fact]`
- Integration test classes carry `[Trait("Category", "Integration")]` at the
class level and use plain `[Fact]` / `[Theory]`
- xUnit `[Fact]` for single cases, `[Theory]` + `[InlineData]` for parameterised
- Method name pattern: `MethodOrProperty_Condition_ExpectedResult`
- Arrange / Act / Assert with a blank line between each section; trivial
Expand All @@ -203,10 +212,9 @@ API to confirm the data was ingested.
[Roles & permissions](#roles--permissions-admin-only-actions))
- The full release-prep workflow (decide SemVer, bump, update deps, build/test,
end-to-end smoke test, release notes, PR to `main`) is encoded in the
**`prepare-release`** skill at `.claude/skills/prepare-release/`. Run it via
Claude Code (`/prepare-release`) when cutting a release; it only prepares and
**opens** the PR — the admin reviews and merges it, then the admin triggers
`deploy-nuget.yml`. The skill never merges or publishes.
**`prepare-release`** skill at `.agents/skills/prepare-release/`. Run it via
Claude Code (`/prepare-release`) when cutting a release; it only prepares the
PR — publishing stays the manual `deploy-nuget.yml` trigger.

## What NOT to do

Expand Down
9 changes: 0 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,3 @@
project layout, build & test commands, code conventions, test rules, and the
release process all live there. Read it before making changes — do not
duplicate its content here.

## Claude-specific notes

- Quick start: `dotnet build OpenTelemetryExtension.slnx -c Release`, then
`dotnet test src/OpenTelemetryExtension.Configuration.Tests -c Release --filter "Category=Unit"`.
- GitHub Flow: branch off `main` (`feature/*` or `fix/*`) → PR → `main`; never
commit straight to `main`. Release branches (`release/*`) are skill-managed.
- Use the `/prepare-release` skill (`.claude/skills/prepare-release/`) for the
entire release workflow — never bump `<Version>` or publish manually.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ change. At release time the maintainer cuts the version and writes the notes;
the `prepare-release` skill decides the SemVer bump (PATCH / MINOR / MAJOR) from
the commits merged since the last release.

> **Maintainers:** the release-prep steps (version decision, dependency updates, build/test, smoke test, release notes, release PR) are automated by the `prepare-release` Claude Code skill in [`.claude/skills/prepare-release/`](./.claude/skills/prepare-release/). It prepares the PR only — the actual NuGet publish remains the manual **Deploy Nuget** workflow.
> **Maintainers:** the release-prep steps (version decision, dependency updates, build/test, smoke test, release notes, release PR) are automated by the `prepare-release` Claude Code skill in [`.agents/skills/prepare-release/`](./.agents/skills/prepare-release/). It prepares the PR only — the actual NuGet publish remains the manual **Deploy Nuget** workflow.

## Adding a New Instrumentation Option

Expand Down
38 changes: 22 additions & 16 deletions OpenTelemetryExtension.slnx
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
<Solution>
<Folder Name="/Docs/">
<File Path="AGENTS.md" />
<File Path="CLAUDE.md" />
<File Path="CODE_OF_CONDUCT.md" />
<File Path="CONTRIBUTING.md" />
<File Path="LICENSE" />
<File Path="README.md" />
</Folder>
<Folder Name="/.claude/" />
<Folder Name="/.claude/skills/" />
<Folder Name="/.claude/skills/prepare-release/">
<File Path=".claude/skills/prepare-release/SKILL.md" />
<Folder Name="/.agents/" />
<Folder Name="/.agents/skills/" />
<Folder Name="/.agents/skills/prepare-release/">
<File Path=".agents/skills/prepare-release/SKILL.md" />
</Folder>
<Folder Name="/.claude/skills/prepare-release/scripts/">
<File Path=".claude/skills/prepare-release/scripts/check-otel-updates.sh" />
<Folder Name="/.agents/skills/prepare-release/scripts/">
<File Path=".agents/skills/prepare-release/scripts/check-otel-updates.sh" />
</Folder>
<Folder Name="/.claude/skills/prepare-release/assets/">
<File Path=".claude/skills/prepare-release/assets/release-notes.md" />
<Folder Name="/.agents/skills/prepare-release/assets/">
<File Path=".agents/skills/prepare-release/assets/release-notes.md" />
</Folder>
<Folder Name="/.github/">
<File Path=".github/copilot-instructions.md" />
Expand Down Expand Up @@ -55,6 +47,8 @@
<File Path="infrastructure/helm/helm-install-sqlserver.cmd" />
<File Path="infrastructure/helm/aspire-dashboard.nodeports.yaml" />
<File Path="infrastructure/helm/aspire-dashboard.values.yaml" />
<File Path="infrastructure/helm/signoz.nodeports.yaml" />
<File Path="infrastructure/helm/signoz.values.yaml" />
</Folder>
<Folder Name="/Infrastructure/Helm/chart-openobserve/">
<File Path="infrastructure/helm/chart-openobserve/.helmignore" />
Expand Down Expand Up @@ -86,5 +80,17 @@
<Project Path="src/OpenTelemetryExtension.Configuration.Sample.Wpf/OpenTelemetryExtension.Configuration.Sample.Wpf.csproj" />
<Project Path="src/OpenTelemetryExtension.Configuration/OpenTelemetryExtension.Configuration.csproj" />
<Project Path="src/OpenTelemetryExtension.Configuration.Tests/OpenTelemetryExtension.Configuration.Tests.csproj" />
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path=".gitattributes" />
<File Path=".gitignore" />
<File Path="AGENTS.md" />
<File Path="CLAUDE.md" />
<File Path="CODE_OF_CONDUCT.md" />
<File Path="CONTRIBUTING.md" />
<File Path="LICENSE" />
<File Path="README.md" />
<File Path="SECURITY.md" />
</Folder>
<Project Path="src/OpenTelemetryExtension.Configuration.IntegrationTests/OpenTelemetryExtension.Configuration.IntegrationTests.csproj" />
</Solution>
23 changes: 23 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Security Policy

## Reporting a vulnerability

Please report security vulnerabilities **privately** — do not open a public
issue or pull request for them.

Use GitHub's private reporting flow:
[**Report a vulnerability**](https://github.com/thorstenalpers/OpenTelemetryExtension.Configuration/security/advisories/new).

Please include enough detail to reproduce the issue (affected version, a minimal
repro or proof of concept, and the impact). You can expect an initial response
within a few days. Once a fix is available it will be released to NuGet and the
advisory published.

## Supported versions

Only the latest `2.x` release receives security fixes.

| Version | Supported |
| ------- | --------- |
| 2.x | ✅ |
| < 2.0 | ❌ |
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ spec:
{{- if .Values.persistence.enabled }}
- name: data
persistentVolumeClaim:
claimName: openobserve-data
claimName: {{ include "openobserve.fullname" . }}-data
{{- end }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
Expand Down
5 changes: 4 additions & 1 deletion infrastructure/helm/chart-openobserve/templates/pvc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: openobserve-data
name: {{ include "openobserve.fullname" . }}-data
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-5"
spec:
accessModes:
- ReadWriteOnce
Expand Down
Loading
Loading