The `Metrics` interface in the `metrics` package has no way to reset accumulated timer data. Add an operation that clears all existing metrics, so that a caller can reuse the same `Metrics` instance for fresh measurements. After clearing, a call to `All()` must return an empty map, and any new timers obtained afterwards must start from zero.

Augment the metrics interface to support clearing


When OPA's parser is configured with `RegoVersion: RegoV1`, the validation of `Capabilities.FutureKeywords` and `ParserOptions.FutureKeywords` is missing—illegal future keywords are not rejected.

The parser must reject unknown keywords in capabilities and in explicitly requested future keywords the same way it already does for `RegoV0`:

- If `Capabilities.FutureKeywords` contains a keyword that is not a known future keyword, the parser must return an error with the message `"illegal capabilities: unknown keyword: <keyword>"`.
- If `ParserOptions.FutureKeywords` explicitly requests a keyword that is not known (or not allowed by capabilities), the parser must return an error with the message `"unknown future keyword: <keyword>"`.

This validation should happen regardless of the Rego version; apply the same checks that exist for `RegoV0` to the `RegoV1` path.

ast: Asserting future-keywords capabilities are valid also for Rego v1 (#7003)


The discovery plugin currently does not expose its health through the plugin manager's status API. This makes it impossible to monitor whether configuration discovery is working correctly, unlike other plugins such as the bundle plugin that already report `NOT_READY`, `OK`, or `ERROR` states.

Expected behavior:
- When the discovery plugin is created, it should report its status as `NOT_READY`.
- When the plugin is started *and* no dynamic discovery (no downloader) is configured, it should immediately report `OK`.
- When dynamic discovery is configured, the plugin should remain `NOT_READY` until the very first successful configuration activation, then switch to `OK`. Subsequent successful or failed updates should not change this `OK` status.
- When the plugin is stopped, it should revert to `NOT_READY`.

The plugin should report its status under a well-known name (e.g., `"discovery"`) so that consumers of the status API can distinguish it from other plugins. The manager's existing `UpdatePluginStatus` method should be used for all transitions.

plugins/discovery: Add plugin status updates


**Title:** Add transaction safety checks to the in-memory store

**Description:**

The in-memory storage backend (`storage/inmem`) currently places almost no guardrails on the transaction objects passed to its methods. This allows misuse that can lead to data races, silent corruption, or confusing panics:

* using a transaction after it has been committed or aborted ("stale" transaction)
* passing a transaction that was created by a different `store` instance
* unregistering a trigger using an invalid or wrong-type transaction (the old code silently returned)

We need the in-memory store to enforce transaction lifecycle and ownership invariants, so that misuse is caught early and reported clearly, either through structured errors or, for the already-unrecoverable `Abort` and `Unregister` paths, through deliberate panics.

**Acceptance Criteria:**

1. **Stale transaction detection**
   Once a transaction has been committed or aborted, any subsequent call to a store method (such as `Read`, `Write`, `ListPolicies`, `GetPolicy`, `UpsertPolicy`, `DeletePolicy`, `Register`, `Build`) with that transaction must return a `*storage.Error` with code `storage.InvalidTransactionErr` and a message that makes it clear the transaction is stale (e.g., “stale transaction”).

2. **Cross-store transaction detection**
   If a transaction created by one in-memory store instance is passed to a different store instance, the store must return an `*storage.Error` with code `storage.InvalidTransactionErr` and a message indicating the transaction is not recognised (e.g., “unknown transaction”). A type assertion alone is not sufficient; the store must verify the transaction belongs to it.

3. **Abort must panic on invalid transactions**
   `Abort` should still panic when called with an already-finalised or foreign transaction, because callers are expected to never hit this case. The panic must contain a meaningful error value (a `*storage.Error`), not a raw type-assertion panic.

4. **Unregister must panic when invariants are broken**
   Calling `Unregister` with a transaction that is not a write transaction, is stale, or belongs to a different store must panic with a `*storage.Error`. The previous behaviour, which silently returned, masked bugs.

5. **On-commit triggers must see a live transaction**
   When `Commit` runs, any registered on-commit triggers must still be able to use the transaction during their callback. Only after all triggers have executed should the transaction be marked as stale. This ensures trigger functions can perform additional store operations if needed.

6. **No regressions for the public API**
   The `storage.Store` and related interfaces must remain unchanged. The additional checks are purely internal safety measures. All existing error codes (`InvalidTransactionErr`, `IndexingNotSupportedErr`, etc.) and their helpers (`storage.IsInvalidTransaction`, etc.) must continue to work as before.

**Motivation / Context:**

This request arose from the discovery that callers could accidentally reuse a committed transaction and get undefined behaviour. The in-memory store is often used in tests and embedded scenarios where such mistakes are easy to make. Systematic checks will prevent subtle bugs and make violations immediately visible.

storage: Add safety checks to in-memory store


As a user of `opa test`, I want the pretty reporter to show which file each failing test belongs to, so I can quickly locate the source of a failure when multiple policy files are involved.

### Problem
When I run `opa test` (or `opa test -v`) and tests in several `.rego` files fail, the output lists the test names without any file information. This makes it hard to match failures back to files, especially when test names are reused or there are many test files. Currently the output is just a flat sequence of test results.

### Desired behavior
In the pretty reporter output (both regular and verbose mode), test results should be grouped by the file they originate from. Before printing the results for a given file, a header line with the file path (e.g., `policy.rego:`) should be printed. For each file, all its test results should appear under that header. A blank line should separate groups of different files for readability.

#### Example
Given two failing files `auth.rego` and `logging.rego`, the output would look like:
```
auth.rego:
data.http.authz.test_allow_admin: FAIL (0s)
data.http.authz.test_deny_guest: FAIL (0s)

logging.rego:
data.logging.test_masking: ERROR (0s)
  some error message
```

This grouping should apply to **all** test results that are printed: failed, errored, skipped, or passed (in verbose mode). Benchmarks printed via `--bench` should not be affected by this grouping.

### Edge cases to consider
- Tests that do not carry file location information (e.g., `Location` is nil) should still be printed as before, without a file header, and should not interfere with the grouping.
- If a single file has both passing and failing tests in verbose mode, all of its results should appear under the same file header.
- The blank separation between file groups should be added only when transitioning to a new file, not at the very beginning or after the last result.
- The change must not alter the existing format of individual result lines (PASS/FAIL/ERROR/SKIPPED and their optional output). The summary section at the end should remain unchanged.

### Impact
This makes test failure investigation significantly faster, especially in CI logs where you cannot easily correlate test names to files manually.

feat: Add file path to failing tests to make debugging failing tests easier (#4461)


Type checker: suppress expression match error when closures have errors

When the type checker encounters an expression containing a closure (array, set, or object comprehension) that has a type error, it currently emits both the actionable closure error and a less-specific "match error" from the enclosing expression. The less-specific match error should be suppressed, following the same logic already used when reference errors are present: if the expression error is caused by a nil type, and a more actionable error occurred in a contained closure, report only the closure error.

Also, the type checker currently stops after checking the first expression in a body. It should continue checking all expressions.

Acceptance criteria:
- For a body like `_ = [true | count(1)]`, only the argument-type error inside the closure is reported (no extra match error).
- Expression-level nil-type errors are suppressed when any contained closure produces an error (consistent with existing reference error suppression).
- All expressions in a body are type-checked.

Suppress match errors if closures contained errors


**Title:** Add AWS Web Identity (IRSA) credential provider for S3 signing

**Background**
OPA’s REST plugin supports AWS4 signing for S3-backed bundles/status using two credential sources: `environment_credentials` (static keys) and `metadata_credentials` (EC2/ECS metadata). Both implement the `awsCredentialService` interface and are wired into the `awsSigningAuthPlugin`.

**Request**
Add a third credential provider, `web_identity_credentials`, that supports EKS IAM Roles for Service Accounts (IRSA). This provider should use OIDC web identity tokens to call STS `AssumeRoleWithWebIdentity` and obtain temporary credentials.

**External contract**
Under `services[_].credentials.s3_signing`, users should be able to specify `web_identity_credentials` with these optional fields:
- `aws_region` (string, optional) – if omitted, falls back to the `AWS_REGION` environment variable.
- `session_name` (string, optional) – role session name; defaults to `"open-policy-agent"`.

The provider must read the required values `AWS_ROLE_ARN` and `AWS_WEB_IDENTITY_TOKEN_FILE` from the environment (standard IRSA injection).

**Integration rules**
- The existing “exactly one credential method” validation must be extended to include the new provider. All three methods are mutually exclusive.
- The selection precedence in `awsCredentialService()` should be: `environment_credentials` → `web_identity_credentials` → `metadata_credentials`.
- When `web_identity_credentials` is configured, the plugin must call `populateFromEnv()` during client creation and return an error if the required environment variables are missing.

**Credential lifecycle (must match the existing refresh pattern)**
- On each `credentials()` call, check expiration. If the credentials expire in less than 5 minutes, fetch new ones; otherwise return the cached set.
- Build the STS request: a GET to the STS endpoint with query parameters `Action=AssumeRoleWithWebIdentity`, `RoleArn`, `RoleSessionName`, `WebIdentityToken`, `Version=2011-06-15`.
- STS endpoint selection: if `stsURL` is set (for testing), use it; else if region is set, use the regional endpoint `https://sts.<region>.amazonaws.com`; else use the global `https://sts.amazonaws.com`.
- Parse the XML response and extract `AccessKeyId`, `SecretAccessKey`, `SessionToken`, and `Expiration`.
- If a refresh fails (HTTP/parse error), **return the previously cached credentials along with the error** so that callers can continue using still-valid credentials. This is a slight but important robustness improvement over the metadata provider, which returns zero-value creds on failure.

**Documentation**
Add a section under the S3 signing docs describing `web_identity_credentials`, its fields, and that it expects `AWS_ROLE_ARN` and `AWS_WEB_IDENTITY_TOKEN_FILE` to be set. The existing `metadata_credentials` region description should be corrected to indicate that `aws_region` is optional and falls back to `AWS_REGION`.

**References**
- STS AssumeRoleWithWebIdentity: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html
- EKS IRSA env vars: https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html#pod-configuration

plugin/rest: Adds AWS Web Identity support


**Title:** Dynamic rewriting drops `with` modifiers on generated equality expressions

**Description:**
When a rule body contains a dynamic reference (e.g., `data.test.str`) and the enclosing expression carries a `with` modifier (e.g., `with input as 1`), the compiler’s dynamic rewriting step generates an internal assignment expression (using the equality factory) that is created *without* copying the `with` modifier from the original expression. Consequently the generated local equalities are evaluated with the default input rather than the overridden input, leading to incorrect results for any rule that combines dynamic terms and `with` modifiers.

The issue manifests for equality expressions, call expressions, term expressions, and comprehensions that contain dynamic terms. The fix should ensure that every internally generated equality expression inherits the `with` modifiers of the expression whose dynamic term triggered its generation, so that the modifier is applied consistently across the rewritten body.

**Expected behavior:**
For a rule like:
```
p { count(data.test.str) <http://data.test.str)> with input as 1 }
```
the local-variable assignment that replaces `data.test.str` must also carry `with input as 1`, not just the original call expression.

Fix dynamic rewriting to copy with modifiers


**Title:** Expose decision log drop count in status metrics

**Request:**
When the decision logs plugin rate-limits log events (per `max_decisions_per_second`), it currently discards events silently. We need visibility into how many events are being dropped. Add a new counter metric, `decision_logs_dropped`, that increments every time an event is dropped due to rate limiting. This counter must appear in the status plugin’s periodic metrics payload (i.e., in the `metrics` field of status updates) so that control-plane operators can monitor drop rates.

**Requirements:**
- Increment the counter only when the rate limiter rejects an event.
- Use the same global `metrics.Metrics` provider that the status plugin already uses, so the counter is automatically included in status reports without additional wiring. The decision logs plugin should accept a metrics provider (if none is set, dropping should still work but without incrementing).
- The discovery subsystem already passes a metrics provider to the status plugin; ensure it also provides that same provider to the decision logs plugin so the counter works end-to-end when plugins are managed through discovery.
- The counter must be thread-safe (consistent with other metrics already reported by the status plugin).

plugins: Include log drop count in the status plugin's metrics


```
Refactor runtime to separate initialization from start

Currently, Runtime.Start performs both initialization (loading policies,
setting up the store) and begins a blocking loop (server or REPL). Callers
have no way to initialize the runtime without also blocking. We need to
separate these steps so that callers can set up a Runtime instance and
then decide when to start its blocking behavior.

Specifically:
- Provide a way to construct an initialized Runtime that does not block.
- Expose separate, public methods to start server and REPL modes that do
  block the calling goroutine.
- The `Server` boolean currently in `Params` is a startup-mode switch,
  not a configuration parameter. Remove it; callers should choose the
  start method directly.
- Ensure that existing behavior is preserved: logging setup, watcher
  activation, error limit handling, server configuration, REPL banner
  and output, etc.
- Update existing tests (TestEval, TestInit, TestRuntimeProcessWatchEvents)
  to use the new initialization and start API so correctness is validated.
```

Refactor runtime to separate init and start


**Title:** AWS ECR Authorization Header Leaked on Redirects to S3 Pre-signed URLs

**Description:**

When OPA is configured to pull OCI bundles from Amazon ECR using the AWS signing authentication plugin with `service: "ecr"`, the plugin correctly adds an ECR authorization header to the initial request. However, ECR responds with redirects to S3 pre-signed URLs for blob downloads. The current behavior adds the ECR authorization header to those redirected requests as well. S3 rejects these requests with a 400 error because the pre-signed URL already encodes the necessary authentication, and the additional header conflicts.

Expected behavior: The ECR authorization header should only be included for requests whose target host matches the host from the configured registry URL. When a request has been redirected to a different host (e.g., an S3 bucket), the header must not be added.

This issue prevents OPA from successfully downloading OCI bundles from ECR when using the AWS signing auth plugin with service `ecr`. The fix should ensure that the request preparation step for this plugin compares the request’s host against the original configured host and skips the ECR-specific authorization if the hosts do not match.

Disable the Authorization header for ECR redirects.


The metrics marshaling path does unnecessary map-growth allocations that add measurable overhead for workloads with many counters, timers, and histograms.

When `metrics.All()` and `metrics.Timers()` build their result maps, they start at zero capacity even though the exact number of entries is known up-front (the sizes of the underlying timer, histogram, and counter maps). Similarly, each histogram’s `Value()` method constructs a fixed-size map with the same set of percentile/min/max keys every time, but allocates without a capacity hint. These allocations and re-hashings directly affect every server endpoint that marshals metrics (e.g., the OPA server metrics API).

Please preallocate the result maps in `All()`, `Timers()`, and `histogram.Value()` using the appropriate capacities so that a single allocation suffices. Additionally, a benchmark that exercises the full JSON-marshaling path for a typical set of metrics would be valuable to validate the improvement and guard against regressions.

v1/metrics: Prealloc maps + add benchmark (#7664)


The planner must be extended to support compiling complete rules from modules into callable IR functions, so that queries referencing `data.<pkg>.<rule>` can be evaluated without relying on partial evaluation to inline all rule bodies.

**Behavior required**

- When modules are provided, the planner should group their rules by path (package + rule name). For each group, emit a single IR function whose name is the string form of the rule’s ref (e.g., `"data.example.p"`).
- Multiple rule bodies for the same path must be represented as separate blocks inside the same function, with a final return block appended after all body blocks.
- Inside a rule body, the head value should be assigned to the function’s return local using a one-shot assignment that aborts with a conflict error if already defined (to detect unintentional multiple definitions that succeed for the same input).
- References in a query whose head is `data` must, instead of the current `planScan` data traversal, emit a `CallStmt` that invokes the planned function for the referenced ref. The input document should be passed as the first argument, and the result local of the call should become the target for any further traversal on the ref.
- Rule compilation must save and restore the planner’s current variable context and block pointer so that rule bodies are planned independently of the outer query.
- For now, only complete rules (no `else`, no head key, no default, no head args) must be supported; other rule forms should return `"not implemented"` errors.
- Calling a function whose result is a partial object or set, or referencing nested refs like `data.foo.p[x]` where `p` is an object, may not work yet and is acceptable to handle later, but simple equality against a complete rule value must succeed.

**IR additions needed**

- `Funcs` container on `Policy` (map of name → `Func`), and a `Func` node holding a name, parameter locals, a return local, and a list of blocks.
- `CallStmt` with fields: `Func` (string name), `Args` (list of locals), `Result` (local to store the return value).
- `ReturnLocalStmt` with a `Source` local that yields the value of that local as the function’s result.
- `AssignVarOnceStmt` with `Target` and `Source` locals, whose runtime semantics must abort with conflict if the target is already defined.

**Planner organization**

- Planned functions should be stored in a structure that organizes them by their path so they can be looked up efficiently when planning `data.*` references; a trie keyed by the constant prefix of the ref is natural.
- The walker must traverse the new `Funcs` container in a deterministic order (sort by function name), visiting each `Func` and its blocks.
- The existing `planScan` method should be renamed to `planRefScan` (keeping its current behavior intact) to make room for the new `planRefData` method that intercepts `data` refs.

wasm: Add support for functions in planner


We have observed that when OPA is running with the inter-query built-in cache enabled (even with a conservative `max_size_bytes` limit), total process memory grows steadily over time and does not level off. The cache is supposed to hold at most `max_size_bytes` worth of entries, evicting older entries as needed, but repeated inserts and evictions cause the cache's internal footprint to increase without bound—this looks like a leak in the eviction/linked-list bookkeeping.

The expected behaviour:
- After the cache is warmed and evictions begin, the overall memory held by the cache should remain roughly proportional to the configured
  `max_size_bytes`.  Continually inserting and deleting (or having items evicted) must **not** cause additional data to accumulate.
- The eviction order that the cache uses (currently the order items were inserted) should stay consistent, and no orphaned entries should remain in the underlying eviction list after the corresponding key is removed from the cache map.
- The fix must be safe under the existing mutex protection; do **not** introduce data races.

Acceptance criteria:
1. Configure OPA with a small `inter_query_builtin_cache.max_size_bytes`, cause many distinct cache keys to be inserted (so that eviction happens frequently), and observe that resident memory stops growing once the cache reaches its limit.
2. Explicit deletes (via the `InterQueryCache.Delete` method) must also clean up all internal state associated with that key, so that deleted keys do not contribute to memory usage.
3. The invariant that the number of items in the cache’s internal map equals the length of the eviction list must hold after every insert, delete, and eviction.


```
Fix deadlock when stopping the bundle plugin

When OPA shuts down or the bundle plugin is explicitly stopped, the process
can deadlock. The plugin’s Stop method acquires its mutex and then calls
Stop on each downloader. The downloader’s Stop triggers the registered
download callback (oneShot/process), which attempts to acquire the same
plugin mutex. This leads to a deadlock.

Additionally, the downloader’s Stop is not safe for multiple calls:
invoking Stop more than once (e.g. from separate callers) can block
indefinitely.

The fix must:

1) Release the plugin mutex before stopping the downloaders, so that
   callbacks triggered during shutdown can complete without re-acquiring
   the held lock.

2) Make the downloader’s Stop idempotent and safe for concurrent use. A
   second call to Stop on an already-stopped downloader must return
   immediately without blocking.

3) After the plugin has been stopped, any in-flight download callbacks
   must not attempt to access or clear the downloader map, since it may
   no longer be valid.
```

Fix OPA deadlock while stopping bundle plugin


```
Issue: Inline rule heads incorrectly marked as covered in test coverage reports.

Steps to reproduce: given a policy containing an inline rule whose body never succeeds (e.g. `foo if false`), running tests with coverage incorrectly shows the rule head line as covered. The same rule expressed as a multi-line body (`foo if { false }`) correctly shows the head as not covered.

Expected behavior: coverage should treat both forms identically. A rule head should be marked as not covered when its body never produces a successful evaluation, regardless of whether the head and body appear on the same line.

Likely cause: the coverage report currently decides whether a rule head is covered by checking whether the rule’s _body row_ is covered. When head and body share a line this yields a false positive.

Fix: when walking rules after the coverage trace to determine which heads are not covered, check whether the head’s actual source range (start/end position) is contained in any of the covered ranges recorded for that file, instead of performing a row-only check. Ensure that any range-containment helpers correctly handle multi-character ranges (same-line and multi-line) so that a head range not fully inside a covered range is correctly treated as not covered.
```

cover: Track inline rule head in post trace walk (#8767)


```
Title: OPA does not accept PKCS#8 encoded RSA private keys for signing

OPA currently supports signing bundles and using private keys for JWT-based
authentication (OAuth2 JWT bearer grant type). However, the implementation
rejects RSA private keys that are supplied in the widely used PKCS#8 format
(`BEGIN PRIVATE KEY`). It accepts only traditional PKCS#1 RSA private keys
(`BEGIN RSA PRIVATE KEY`). This forces users to convert keys and causes
confusing failures.

Acceptance criteria / expected behaviour:

1) When a user provides an RSA private key in PKCS#8 format (PEM block with
   `BEGIN PRIVATE KEY`) as a bundle signing key, OPA must successfully load
   and use the key to sign bundles. The same applies to the OAuth2 JWT bearer
   grant type configuration for the REST client: a PKCS#8 RSA private key
   must be accepted and used to sign JWT assertions.

2) All existing PKCS#1 RSA private key formats must continue to work
   unchanged. No regression in key loading for ECDSA or other algorithms
   is acceptable.

3) If a key is not a valid PKCS#1 RSA private key and is also not a valid
   PKCS#8 private key, OPA must return a clear error that helps the
   operator understand why the key could not be loaded. The error message
   should include details about both attempted parse operations (PKCS#1
   and PKCS#8) so that the user can diagnose format problems.

Security / correctness:

- The implementation must not weaken key parsing: it must continue to
  validate the cryptographic parameters of the supplied key. PKCS#8
  keys should be parsed with the same strictness as PKCS#1 keys.

- The fix is only about RSA private keys used in signing contexts
  (bundle signing, JWT signing for OAuth2). It is not about public keys
  or about any other key usage.

Non-goal (for clarity):

- This does not require support for encrypted PKCS#8 or password-
  protected keys. Those remain unsupported unless the existing code
  already handles them for PKCS#1 (the existing behaviour should be
  preserved).

Relevant user-facing workflows:

- `opa build --signing-key <path>` when <path> contains a PKCS#8
  RSA private key.

- OPA configuration for the REST plugin with
  `credentials.oauth2.grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer"`
  and a key supplied via `keys` that is a PKCS#8 RSA private key.
```

Allow PKCS8 encoded private keys (#3117)


**Title:** `http.send` caching not applied for `system.authz` authorization policies

**Description:**

When using `http.send` with `force_cache` (and `force_cache_duration_seconds`) inside `system.authz` policies, the inter-query cache is never consulted or populated. The same policy with identical `http.send` parameters will re-fetch the remote resource on every authorization decision.

This is inconsistent with the main evaluation path (e.g., `v1/data` queries), where the inter-query cache is already wired in and `http.send` caching works as documented.

We need to ensure that authorization evaluations performed by the built-in `system.authz` handler also use the server’s inter-query cache, so that `force_cache`/`force_cache_duration_seconds` behave correctly in this context as well.

Ensure http.send caching works in system.authz (#4195)


```
Title: Partial evaluation mishandles variable scoping when rule head is a reference

### Description
When using partial evaluation (e.g., `opa eval --partial`) on rules whose head is a reference (like `p[x]` or `p[x = input]`), the generated partial queries sometimes contain incorrect variable namespacing. The resulting partial query may fail to preserve the binding of the head variable when that variable appears inside the body as the root of another reference (e.g., `x.bar`) or may not correctly apply the caller’s binding when the head itself is constructed from an input reference.

This causes partial results that cannot be evaluated to the same answers as the original policy, breaking downstream consumers that rely on partial evaluation for incremental evaluation, query explanation, or pre‑processing pipelines.

### Steps to reproduce
Create a policy with a reference head:

```rego
package test

p[x] = 1 {
    input.foo[x] = z
    x.bar = 1
}
```

Then run:

```
opa eval --partial 'data.test.p[y] = 1'
```

Alternatively, using a rule head built from an input reference:

```rego
package test

p[x = input] = 1 {
    x[0] = 1
}
```

and the query:

```
opa eval --partial 'data.test.p[x] = 1'
```

### Observed behavior
For the first policy the partial query may be something like:

```
z1 = input.foo[y]
```

but the constraint `y.bar = 1` is missing or contains an incorrectly namespaced variable, so `y` is not properly linked to the original head variable.

For the second policy, the partial query may not include the binding `x = input` or may rename `x` in a way that breaks the relationship with the caller.

### Expected behavior
The partial query should accurately reflect the full semantics of the rule without altering the scoping. For the first policy the partial result should enforce `y.bar = 1; z1 = input.foo[y]` (modulo naming of generated variables). For the second policy it should produce `x = input; x[0] = 1`, preserving the caller’s variable name and the binding to `input`.

### Impact
Normal (non‑partial) evaluation works correctly; only partial evaluation is affected. The bug yields incomplete or incorrect partial queries that can silently corrupt the results of systems depending on partial evaluation. This is especially severe when partial evaluation is used to pre‑compute query fragments for later execution, or when the partial result is inspected as a policy explanation.
```

Fix variable namespacing in partial eval


## Feature Request: Support `file://` URLs for Bundle Resources

**Current behavior**
OPA's bundle plugin requires every bundle `resource` to be associated with a `service` entry in the configuration. If a user sets a bundle's `resource` to a `file://` URL (e.g., `"file:///tmp/bundle.tar.gz"`) without a matching service, the plugin fails configuration validation.

**Expected behavior**
When a bundle `resource` is a `file://` URL, OPA should:
- Accept the configuration without requiring a `service` entry.
- Load the bundle from the local filesystem path specified in the URL.
- Activate the bundle and notify registered listeners and bulk listeners, using the same activation path as remotely downloaded bundles.
- Respect the bundle’s `signing`, `size_limit_bytes`, and other relevant source options when loading from disk.
- Leave handling of non-`file` URLs unchanged.

This would allow users to test OPA integrations with local bundle files without needing to set up a local HTTP server or modify their configuration to include a dummy service.

**Impact**
Adding `file://` support makes local testing and development with bundles significantly easier, removing friction when validating policy changes or building tooling around OPA.

plugins/bundle: Add support for file:// urls


**Title:** Multi-expression queries with failing comparisons incorrectly return a result in `rego.Eval`

**Description:**

When evaluating a multi-expression query via the `rego` package that should yield no results because a comparison expression is false, `Rego.Eval()` returns a single empty result instead of an empty result set. For example:

```go
r := rego.New(rego.Query("a = 1; b = 2; a > b"))
rs, err := r.Eval(ctx)
```

I would expect `rs` to be an empty set (no bindings), because `a > b` (i.e., `1 > 2`) is false and should cause the query to be undefined. However, `rs` contains one result. This leads to incorrect policy decisions for any rule that relies on multi-expression conditional logic evaluated through the `rego` API.

The equivalent single-rule policy `p { a = 1; b = 2; a > b }` behaves correctly (no results), so the issue is confined to how the `rego` package handles multi-expression queries directly.

**Suspected Cause:**

I believe the problem lies in `rewriteQueryToCaptureValue`. This step inserts capture variables for expression values, but it appears to only do so when the query contains iteration (e.g., comprehensions or `some` clauses). For a simple multi-expression query like `a = 1; b = 2; a > b`, no capture variable is added. Without a captured result, the final comparison expression may be treated as a generator that succeeds unconditionally, producing a spurious empty result. The fix should ensure that capture variables are also added for any multi-expression query, not just those containing iteration, so that a false comparison correctly yields no result.

**Expected Behavior:**

- Queries like `a = 1; b = 2; a > b` should produce an empty result set (no bindings).
- Single-expression queries (e.g., `1 > 2` alone) already work correctly, so the fix should not break those.
- The behavior should be consistent with the evaluation of the same expressions inside a rule body.

**Acceptance Criteria:**

- The `rego` package returns no results for multi-expression queries where a comparison evaluates to false.
- The evaluation correctly respects the order of expressions and short-circuits on failure.
- The existing behavior for queries containing iteration continues to work.
- The fix should be accompanied by a test case that exercises this scenario (e.g., `a = 1; b = 2; a > b` expecting an empty result set).


```markdown
### Add `regex.find_all_string_submatch_n` and `strings.replace_n` built‑ins

**Background**
- OPA already has `regex.find_n`, which returns matching substrings, but there is no way to capture regex groups.
- OPA has `replace(string, old, new)` for single‑pair replacement, but no built‑in to apply **multiple** old→new replacements in one call.

**Request**
Add two new built‑ins to the default set:

1. **`regex.find_all_string_submatch_n(pattern, value, number)`** → `array[array[string]]`
   - `pattern` – regex as a string.
   - `value` – the string to search.
   - `number` – maximum matches to return; `-1` means all.
   - Returns all successive matches of `pattern` in `value`, including capture groups for each match (outer array = matches, inner array = full match followed by captured groups).
   - Must raise an evaluation error if `pattern` is not a valid regex.

2. **`strings.replace_n(patterns, value)`** → `string`
   - `patterns` – an object where **each key is an old substring** and **its value is the replacement string** (both must be strings).
   - `value` – the string in which replacements are performed.
   - Returns a new string where every occurrence of each old substring is replaced by the corresponding new substring.
   - Replacement behaviour **must match `strings.NewReplacer` in Go**:
     - Replacements are applied left‑to‑right without overlapping.
     - If multiple old strings could match at the same position, the behaviour follows the iteration order of the pairs (which is the order in which they are supplied to `NewReplacer`). Since the object keys have no guaranteed order, the exact tie‑breaking is not prescribed, but the result must be deterministic for a given object value.
   - If any value in `patterns` is not a string, raise an evaluation error.
   - If `patterns` is empty, return `value` unchanged.

**Acceptance criteria**
- Both built‑ins are listed in the default built‑ins and can be called from Rego policies.
- The [policy‑reference documentation](https://www.openpolicyagent.org/docs/latest/policy-reference/) is updated to describe the new functions.
- Invalid regex and non‑string pattern values produce clear errors at evaluation time.
- Existing functions (`regex.find_n`, `replace`) continue to work unchanged.
```

Add regex.find_all_string_submatch_n and strings.replace_n built-ins


**Title:** `http.send` incorrectly escapes/quote string parameters (TLS certs, raw_body, etc.)

**Description:**
The `http.send` built-in mishandles string-valued parameters that contain special characters, particularly newlines. For example, users who provide PEM-encoded TLS client certificates or keys see unexpected failures because the strings are not extracted literally from the AST—instead they go through `(*ast.Term).String()`, which produces a quoted representation. The code then tries to compensate by stripping outer quotes, but internal escape sequences (like `\n` inside the string) remain escaped or are incorrectly processed, leading to invalid certificate data being sent to the TLS layer.

The same issue likely affects `raw_body`, `url`, and other string parameters. Users expect that a Rego string containing newlines (e.g., a PEM block) is passed through exactly as written, without additional quoting or unescaping.

**Desired behavior:**
- All string parameters expected by `http.send` (`method`, `url`, `raw_body`, `tls_ca_cert`, `tls_ca_cert_file`, `tls_ca_cert_env_variable`, `tls_client_cert`, `tls_client_cert_file`, `tls_client_cert_env_variable`, `tls_client_key`, `tls_client_key_file`, `tls_client_key_env_variable`, `tls_server_name`) must be obtained directly from the `ast.String` value, bypassing `(*ast.Term).String()` entirely.
- Remove any ad-hoc replacement logic that was previously needed to fix up incorrectly quoted strings (e.g., `\\n` → `\n` transformations).
- If a parameter that must be a string receives a non‑string value, `http.send` should return a clear, consistent error message indicating which key is wrong (e.g., `"raw_body" must be a string`).

**Additional context:**
This affects use cases where PEM data is constructed dynamically and passed to `http.send` for mTLS. The current behavior forces users to pre‑process their strings in unnatural ways or avoid newlines, which breaks standard certificate formats. Fixing this will make `http.send` behave correctly with respect to Rego’s semantics: a string literal in a policy should be the exact string value, without any extra quoting.

topdown: fix `http.send` string conversions


# Bug Report: OPA fails to fetch AWS credentials when IMDSv2 is required on EC2

## Problem

When running OPA on an EC2 instance that enforces IMDSv2, OPA fails to retrieve IAM role credentials from the instance metadata service. This causes any functionality that relies on AWS signing (e.g., bundle downloads from S3) to break.

The current implementation uses only IMDSv1 (a simple `GET` to the metadata credentials endpoint without a token). Many AWS environments now default to requiring or unconditionally enforcing IMDSv2, which means those `GET` requests are rejected (HTTP 401 or similar), and OPA cannot obtain credentials.

## Expected Behavior

OPA should support IMDSv2 for EC2 instance metadata access. Specifically, when OPA is not running in an ECS container, it should:

- First, send an HTTP `PUT` request to `http://169.254.169.254/latest/api/token` with the header `X-aws-ec2-metadata-token-ttl-seconds` set to a reasonable value (e.g., `60`).
- Then, include the returned token as the value of the `X-aws-ec2-metadata-token` header in the subsequent `GET` request to the credentials endpoint (`http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>`).
- If the token endpoint returns an error or the credentials endpoint returns a non-200 status code, OPA should surface a clear error message indicating which step failed.

## Environment‑Specific Behaviour

- When OPA is running in an **ECS** container (i.e., the environment variable `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is set), the existing ECS credential retrieval path must be preserved **without** any IMDSv2 token logic. ECS uses a different endpoint (`http://169.254.170.2`) and does not require a token.
- The credentials endpoint URL construction (including role‑name resolution) should continue to work as it does today; the token flow only applies when the endpoint is the EC2 metadata service.

## Additional Considerations

- Both the token request and the credentials request should use a reasonably short timeout (e.g., 10 seconds) to avoid blocking indefinitely in broken network environments.
- The implementation should handle errors from the token service gracefully, distinguishing between a failed token request and a failed credentials request, to aid debugging.
- Logging of the metadata service responses (URL, status, headers) should be retained or improved for operational visibility.

## Impact

Without this change, OPA cannot operate on EC2 instances where IMDSv1 is disabled. This is becoming the default or recommended setting in many environments due to its security improvements over IMDSv1 (protection against SSRF vulnerabilities). Supporting IMDSv2 is therefore essential for OPA to remain usable on modern AWS infrastructure.

Implement IMDSv2 for AWS metadata service


Allow setting bundle roots when building a bundle with the `compile.Compiler`.

When `Compiler.Build()` produces a bundle, the resulting `.manifest` currently never includes `roots`. This prevents callers from scoping the bundle’s data to specific root paths, which is needed for consumers that rely on manifest roots. Add a configuration option on `Compiler` that accepts one or more root strings. When set, the bundle produced by `Build()` must include those roots in its manifest. When not set, the behavior should remain unchanged (no roots). The option should be additive (multiple calls concatenate roots), matching the existing patterns on `Compiler`.

compile: bundle roots can be provided by caller


**Feature request: SDK Decision/Partial results should include provenance (bundle revisions & OPA version)**

**Problem**
When using the OPA SDK to evaluate policy decisions, the returned `DecisionResult` and `PartialResult` structs do not carry any provenance information. Contrast this with OPA’s REST API, which includes a `provenance` field in its responses that reports the OPA server version and the revision of every bundle used for the decision. SDK users have no equivalent way to determine which bundle revisions (or even which OPA version) were in effect when a decision was made. This makes auditing, debugging, and integration with deployment tooling much harder.

**Desired behaviour**
- `DecisionResult` and `PartialResult` should expose a `Provenance` field whose type matches the existing `types.ProvenanceV1` structure already used by the server API.
- The field should be populated with:
  - The OPA SDK version information (version string, VCS, timestamp, hostname).
  - A map of bundle names to revision strings, reflecting the bundles actually loaded at the time of evaluation.
- The provenance should be computed from the same bundle metadata that the SDK already fetches internally (the `bundles` helper). If no bundles are loaded or a bundle lacks a revision, the corresponding entry may be omitted or left with an empty revision (the server API’s behaviour is a reasonable reference).
- This behaviour should apply to both the `Decision` and `Partial` calls.

**Additional context**
- The SDK’s test helper (`sdk/test`) currently does not understand bundles that contain `.manifest` files or `.json` data files; it only handles `.rego` files. This makes it impossible to write SDK-level tests that exercise bundles with explicit revisions or data documents. Extending the mock‑server bundle handler to support `.manifest` files (providing revision metadata) and `.json` data files would allow the new provenance feature (and other bundle-data scenarios) to be tested properly.

**Impact**
Until this is implemented, SDK users must resort to out‑of‑band channels to learn which bundle revision was used for a given decision, which breaks the goal of transparent, auditable policy enforcement.

sdk: Return provenance information in Result types (#5460)


We need a feature parity for `opa eval` similar to `opa bench`, allowing repeated evaluation with `--profile` and `--count=N` to collect aggregated metrics and expression profiling statistics across multiple runs. Currently, `opa eval --profile` only runs once and outputs raw timers and a flat profile. Users want to run the same query multiple times and get aggregated statistics (min/max/mean/90%/99% percentiles) for both the timer metrics and the per-expression time. The `--count` flag already exists for `opa bench`; we should extend it to `opa eval` when `--profile` is enabled.

**Requirements:**

- Add a `--count=N` flag to `opa eval` (default 1). When `--count` > 1 and `--profile` is enabled, evaluate the query N times, collecting the profiling data (metrics timers and expression stats) from each run independently.
- The per-run evaluation must not contaminate subsequent runs: profiler state and metrics must be reset before each evaluation.
- After the N evaluations, aggregate the collected data:
  - For each timer metric (e.g., `timer_rego_query_eval_ns`), compute min, max, mean, 90%, and 99% percentiles over the N runs. Use the existing histogram statistics from `go-metrics` (already used internally for the `Histogram` type) to produce these aggregates.
  - For each expression in the profile, aggregate its per-run `ExprTimeNs` values (others like `NumEval`, `NumRedo`, and location should be the same across runs, so just take from the first run).
- **Output format** (JSON and pretty):
  - When `--count=1` (or `--count` not specified), behavior must remain unchanged: output `metrics` and `profile` fields as before.
  - When `--count>1`, remove `metrics` and `profile` from the output object, and instead include `aggregated_metrics` (a map from timer name to a statistics object containing `min`, `max`, `mean`, `90%`, `99%`, plus full percentiles like `75%`, `95%`, `99.9%`, `99.99%`, `median`, `stddev`, `count`) and `aggregated_profile` (list of objects with `total_time_ns_stats` containing the same statistics for the expression timing, plus `num_eval`, `num_redo`, `location`).
  - The pretty output should render these as two tables: one for aggregated metrics (columns: METRIC, MIN, MAX, MEAN, 90%, 99%) and one for aggregated profile (columns: MIN, MAX, MEAN, 90%, 99%, NUM EVAL, NUM REDO, LOCATION). The aggregated profile table should display times as human-readable durations (e.g., `µs`, `ms`).
- The implementation should not break the `opa bench` code that shares `evalContext` (which currently holds a `*rego.Rego`). Since we need fresh `rego.Rego` instances per run (to avoid reusing stateful prepared query objects), the internal representation of `evalContext` will need to change, but the external commands must remain functional. The `bench` command must also adapt to any changes in `evalContext`'s exported fields or construction.

**Edge cases and constraints:**

- When `--count` is specified without `--profile`, it should have no effect (just evaluate once). The aggregation logic must only activate when both profiling and count>1 are set.
- The flag must accept only positive integers; 0 or negative values should be rejected (or treated as error).
- The per-run reset of metrics must clear all timers, histograms, and counters to ensure independent measurements.
- The profiler reset must create a new profiler instance each run, since its internal state accumulates.
- The aggregated profile must handle the case where the number of expressions in the profile differs across runs (should not happen in practice, but if it did, we need a safe behavior; ideally assert that the profile arrays have the same length and expression order, as profiling is deterministic for the same query).
- The existing `--profile-sort` and `--profile-limit` options must work with aggregated output. They should sort by the aggregated statistics (e.g., mean total_time_ns) and limit the number of displayed rows accordingly.
- The `--format=pretty` output for aggregated metrics/profile must respect the `--pretty-limit` for truncating long metric names or values.
- The JSON output should not include the raw profile or metrics fields when aggregated ones are present.

**Note:** This feature is purely additive and should not affect the behavior of `opa eval` without `--count` or without `--profile`.


The compiler's semantic check for function references currently misses cases where an unapplied function reference appears inside a composite term (array, object, set). For example, rules like:

`p { [data.base.foo] }`
`p { x = data.base.foo }`

pass without an error, but they should be flagged just as `p { data.base.foo }` is. An unapplied reference at evaluation time leads to undefined behaviour, so the check must always apply, regardless of nesting depth.

At the same time, nested where one function is passed as an argument to another (e.g., `f(g(x))`, `data.base.foo(data.base.bar)`) must still be accepted as valid. Ensure the fix covers all places a reference can appear, including inside array, object, and set literals, without breaking legitimate nested function application.

Fix semantic check for function references


**Bug: Test runner stops entire run on test timeout instead of just failing the timed-out test**

When `opa test` is invoked with a timeout (e.g. `--timeout 10ms`) and a test exceeds the deadline, the runner currently treats the resulting error like an explicit cancellation and stops executing the remaining tests. Only an explicit cancellation—such as the user interrupting the process (SIGINT) or a context cancellation—should cause the runner to stop early. A timeout should make the individual test fail (with an appropriate error) but the runner should then proceed to the next test as usual.

Acceptance criteria:
- Given a test suite with multiple tests and a per-test timeout, when one test times out, the runner must still execute all subsequent tests.
- An explicit cancellation (e.g., via Ctrl+C or a cancelled context) must still stop the runner and skip remaining tests.
- The timed-out test must still report a failure (e.g., as a cancel/timeout error), but must not abort the overall test run.

Fixup into commit 0ccccdba71d39436d5282545bb92db72c9566c6d (squash before merge)


## Feature Request: Reduce version-check frequency for long-running OPA instances

### Problem
When OPA's version check is enabled, it periodically reports the current version and checks for updates once per hour, with a random jitter. For instances that run for many hours or days, this hourly log noise is excessive and unwelcome. The check should become less frequent after the instance has been running for a while.

### Desired Behavior
The periodic version-check loop should initially run at the existing ~hourly cadence, then throttle down to a ~6-hourly cadence after a few initial checks. The random jitter (up to 60 minutes) applied to avoid thundering-herd problems should be preserved in both phases.

### Acceptance Criteria
- **Initial phase:** The first 6 version checks occur at roughly one-hour intervals, each with the usual random jitter of 0–60 minutes (same as today).
- **Later phase:** Starting with the 7th check and for all subsequent checks, the interval becomes roughly six hours, again with the same 0–60 minute random jitter.
- **Transition:** The switch from hourly to six-hourly must happen automatically after 6 completed checks; no extra configuration flags are required.
- **No regression:** When version checking is disabled, nothing changes. When enabled, startup behavior, the first check timing, and the check payload remain unchanged. Other runtime features (REPL, server, etc.) are unaffected.

runtime: send version report less often when long-running


```
Fix decision logs plugin dropping chunks after a failed upload.

When the total buffered log size exceeds `upload_size_limit_bytes`, the plugin
splits the payload into multiple chunks and uploads them sequentially in
`oneShot`. If any chunk upload fails, only that failed chunk is requeued and
the method returns immediately. Any chunks that were still waiting to be
uploaded from the current batch are not requeued; they are silently discarded,
leading to lost decision log events.

The fix must ensure that all chunks from the current batch that have not been
successfully uploaded are preserved in the buffer for retry, not just the
first failed one.
```

Fix discarded logs on chunk upload failure


We need a benchmark for partial evaluation (the "inlining full scan" path where a partial rule iterates over data) using the topdown `Query` API and `PartialRun`. The benchmark should exercise partial eval in isolation without subsequent evaluation.

At the same time, we need to instrument several low-level operations inside partial evaluation. Currently the topdown instrumentation covers regular evaluation steps (plug, resolve, rule index, builtin call, cache hits). We now need equivalent timing metrics for these partial-eval steps:

- `saveUnify` (the save-set unification that happens during partial eval)
- `Contains` and `ContainsRecursive` on the `saveSet`
- Copy propagation when applied to partial result bodies (the `Apply` call on the copy propagator)

When instrumentation is enabled (`topdown.Instrumentation` is present), each of these operations should emit a `startTimer`/`stopTimer` pair. The instrumentation struct must be threaded through the partial-eval code paths that need it, including the path triggered by `PrepareForEval` when a partial result is evaluated. There should be no panics when instrumentation is nil (the code should safely handle a nil `Instrumentation`).

eval: Add partial eval iteration benchmark and instrument


## Feature Request: Remove trivially true equality expressions from partial evaluation output

### Summary
OPA’s partial evaluation (e.g., `opa eval --partial` or equivalent API) sometimes produces output queries that contain expressions like `x = x` (or `equal(x, x)`) where both operands are the same variable. Such expressions are always true and add no constraint on the remaining variables. They should be omitted from the output to keep the partially evaluated query as concise as the current no‑op elimination already intends.

### Background
Today, the partial evaluator already removes certain no‑op expressions—for example, a constant `true` term is discarded. However, equality expressions of the form `equal(A, A)` (where `A` is the same term) are not recognized as no‑ops and remain in the output. This leads to redundant conditions that clutter the result and may confuse downstream consumers that only care about the essential constraints.

### Observable behavior to fix

**Before (current behavior):**
For a rule:
```rego
package test
p = x {
    input = x
    x = 100
}
```
The partial evaluation of `data.test.p == 100` might produce a query set that includes both `input = 100` and a redundant `input = input` (or equivalent `equal(input, input)`).

**After (desired behavior):**
The query set should contain only `input = 100`, with the self‑equality expression removed.

### Requirements

1. Any expression that is a call to the built-in equality operator (`equal` or `=`) where both operands are **the same term** must be treated as a no‑op and excluded from the partial evaluation result.
2. This treatment should be consistent with the existing removal of constant truthy values (e.g., the boolean `true`). In particular:
   - `equal(A, A)` should be considered always true and removed.
   - `equal(A, B)` where `A` and `B` are different (even if they are both constants) should continue to be preserved as normal constraints, unless they are already covered by constant‑folding elsewhere.
3. The special case of constant `false` must **not** be removed, as it represents a contradiction and must remain in the output.
4. The change must not affect any other no‑op elimination rules or the correctness of the partial evaluation itself; only the output’s minimality should improve.

### Acceptance criteria

- Given a rule similar to `p = x { input = x; x = 100 }`, the partial evaluation of `data.test.p == 100` yields exactly the query `input = 100` (no additional self‑equalities).
- If a partial evaluation produces both useful constraints and self‑equalities, only the self‑equalities are dropped.
- Constant `false` is never discarded.
- Existing behavior for constant `true` and other no‑op removals remains unchanged.

Extend copy propagation to remove no-op cases


Add a `show debug` command to the REPL to display the current state of debugging flags.

When a user runs `show debug`, the REPL should output a JSON object that indicates whether tracing, metrics reporting, and instrumentation are currently enabled. Each flag should be represented as a boolean field. The output must be well-formed JSON so that it can be consumed programmatically.

The existing plain `show` command (which prints the active module) must continue to work unchanged. The new `show debug` subcommand should only be recognised when the first argument to `show` is the literal string `debug`. If an unrecognised argument is passed to `show`, the REPL should return an error.

The three flags whose state should be reported are:
- tracing (toggled by the existing `trace` command)
- metrics (toggled by `metrics`)
- instrumentation (toggled by `instrument`)

After toggling any of these flags, a subsequent `show debug` must reflect the updated state.

The command should also be discoverable in the REPL's built-in help output.


We need to reduce heap allocations and evaluation time when Rego rules iterate over arrays, e.g. `input.foo[_] == "some_value"`. This is a hot path: profiling shows that per-element allocations from closure captures and error-wrapping logic are expensive.

Acceptance criteria:
- **Behavior unchanged**: Any policy using array iteration must produce exactly the same results as before, including error propagation (cancellation, early-exit) and trace events.
- **Tracing parity**: When tracing is enabled, the same unification trace events must still be emitted for each array element.
- **Only arrays**: The change must not alter the semantics or performance of set/object iteration; only array iteration should be restructured.
- **Measurable improvement**: Array-iteration benchmarks should show a substantial drop in allocations and wall-clock time relative to the current implementation.

Constraints:
- Do not change the public API or the signature of `unifyIterator`/`evalIterator` helpers.
- The existing `handleErr` helper must remain available; any restructuring of error handling must still correctly suppress or propagate early-exit errors.
- Bindings created during iteration must be properly undone after each element (no cross-element binding leakage).


We need the following implementation request, a terse performance improvement task.

```
Performance: reduce per-element big.Float allocations in sum/product built-ins.

The NumberToFloat helper used in builtinSum and builtinProduct allocates
a new big.Float on every call. For float-heavy workloads (arrays/sets of
non-integer numbers) this produces significant garbage.

Modify the aggregation code so that a single big.Float buffer is reused
across the iteration, avoiding per-element allocations. You may add a
variant of NumberToFloat that writes into a caller-provided big.Float
instead of allocating.

Numeric results must remain unchanged; edge cases like empty collections,
mixed int/float, and error handling must be preserved.
```

perf(topdown): reduce allocs in float sum/product (#8235)


When Entity support was added to the resource data model, the JSON unmarshaling path was not updated. As a result, `entityRefs` in a resource are silently dropped during JSON decoding. We need to fix this and add proper round-trip marshal/unmarshal tests for all signal types (traces, metrics, logs, profiles) so that similar omissions are caught automatically in the future.

Specifically:
- Resource JSON unmarshaling must handle the `entityRefs`/`entity_refs` field, populating the corresponding slice of `EntityRef`.
- Each `EntityRef` must decode its `schemaUrl`, `type`, `idKeys` (a list of strings), and `descriptionKeys` (a list of strings).
- Add a round-trip test for each pdata signal type (traces, metrics, logs, profiles) that marshals a fully-populated object and then unmarshals the JSON, asserting equality. The test data should include resources with entityRefs and attributes using a variety of value types (string, bool, int, double, bytes, array, key-value list).

Fix JSON unmarshal and add e2e tests (#13480)


We need to make the config unmarshaling for the `service` section consistent with how other top-level components (receivers, processors, exporters, extensions) are handled. Currently the service block uses a dedicated struct for its raw settings (`serviceSettings`) instead of being processed through the same generic unmarshaling helper that the other sections use. This leads to several issues:
- The service configuration does not benefit from the same mapstructure-based decoding, defaulting, and error pathways that the other sections get.
- There is overlap and duplication in how default values are applied (e.g., default telemetry log settings are set by directly constructing a `ServiceTelemetry` struct rather than letting the generic unmarshaler handle them with `mapstructure` defaults).
- Error reporting is inconsistent: other sections produce typed error codes specific to their category, whereas service-related errors currently are all lumped together under a generic top-level structure error code.

Goal:
1. Refactor the config unmarshaler so that the `service` config section is unmarshaled in the same generic fashion as the other sections. That means:
   - The raw parsed service data should be kept as `map[string]interface{}` (like the other sections) and then passed to the existing `unmarshal` helper that uses `config.Map` and `mapstructure`.
   - Pipeline metadata (e.g., `Name` and `InputType`) should still be populated after unmarshaling, based on the pipeline’s map key, just as before.
   - Default telemetry values should be preserved (e.g., level = info, encoding = "console", development = false).
2. Introduce distinct error codes for each component category (extension, receiver, processor, exporter, service) so that category-specific decoding errors can be distinguished from top-level structural errors. The existing `errUnknownType` and `errUnmarshalTopLevelStructureError` codes should be replaced accordingly.
3. Move the `Service`, `ServiceTelemetry`, `ServiceTelemetryLogs`, `DataType`, `Pipeline`, and `Pipelines` type definitions out of `config/config.go` into a new, dedicated file within the `config` package (e.g., `config/service.go`). This separates concerns and makes the large `config.go` file easier to navigate. The `config.go` file should then only contain the `Config` struct and its validation logic, plus the basic type/interface definitions.

Important invariants:
- Existing unit tests for valid configs must continue to pass.
- Negative test cases (invalid configs) should be updated to expect the new, more specific error codes where appropriate. For example, an invalid pipeline type should now report an `errUnmarshalService` code, not a generic top-level structure error.
- The overall behavior of the collector when parsing and validating the `service` section of the configuration must remain identical, except for the error codes.
- All `mapstructure` tags on the service-related structs should be added/verified so that the generic unmarshaling path works correctly (e.g., `telemetry`, `extensions`, `pipelines` on `Service`, and nested fields).

This aligns the service configuration handling with the other component sections, simplifies the codebase, and improves error diagnostics for users.

Move service config to separate file, unmarshal service as any other component (#4334)


**Feature request: Prometheus receiver pdata path missing histogram distribution conversion**

The OpenTelemetry Collector’s Prometheus receiver is being migrated from OpenCensus proto to pdata. The OpenCensus path (`metricGroup.toDistributionTimeSeries` in `internal/metricfamily.go`) correctly converts a histogram metric group into a distribution timeseries. The pdata counterpart struct (`metricGroupPdata` in `internal/otlp_metricfamily.go`) exists and embeds the same metric data, but there is no method to produce a pdata `HistogramDataPoint` slice from it. As a result, when the receiver is built with the pdata metric builder, histogram metrics are silently dropped or handled incorrectly.

We need to add the missing conversion so that histogram metrics are exported via the pdata path exactly as they are via the OpenCensus path.

**Acceptance criteria**

1. Add a `getGroupKey` method on `metricFamilyPdata` that updates the label keys and computes a deterministic group identifier consistent with the existing `metricFamily.getGroupKey`.

2. Add a `toDistributionPoint` method on `metricGroupPdata` that populates a `pdata.HistogramDataPointSlice` with one data point. The conversion must produce the same final metric data as the OpenCensus `metricGroup.toDistributionTimeSeries` when given the same input. The method should handle these invariants:

   - Return `false` and leave the destination empty when the group lacks a count or has no bucket data (`complexValue` is empty).
   - Sort bucket data before building the histogram.
   - Compute **bucket counts** as cumulatives, adjusting the raw bucket values (each bucket value minus the previous bucket value) to match the semantics of `SetBucketCounts`.
   - Set **explicit bounds** without the final `+inf` bound (the last complex value is the `+inf` bucket, and its boundary is excluded from the bounds slice).
   - Set `Count` to the group’s count, `Sum` to the group’s sum, and both `Timestamp` and `StartTimestamp` to the group’s timestamp converted from milliseconds to nanoseconds (`timestamp * 1e6`).
   - Populate the data point’s labels using an ordered label key list and the labels from the metric group, analogous to the OpenCensus label population.

3. Add a helper `populateLabelValuesPdata` that inserts label key-value pairs into a `pdata.StringMap` from an ordered list of keys and a Prometheus label set.

4. Fix the `loadMetricGroupOrCreate` initialization: the `metricGroup` embedded struct fields `ls` and `ts` are currently swapped, causing label and timestamp confusion. Correct the field order so that labels and timestamp are set to the arguments’ corresponding values.

**Out of scope**

- No changes to the metric builder or the overall pipeline wiring; only the internal conversion methods are needed.
- Exemplar handling is not required for the initial implementation, but the histogram point slice must be created correctly.
- No new public API or changes to existing exported interfaces.

**Verification hints**

The implementation can be verified by running the existing test `TestMetricGroupData_toDistributionUnitTest` and `TestMetricGroupData_toDistributionPointEquivalence` (both currently expected to be missing or failing). The equivalence test creates both OpenCensus and pdata representations from the same scraped data and asserts that the resulting histogram points match in all fields (count, sum, bounds, bucket counts, timestamps, labels). The tests should pass once the methods are implemented.

receiver/prometheus: add metricGroup.toDistributionPoint pdata conversion (#3667)


**Title:** Prometheus receiver drops `job` and `instance` labels; should attach them as resource attributes

**Description:**
When the OpenTelemetry Collector scrapes a Prometheus target via the Prometheus receiver, the two auto-generated labels `job` and `instance` are not preserved on the resulting metrics.
Prometheus guarantees that every scraped target has `job` and `instance` labels. Many downstream systems and dashboards rely on these labels to route, aggregate, and identify metrics sources. Currently, the receiver discards them, which breaks Prometheus data-model expectations and forces users to rewrite queries and alerting rules that depend on `job`/`instance`.

**Expected behavior:**
The Prometheus receiver should include `job` and `instance` as well-known resource attributes on every scraped metric, exactly as Prometheus does. The existing resource attributes (`port`, `scheme`) should remain unchanged. The `job` and `instance` values correspond to the target’s job name and instance identifier (host:port) as configured in the scrape config.

**Impact:**
- Restores Prometheus compatibility for any tool that consumes metrics through the collector.
- Avoids breaking changes for users migrating from standalone Prometheus to the collector.

Add job and instance as well-known attribute in prometheus receiver (#2897)


We should get rid of the convenience helpers `config.NewMapFromFile` and `config.NewMapFromBuffer`. They mix YAML parsing and config‑map loading inside the `config` package, which is something the config‑map provider family is supposed to own. All production and test code that wants a `*config.Map` from a file or an `io.Reader` should go through the provider layer (`configmapprovider.NewFile`, `configmapprovider.NewInMemory`, etc.) instead.

## What needs to happen

1. **Remove the public symbols** `NewMapFromFile` and `NewMapFromBuffer` from the `config` package.
2. **Update all internal callers** – production code and tests – so they obtain a `*config.Map` through the appropriate provider, or, where that isn’t practical, through a shared test‑only helper.
3. **Provide a test‑only helper** (e.g. in `config/configtest`) that loads a `*config.Map` from a file using the standard file provider. This avoids repeating the same verbose provider plumbing in multiple test files.

## Constraints & edge‑cases

- The removed helpers used YAML parsing; replacements must preserve identical YAML semantics.
- Some tests currently construct a config map directly from YAML strings. Those can switch to `config.NewMapFromStringMap` with the equivalent flat‑key representation, providers, or the test helper, whichever preserves clarity and doesn’t change test intent.
- Avoid introducing circular dependencies. The test helper in `configtest` should use the provider layer that already exists in `configmapprovider`.
- Make sure no production code path accidentally depends on the test‑helper.
- The `configsource` manager internally parsed YAML snippets with `NewMapFromBuffer` – that path must continue to work using unmarshal‑then‑wrap with `NewMapFromStringMap`, matching the previous YAML parsing behavior.

## Acceptance criteria

- `NewMapFromFile` and `NewMapFromBuffer` no longer exist in the public API of the `config` package.
- All existing tests pass unchanged (modulo necessary mechanical migrations to the provider or test helper).
- A single, discoverable helper exists in the test‑support area for loading a config map from a file.

Remove NewConfigMapFrom[File|Buffer], add testonly version (#4502)


Title: Add queue-retry for opencensus exporter

Description:

The OpenCensus exporter currently does not support queued sending or retry on failure. When the backend is temporarily unavailable, the exporter drops data instead of buffering it and retrying. Other exporters (OTLP, Jaeger) already get queuing and retry by leveraging the `exporterhelper` package with `QueueSettings` and `RetrySettings`. We should add the same capability to the OpenCensus exporter.

The exporter should accept `sending_queue` and `retry_on_failure` configuration blocks with the same semantics and defaults used by other exporters, using the helper structs from `exporterhelper`. The factory should construct the trace and metrics exporters by wrapping the raw export methods with `exporterhelper.NewTraceExporter` / `exporterhelper.NewMetricsExporter`, passing the queue, retry, and shutdown handlers via the appropriate options (`WithQueue`, `WithRetry`, `WithShutdown`).

Add queue-retry for opencensus exporter (#2307)


**Bug Report: `obsreport.NewExporter`/`NewReceiver` panic on metric creation errors instead of logging**

### Summary
The deprecated `NewExporter` and `NewReceiver` constructors in `obsreport` panic when OpenTelemetry metric instrument creation fails. They should instead log a warning (if a logger is available) and return a usable, partially‑initialized object, because they are meant to be non‑panicking constructor variants.

### Observed behavior
- Calling `obsreport.NewExporter(cfg)` (or `obsreport.NewReceiver(cfg)`) when the underlying `MeterProvider` fails to create one or more of the internal counters (e.g., `sentSpans`, `failedToSendSpans`, …) causes an immediate `panic`.
- The panic crashes the process, even though the metric creation failure is often non‑fatal and the exporter/receiver can still function.

### Expected behavior
- The deprecated `New` variants should **not** panic. They should collect the errors from metric instrument creation, log a single warning (if a logger has been provided via `ExporterCreateSettings.Logger` / `ReceiverCreateSettings.Logger`), and return the object.
- If no logger is configured, the error should be silently swallowed; the object should still be returned.
- The `Must` variants (`MustNewExporter`, `MustNewReceiver`) should **continue to panic** on such errors; that is their documented contract.

### Why this matters
- The naming convention suggests that `Must…` panics on error while `New…` does not. Users who rely on the deprecated `New…` functions (or have legacy code that calls them) reasonably expect a graceful degradation (a warning log) instead of a fatal crash.
- A momentary problem with a metrics backend should not bring down a long‑running collector process.

### Request
Please update `NewExporter` and `NewReceiver` to:
- Return a possibly partially‑initialized `*Exporter` / `*Receiver` after metric creation errors.
- Log a warning (via the configured logger) detailing the aggregated errors, only when the logger is non‑nil.
- Keep `MustNewExporter` and `MustNewReceiver` unchanged in their panic‑on‑error behavior.

If the deprecation notices for `NewExporter` and `NewReceiver` need updating to reflect the new behavior, please adjust them as well.

make new functions to log and must functions to panic


Title: Service zpages not reachable through zpages extension

Description:
The `zpages` extension uses the component host to register its handlers by calling `host.RegisterZPages(mux *http.ServeMux, pathPrefix string)`. The runtime host passed to extensions is now wrapped in a helper (e.g., to add logging on fatal errors), but this wrapper does not expose a `RegisterZPages` method. As a result, the service-level zpages (`/debug/tracez`, `/debug/rpcz`, `/debug/pipelinez`, `/debug/servicez`, `/debug/extensionz`) are never registered and return 404 or fail to serve on the zpages port (default `55679`).

We need a temporary fix: the wrapper should forward `RegisterZPages` calls to the underlying host if the underlying host supports that optional interface. This allows the zpages extension to work again while we design a better mechanism for service pages in the extension.

Acceptance criteria:
- Starting the collector with the default configuration (which enables the zpages extension) should serve the five known debug pages on the zpages HTTP port.
- The fix should be limited to the host wrapper; the extension and service code should remain unchanged.
- The forwarding should use a type assertion to check that the inner host implements the method, keeping the wrapper itself compliant with the existing `component.Host` interface without adding the method to that interface.


**Feature request: Extensible option types for configgrpc client/server construction**

`configgrpc.ClientConfig.ToClientConn` and `ServerConfig.ToServer` currently accept extra options as `...grpc.DialOption` and `...grpc.ServerOption` respectively. This prevents us from ever adding non‑gRPC option types (e.g. interceptors, custom dialers, observability hooks) without breaking the API. We want to replace the concrete gRPC option types with a more general option interface while keeping backward compatibility.

**Acceptance criteria**

1. **New generic option interfaces**
   - Introduce a sealed (cannot be implemented externally) interface for client‑connection options.
   - Introduce a sealed interface for server options.
   - Provide public constructors that wrap an individual `grpc.DialOption` into the client option interface, and an individual `grpc.ServerOption` into the server option interface.

2. **New methods on config structs**
   - Add a method `ToClientConnWithOptions` on `ClientConfig` that accepts the new client option interface variadic. Its semantics must be identical to `ToClientConn` when all supplied options are wrapper types around `grpc.DialOption`.
   - Add a method `ToServerWithOptions` on `ServerConfig` that accepts the new server option interface variadic, with analogous semantics.

3. **Deprecation of original methods**
   - `ClientConfig.ToClientConn` must remain callable, but its documentation must mark it as deprecated and direct users to `ToClientConnWithOptions` + the wrapper constructor.
   - `ServerConfig.ToServer` must be similarly deprecated.
   - Each deprecated method must convert every raw `grpc.DialOption`/`grpc.ServerOption` to the corresponding wrapper type and then delegate entirely to the new method, so there is exactly one implementation of the connection-creation logic.

4. **Internal option processing**
   - The internal helpers that build the final `[]grpc.DialOption` and `[]grpc.ServerOption` slices must accept the new option interfaces and extract any wrapped gRPC options from them.
   - The extracted gRPC options must be appended to the option list in the same order they were provided, preserving the existing behavior exactly.

5. **Caller updates**
   - All in‑tree callers that currently pass `grpc.DialOption` or `grpc.ServerOption` directly (e.g. the OTLP exporter providing a user‑agent dial option, the OTLP receiver constructing the gRPC server) must be updated to use the new methods and the wrapper constructors. No observable behaviour should change.

6. **Testing**
   - Verify that using the new method + wrapper constructor results in the same gRPC options as the old method with raw `grpc.DialOption`/`grpc.ServerOption`.
   - Verify that the deprecated methods still work correctly when fed raw gRPC options.

[configgrpc] wrap gRPC client/server options in extensible interface (#11069)


The exporterhelper's byte-size-based request splitting for metrics does not correctly account for the size of metric-level fields (name, description, unit, metadata) when a metric is split across multiple requests. This can cause the resulting split requests to exceed the configured maximum byte size, potentially leading to export failures. Additionally, a metric that loses all of its data points during splitting can end up being added to the output with only its description/metadata present, adding needless overhead.

Fix the split logic so that:
- The metric's name, description, unit, and metadata are included in the per-fragment size calculation when splitting a metric.
- A metric fragment is only added to the output if it contains at least one data point after splitting; empty metrics (zero data points) must be omitted.

A single metric whose fixed metadata alone already exceeds the remaining capacity should still be treated as unsplittable, consistent with the existing handling.

Fix metrics split logic to consider metrics description into the size (#13418)


**Summary**
The test helper components (`ExampleReceiver`, `ExampleProcessor`, `ExampleExporter`, `ExampleConnector`) each duplicate the same lifecycle state tracking (booleans `Started`/`Stopped` and corresponding `Start`/`Shutdown` methods). This duplication makes future changes error-prone and exposes internal state as public writable fields. Tests read the state through direct struct field access, which is brittle and allows accidental mutation.

**Expected behavior / Solution**
Extract a common, reusable type that encapsulates the started/stopped lifecycle state. This type should provide:

- `Start` and `Shutdown` methods that update the internal state appropriately (mirroring the current behaviour where Start sets started = true, Shutdown sets stopped = true).
- Exported **accessor methods** (`Started() bool`, `Stopped() bool`) instead of exported fields, so that callers can only observe the state, not modify it inadvertently.

All four example components should embed this new type and remove the duplicate `Started`/`Stopped` fields and their `Start`/`Shutdown` implementations. Components must continue to satisfy their respective interfaces (receiver, processor, exporter, connector) and work correctly with pipeline construction and lifecycle hooks.

**Impact / Scope**
- The four example test components will no longer define their own lifecycle fields and methods.
- All test and production code that currently accesses `.Started` or `.Stopped` as fields must be updated to use the new accessor methods `.Started()` and `.Stopped()`.
- No other behavioural changes are intended; the pipeline integration tests that verify component startup/shutdown order must pass with the refactored helpers.

**Additional notes**
- Ensure the new type is unexported (internal to the testcomponents package) so it does not become a public API surface.
- When embedding, be mindful of method name conflicts and adjust the component struct’s other embedded fields if necessary to avoid ambiguity (e.g., if a consumer interface and the lifecycle type share names, resolve appropriately).
- The factory functions that create these test components may need minor adjustments to accommodate the new embedding, but the external API for registering and using the test factories should remain unchanged.


```
The `exporterhelper/internal` package defines its own `QueueBatchSettings` struct that
duplicates a subset of the fields from `queuebatch.Settings`.  Having two copies of the
same concept in different packages has already led to a bug where a change to one was
not mirrored in the other.

Remove the duplicate.  To do this without breaking callers, the `queuebatch.Settings`
type must be split so that only the queue/batch‑specific fields (ReferenceCounter,
Encoding, ItemsSizer, BytesSizer, Partitioner) remain on the base `Settings` type, while
the higher‑level fields (Signal, ID, Telemetry, MergeCtx) move into a new type (e.g.
`AllSettings`) that embeds the base settings.  The `exporterhelper` public type
`QueueBatchSettings` should then alias the base `queuebatch.Settings` type directly.

Update the exporter helper’s internal wiring so that the full `AllSettings` is
constructed where needed (in `NewBaseExporter` / `NewQueueSender`), while the
`WithQueueBatch`‑style helpers accept the base `Settings` type.
```

[chore] Remove internal duplicate definition of QueueBatchSettings (#13700)


```markdown
**Title:** Reject invalid `queue_size` in exporter queue settings

**Background**
The `QueueSettings` struct (used by various exporters for internal buffering/retry) accepts any integer for `queue_size`. When combined with `enabled: true`, values like 0 or negative numbers can cause undefined runtime behavior or silent failures. Early config validation would catch mistakes and give a clear error before the collector runs.

**Desired behavior**
When an exporter configuration includes `QueueSettings` and the queue is enabled (`enabled: true`), `queue_size` **must be > 0**. If the queue is disabled (`enabled: false`) the `queue_size` value should be ignored during validation.

**Scope**
- `QueueSettings` itself should provide a validation routine that checks this constraint, so any consumer can reuse it.
- The OTLP exporter (which already has a `Validate()` method on its config) should invoke the queue-settings validation and return a descriptive error if the configuration is invalid.

**Edge cases**
- The default `QueueSettings` (obtained via `DefaultQueueSettings()`) must pass validation.
- When `enabled` is set to `false`, `queue_size` may be any value (including 0 or negative) without causing a validation error, because the queue is not in use.

**Acceptance**
- Invalid queue sizes are rejected during exporter config validation with a message indicating `queue_size` must be positive.
- The OTLP exporter is shielded from starting with a broken queue configuration.
```

Freakynoblegas/reject invalid queue size exporterhelper (#4799)


Add support for bytes-based batching of logs in the exporter helper. Currently the batch splitter for logs only considers item count via `SizerTypeItems`. Extend it to accept `SizerTypeBytes` so that, when the batcher config specifies `sizer: bytes`, the `MaxSize` is interpreted as a maximum serialized protobuf byte size for a batch. The split must be based on the actual protobuf encoding size of each `LogRecord`, `ScopeLogs`, and `ResourceLogs`, including the repeated-field overhead (tag and varint length). A single log record whose serialized size already exceeds the limit must still be placed in its own batch rather than being dropped. The extraction logic should use a sizing abstraction that works for both item-count and byte-size strategies, so that the count-based code path remains identical. Define the `SizerTypeBytes` constant; for now, `UnmarshalText` should still reject `"bytes"` to avoid prematurely enabling it for other signals. Keep the existing behaviour for `SizerTypeItems` unchanged. Performance and memory overhead are acceptable but should be measured with benchmarks for the bytes-path.

[exporter][batching] Serialized bytes based batching for logs (#12299)


Generalize `composeSignalURL` in the OTLP HTTP exporter to accept a signal version string (e.g. `"v1"`, `"v1development"`) instead of hardcoding `"/v1/"`. Update all existing callers to pass `"v1"` so that current URL behavior for traces, metrics, and logs is unchanged. This prepares the exporter to support profiles.

[chore][exporter/otlphttpexporter] Generalize `composeSignalURL` (#11206)


The `profilesRequest` type's `ItemsCount` method recomputes the number of items from the live data every time it is called. After `MergeSplit` moves resource profiles from one request to another, the counts for both the source and destination requests become stale or inconsistent. The logs request helper already handles this correctly; apply the same approach to profiles so that `ItemsCount` returns the expected count after merge/split operations, and ensure the count is computed once on construction.

[chore] Apply, items cache logic to profiles (#12171)


The OTLP HTTP exporter cannot be used with authentication extensions (e.g., OAuth2, basic auth) because the HTTP client is built during component creation rather than during component start.

**Observed problem**
When an authentication extension is configured for the OTLP HTTP exporter, the exporter never uses it. The exporter ignores any auth extension setup because it creates its `http.Client` inside `newExporter` at creation time, before extensions are available via the host.

**Expected behavior**
The exporter should support authentication extensions by deferring HTTP client construction to the component `Start` phase—when the host and its extensions become available. Errors that depend on runtime configuration (including invalid compression settings that require the client to be built) should surface at `Start` time rather than at creation time.

**Context**
This is the standard lifecycle pattern in the collector: components that need host services (like extensions) should obtain them in `Start`. The `exporterhelper` already provides a `WithStart` option that allows exporters to hook into the start lifecycle and properly set up their internal state. The fix should use that mechanism while preserving the existing timeout‑disable behavior (timeout is explicitly set to zero because the exporter relies on the `http.Client` timeout logic).

**Impact**
Without this change, the exporter cannot participate in collector authentication extension configurations, making it impossible to secure telemetry export to backends that require authentication.

Refactor otlphttp exporter for upcoming API chnages (#3289)


```plaintext
### Feature Request: Add error return to `extensionauth.NewClient` and `extensionauth.NewServer`

**Context**
The `extensionauth` package is an unreleased module that provides basic implementations of the `Client` and `Server` authenticator interfaces. Currently its constructor functions `NewClient` and `NewServer` return only the concrete instance, with no way to signal failures.

**Problem**
If these constructors ever need to perform validation of options, allocate resources, or enforce invariants, there is no mechanism to report an error. Adding error returns later would be a breaking change. Since the module has not been released yet, now is the right time to future-proof the API.

**Expected Behavior**
- `extensionauth.NewClient` should return `(Client, error)`.
- `extensionauth.NewServer` should return `(Server, error)`.
- In the current implementation, where no errors can occur, the functions should return `nil` errors.

**Compatibility**
- The deprecated wrapper functions in the `auth` package (`auth.NewClient` and `auth.NewServer`) delegate to these constructors. They must continue to implement their current signatures (returning only the object, no error).
  - These wrappers should be updated to call the new signatures and, if an error occurs (which it won’t in the current code), they should panic with a descriptive message to maintain the existing behavior and signal that something went unexpectedly wrong.
- All existing callers (including tests) that use `extensionauth.NewClient` or `extensionauth.NewServer` directly must be updated to handle the returned error. The deprecated `auth` package callers should not be affected because their signatures remain unchanged.

**Impact**
This change makes the `extensionauth` package’s public construction API robust against future extensions, aligns with Go conventions, and avoids a breaking change later.
```

[chore][extensionauth] Return error on NewClient and NewServer constructors (#12511)


As part of the ongoing internal telemetry cleanup (related to #4970), we need to simplify the `CreateLogger` contract in the `service/telemetry` `Factory` interface.

Currently `CreateLogger` returns a `*zap.Logger` and a `LoggerProvider` (which is just an OTel `log.LoggerProvider` plus `Shutdown`). The service then wraps the returned `*zap.Logger` with `componentattribute` teeing (both console and OTLP) by using the returned `LoggerProvider`. This leaks the OTel `LoggerProvider` into the service where it isn't needed, and it forces the service to know about `componentattribute` wrapping details.

We want to reverse that: `CreateLogger` should return a `*zap.Logger` and a `component.ShutdownFunc` instead of a `LoggerProvider`. The `LoggerProvider` type and its noop variant should be removed. The teeing behavior (writing to console via `componentattribute.NewConsoleCoreWithAttributes` and forwarding to an OTel `LoggerProvider` via `componentattribute.NewOTelTeeCoreWithAttributes`) must be preserved, but it should be moved into the `otelconftelemetry` logger implementation (since that is the only place where we actually create an OTel `LoggerProvider`). The service should no longer perform this wrapping; it should only store the returned shutdown function and call it during shutdown.

Acceptance:
- `Factory.CreateLogger` and `CreateLoggerFunc` signatures changed to return `component.ShutdownFunc` instead of `LoggerProvider`.
- `LoggerProvider` interface removed; `noopLoggerProvider` removed; all related OTel `log` imports removed from `telemetry.go` (the dependency may become indirect).
- `service.go` updated to use the new return values, store the shutdown function, invoke it on shutdown, and remove the `componentattribute` wrapping code and imports.
- `otelconftelemetry/logger.go` updated to apply the `componentattribute` wrapping before returning the logger, using the OTel `LoggerProvider` retrieved from the SDK.
- Shutdown error message changed from `"failed to shutdown logger provider"` to `"failed to shutdown logger"` in `service.go`.
- All existing tests that relied on the `LoggerProvider` return or on the service-level wrapping are adjusted. The OTLP logging test should remain but validate that logs written to the returned `*zap.Logger` are correctly forwarded to the OTLP backend, and shutdown should be tested via the returned shutdown function.

[chore] service/telemetry: don't return LoggerProvider (#13871)


**Fix `IsPermanent` to handle wrapped permanent errors**

`IsPermanent` currently checks only the top-level error via a direct type assertion. This means a permanent error that has been wrapped (for example with `fmt.Errorf` and the `%w` verb, or any other standard wrapping) is not recognized as permanent. The function should walk the error chain so that any wrapped permanent error still returns `true`.

Make sure:
- `IsPermanent` returns `true` when a permanent error is wrapped one or more times.
- `IsPermanent` continues to return `false` for `nil` and for non-permanent errors (whether wrapped or not).
- `Permanent` continues to work as before.

Fix IsPermanent to account for wrapped errors (#2455)


Make the `model/otlpgrpc` request and response structs (`TracesRequest`, `TracesResponse`, `MetricsRequest`, `MetricsResponse`, `LogsRequest`, `LogsResponse`) implement the standard `encoding/json` interfaces (`json.Marshaler` and `json.Unmarshaler`), so they can be passed to `json.Marshal`/`json.Unmarshal` directly instead of requiring standalone JSON marshal/unmarshal functions. Similarly, move protobuf marshaling and unmarshaling onto the structs themselves via methods (e.g., `MarshalProto` / `UnmarshalProto`), consistent with how generated protobuf types typically work.

The existing standalone package-level functions (`Marshal`, `UnmarshalTracesRequest`, `UnmarshalJSONTracesRequest`, and their counterparts for metrics/logs/responses) should be deprecated but remain functional, delegating to the new methods.

Update all internal callers that currently use the standalone functions to use the new struct methods instead. The affected callers are in the `exporter/otlphttpexporter` and `receiver/otlpreceiver` packages. No other external behavior or wire format should change.

Change structs in otlpgrpc to follow standard go encoding interfaces (#5062)


**Title:** `pdata` JSON unmarshaler helpers should be package-level functions (like traces package)

**Description:**

In the `pdata` packages, the `jsonUnmarshaler` type has private `read*` methods that never use the receiver.  The receiver `d` is declared but never accessed.  This unnecessarily ties those functions to the struct when they could just be plain package-level helpers.

The `pdata/ptrace` package already does this correctly: its helper functions (`readTraceData`, `readResourceSpans`, etc.) are package‑level funcs, not methods on `jsonUnmarshaler`.  The `pdata/pmetric` and `pdata/plog` packages should follow the same pattern for consistency and to make it obvious that the unmarshalling logic doesn’t depend on the struct state.

**Scope / expected changes:**

- In `pdata/pmetric/json.go` and `pdata/plog/json.go`, convert all `func (d *jsonUnmarshaler) read…` private methods to package‑level `func read…` funcs.
- Update call sites inside the same files to call the new package‑level functions instead of `d.read…`.
- Update the exported `Unmarshal*` methods on `jsonUnmarshaler` to remove the named receiver if it isn’t used, leaving only an unnamed receiver (`func (jsonUnmarshaler) Unmarshal…`).
- Any corresponding test files that call the old methods via an instantiated `jsonUnmarshaler` should be adjusted to call the new package‑level functions directly (the tests already exist and just need their setup simplified).
- No external API, behaviour, or output should change; this is purely an internal clean‑up.

The goal is to reduce unnecessary coupling, align the logs and metrics unmarshallers with the traces unmarshaller style, and make the code easier to reason about.

Use private funcs instead of members funcs when possible (#6037)