# ObservMe Compatibility Matrix

Last updated: 2026-07-26

This matrix records the ObservMe runtime and observability-stack versions exercised or pinned for the current release line. A component is marked **validated** only when the named command actually exercised it; configured CI targets remain distinct from completed local or workflow evidence.

## Pi version policy

ObservMe never uses Pi's reported version as a startup gate. The Pi-mandated core package peers remain in `peerDependencies` with `"*"`; exact versions in development metadata and historical validation records are evidence, not installation constraints. CI does not reinstall or matrix-test fixed Pi versions. Before registering anything, startup checks only the essential `ExtensionAPI` capabilities `on` and `registerCommand`. When those methods exist, ObservMe starts regardless of whether Pi's version is older, newer, prerelease, malformed, or unavailable. Optional APIs are feature-detected by the handlers that use them.

Pi 0.80.5 is the earliest tested version, not a runtime minimum: its exported extension contract includes `session_info_changed`, which ObservMe uses for live rename metadata. Pi's current extension overloads do not include `bashExecution`, `model_change`, or `thinking_level_change`. Pi records interactive Bash results as `bashExecution` session messages without emitting `message_end`; after `user_bash`, ObservMe observes that result through the read-only `SessionManager.getEntries()` contract. Model and thinking changes are session entry types represented at runtime by `model_select` and `thinking_level_select`; ObservMe does not register those three non-event names. Tested versions provide release evidence only and never define an accepted or rejected runtime range.

## Integration API and child-envelope compatibility

Root discovery and child process compatibility are separate checks. A successful in-process v2 negotiation proves that the loaded root provider implements lifecycle API v2; it does not prove that a child launched under `--no-extensions` loads an extension that understands child-identity envelope version 1.

| Integration path | Root provider | Child extension | Compatible behavior |
| --- | --- | --- | --- |
| Legacy API v1 | Any provider exposing structural API v1 | An ObservMe release compatible with the existing lineage envelope | Metadata-free child identity: legacy `subagent` role, no display name, no child capability, and no v2 identity marker. |
| API v2 + identity envelope v1 | `@senad-d/observme` 0.1.8 or later | `@senad-d/observme` 0.1.8 or later, explicitly loaded when the child uses `--no-extensions` | Required display name, exact `lead`/`helper`/`worker`/`validator` role, and capability are propagated atomically. |
| Packed artifact release evidence | `@senad-d/observme` 0.1.8 installed in an isolated parent package root | The same 0.1.8 tarball installed in a separate child package root and explicitly loaded as the only child extension | `npm run smoke:packaged` negotiates API v2, starts a real Node child with the returned envelope, and verifies the child's bounded identity attributes. |
| V2 root with an older explicitly loaded child | 0.1.8 or later | Earlier than 0.1.8 | Not compatible with identity envelope v1. Pin or upgrade the child, or deliberately use the v1 metadata-free path. Do not partially copy v2 identity fields. |

Version 0.1.8 is the minimum release containing both the v2 root provider/helper and the envelope-version-1 child reader. The packaged-install release gate packs ObservMe once, installs that tarball in separately resolved parent and child module roots, and rejects missing or mismatched child envelope support without printing the child environment.

Separately installed Pi packages can resolve different copies or no resolvable copy of ObservMe. Compatibility is structural over the synchronous `observme:integration:request` event channel; consumers must not depend on shared constructors, `instanceof`, or Node module identity. Helper users may import `@senad-d/observme/integration`; intentionally decoupled consumers may mirror the documented request, response, lifecycle-result, role-catalog, and envelope-version shapes locally.

## Validation record

| Date | Environment | Command | Coverage |
| --- | --- | --- | --- |
| 2026-07-07 | Local Node.js v26.0.0, npm 11.12.1 | `npm run validate` | Typecheck, ESLint, formatting, unit tests, package contents, packaged install smoke, handler smoke, Pi lifecycle smoke. Does not start Docker Compose. |
| 2026-07-07 | Local Docker 29.5.2 with Collector Contrib 0.104.0 | `npm run test:integration:collector` | Starts a local debug-exporter Collector container, exports representative ObservMe traces/metrics/logs, and asserts default-disabled content capture is absent. |
| 2026-07-07 | Local Docker 29.5.2 with the pinned Grafana stack | `npm run test:integration:grafana-stack` | Starts `observability-stack/` services, exports representative ObservMe telemetry, queries Tempo by trace ID and lineage attributes, queries Loki by session ID, queries Prometheus token totals, and validates Grafana dashboard provisioning imports. |
| Continuous integration target | GitHub Actions `ubuntu-latest`, Node.js 22.19.0 | `npm ci --ignore-scripts` then `npm run validate` | CI target from `.github/workflows/ci.yml`; record the workflow run URL here after each release validation. |
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.5 | Exact version assertion then `npm run validate:pi-compatibility` | Passed typecheck, typed event contracts, capability diagnostics, packaged install, handler/lifecycle smoke, and real Pi RPC runtime at the earliest-tested version. |
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.6 | Exact version assertion then `npm run validate:pi-compatibility` | Passed the same compatibility suite at the former release-tested version. |
| 2026-07-22 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.81.1 | Exact version assertion, typechecks, compatibility tests, packaged install, handler/lifecycle smoke, and real Pi RPC runtime | Passed the complete `npm run validate:pi-compatibility` suite at the former release-tested version. |
| 2026-07-22 | Local Node.js v26.0.0, npm 11.12.1; exact Pi 0.81.1 development dependencies | `npm run validate` | Passed source/test typechecks, ESLint, formatting, 618 unit/contract tests, package-content checks, packaged-install smoke, handler smoke, Pi lifecycle smoke, and real Pi runtime smoke. |
| 2026-07-24 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.82.0 | `npm run validate:pi-compatibility` | Passed source/test typechecks, compatibility and event-mapping tests, packaged-install smoke, handler and lifecycle smoke, and the real Pi RPC runtime at the current release-tested version. |
| 2026-07-24 | Local Node.js v26.0.0, npm 11.12.1; packed `@senad-d/observme` 0.1.8 | `npm run smoke:packaged` | Passed one-tarball installation into isolated parent and child roots, parent API-v2 negotiation, real Node child startup, explicit child-extension loading, exact identity hydration, and stale-parent identity exclusion. |
| Lease cancellation CI profile (configured 2026-07-14) | GitHub-hosted Linux `ubuntu-latest` (exact `ImageOS`/`ImageVersion` recorded in the Actions runner log); Node.js 22.19.0; Collector Contrib 0.104.0; Prometheus 2.53.1; Grafana 11.1.0 | `npm run test:active-agent-lease:contracts` then `npm run test:integration:active-agent-lease` | The bounded `lease-cancellation` job validates clean shutdown, `SIGTERM`, and cancellation-oriented `SIGKILL` convergence against the pinned Collector and Prometheus without secrets or a Grafana dependency. Grafana 11.1.0 is the recorded dashboard compatibility baseline validated separately by `npm run test:integration:grafana-stack`. `if: always()` cleanup is best effort; lease expiry is the asserted correctness mechanism. |
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1 | `npm run validate` | Passed 493 unit/contract tests plus typecheck, ESLint, formatting, script, package-content, packaged-install, handler, Pi lifecycle, and Pi runtime checks for the lease release candidate. |
| 2026-07-14 | Local Docker 29.5.2, Compose 5.1.4, Collector Contrib 0.104.0 | `npm run test:integration:collector`; Compose config; pinned Collector `validate` | Passed representative OTLP export, Compose interpolation, and the shipped Collector config validation. |
| 2026-07-14 | Local Docker 29.5.2, Collector Contrib 0.104.0, Prometheus 2.53.1 | `npm run test:integration:active-agent-lease` | Passed clean shutdown, `SIGTERM`, and cancellation-oriented `SIGKILL`; the raw claim remained cached while leased activity converged without Collector restart. Labeled containers and the network were absent after cleanup. |
| 2026-07-14 | Local Docker 29.5.2 with the pinned Grafana stack | `npm run test:integration:grafana-stack` | Unrelated pre-existing broad-stack blocker remains: this run timed out with an empty Prometheus total-token vector. That token path does not validate active-agent leases. Cleanup removed all integration containers and networks; focused lease evidence is unaffected. |
| 2026-07-14 | npm package dry run for `@senad-d/observme` 0.1.3 | `npm run pack:dry-run` | Passed with 124 files; metric source, dashboards, alerts, examples, target docs, and `skills/observme-docs/SKILL.md` were present. |

Active-agent lease interpretation additionally requires producer and Prometheus wall clocks to remain within 5 seconds. GitHub-hosted runners satisfy this expectation. Self-hosted runners are supported only with reliable NTP or equivalent synchronization; clock health must be monitored separately from the ObservMe version matrix.

## Runtime and library matrix

| Component | Version tested or pinned | Source of truth | Status | Evidence and notes |
| --- | --- | --- | --- | --- |
| Pi package API | Runtime policy: required API capabilities only; version never gates startup. Earliest tested Pi: 0.80.5; release-tested `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai`: 0.82.0 | `package.json` `observmeCompatibility`, development dependencies, `package-lock.json`, `.github/workflows/ci.yml` | Validated locally at the recorded versions; CI uses the normal dependency set without a fixed-version compatibility matrix | `npm run validate` includes exported event-contract tests, pre-registration capability diagnostics, package installation smoke, handler/lifecycle smoke, and a real Pi RPC runtime. Pi version values do not participate in startup acceptance. |
| Node.js | Local: 26.0.0; CI target/minimum: 22.19.0 | `node --version`, `package.json` `engines.node`, `.github/workflows/ci.yml` | Validated locally for 26.0.0; CI target pinned at 22.19.0 | Local validation ran on 26.0.0. CI is configured to validate on 22.19.0, which is also the minimum supported Node.js version. |
| OpenTelemetry JS package set | `@opentelemetry/api` 1.9.1; `@opentelemetry/api-logs` 0.220.0; OTLP proto exporters 0.220.0; `@opentelemetry/resources` 2.9.0; `@opentelemetry/sdk-logs` 0.220.0; `@opentelemetry/sdk-metrics` 2.9.0; `@opentelemetry/sdk-trace-base` 2.9.0; `@opentelemetry/sdk-trace-node` 2.9.0 | `package.json`, `package-lock.json` | Validated locally | `npm run validate` includes the OTEL lifecycle/exporter unit tests under `test/otel-*.test.mjs`. |

## Reference observability-stack matrix

| Component | Version pinned | Source of truth | Status | Evidence and notes |
| --- | --- | --- | --- | --- |
| Collector distribution | `otel/opentelemetry-collector-contrib:0.104.0` | `observability-stack/docker-compose.yml`, `test/integration/collector-debug.test.mjs`, `test/integration/grafana-stack.test.mjs` | Validated locally | `npm run test:integration:collector` verifies the debug-exporter path; `npm run test:integration:grafana-stack` verifies Collector fan-out to Tempo, Loki, and Prometheus. |
| Tempo | `grafana/tempo:2.5.0` | `observability-stack/docker-compose.yml` | Validated locally | `npm run test:integration:grafana-stack` queries the exported ObservMe trace by trace ID and by `pi.agent.id`/`pi.agent.parent_id` lineage attributes. |
| Loki | `grafana/loki:2.9.8` | `observability-stack/docker-compose.yml` | Validated locally | `npm run test:integration:grafana-stack` queries normalized Loki labels for the exported ObservMe session ID. |
| Prometheus/Mimir | `prom/prometheus:v2.53.1`; Mimir not configured | `observability-stack/docker-compose.yml` | Prometheus validated locally; Mimir not configured | `npm run test:integration:grafana-stack` queries exported ObservMe LLM token totals through the Prometheus datasource. Add a Mimir row if a Mimir backend is introduced. |
| Grafana | `grafana/grafana:11.1.0` | `observability-stack/docker-compose.yml` | Validated locally | `npm run test:integration:grafana-stack` validates datasource availability and provisioning import of the ObservMe dashboard pack. |

## Update rules

- Update this file whenever `package.json` `observmeCompatibility`, `package-lock.json`, `.github/workflows/ci.yml`, or `observability-stack/docker-compose.yml` changes a tracked version.
- Add a new validation-record row whenever a release candidate is validated locally, in CI, or against the Docker Compose stack.
- Do not mark backend components as validated unless a command actually started or queried that component.
- Keep workflow IDs, session IDs, agent IDs, trace IDs, and other high-cardinality values out of this document.
