diff --git a/aicontext/features/core/versioning/feature.md b/aicontext/features/core/versioning/feature.md new file mode 100644 index 000000000..54c8729bf --- /dev/null +++ b/aicontext/features/core/versioning/feature.md @@ -0,0 +1,31 @@ +# Feature: Versioning + +> Owner: shared | Last reviewed: 2026-07-03 | Canonical: yes +> Scope: The independent version numbers across HSM — what each is, and when to bump it. + +--- + +## Overview + +HSM carries **four independent** version numbers, **one per product**. They are not tied to each other: +each tracks a different product, is allowed to diverge, and bumping one never implies bumping another. +Authoritative bump rules live in the directory `AGENTS.md` files. + +## The four versions + +| Product | Version (where) | When to bump | +|---|---|---| +| **Native (C++) collector** | `HSM_COLLECTOR_VERSION_{MAJOR,MINOR,PATCH}` — `src/native/collector/include/hsm_collector/hsm_collector.h` (mirror in `CMakeLists.txt project VERSION`) | **MAJOR** breaking ABI · **MINOR** new exported `hsm_*` function / appended struct field · **PATCH** backward-compatible behavior/logic change, no ABI change (e.g. a logging fix). → `src/native/collector/AGENTS.md` | +| **Managed (C#) collector** | `src/collector/HSMDataCollector/HSMDataCollector.csproj ` | At a DataCollector NuGet release. | +| **HSM site / server** | `src/server/HSMServer/HSMServer.csproj ` | At a server release. | +| **Agent** | `src/agent/CMakeLists.txt` → `project(HsmAgent VERSION …)` (`HSM_AGENT_VERSION`) | On **any change to the shipped agent binary** — including a native-collector change compiled into it — else self-update can't deliver it (it ships a build only when its version is *strictly greater* than the running agent's). → `src/agent/AGENTS.md` | + +## Key points + +- The **C++ collector** and the **C# collector** are two separate products. Each reports **its own** + version as the `.module/Collector version` sensor, and they may differ (C++ `0.x`, C# `3.4.x`). There + is no shared "product version" tying them together. Conformance compares the two collectors' wire + byte-for-byte but does **not** compare the version *value*, so the divergence is safe. +- The **agent** embeds the native collector but is its own product: a collector change bumps the + collector version **and** (because the agent binary changed) the agent version — two independent + bumps for two products. diff --git a/src/native/collector/AGENTS.md b/src/native/collector/AGENTS.md index 6e50e20cf..4edb47ab3 100644 --- a/src/native/collector/AGENTS.md +++ b/src/native/collector/AGENTS.md @@ -5,34 +5,27 @@ supplement the root [`AGENTS.md`](../../../AGENTS.md); where a rule here refines specific rule wins. Sibling: [`../../agent/AGENTS.md`](../../agent/AGENTS.md) (the agent that embeds this collector). -## Versioning — two numbers, do not confuse them - -Both live in [`include/hsm_collector/hsm_collector.h`](include/hsm_collector/hsm_collector.h) and are -**distinct from any host application's version** (e.g. the agent's `HsmAgent VERSION`). - -### 1. C ABI version `HSM_COLLECTOR_VERSION_*` — bump it when the C ABI grows - -- **Rule:** whenever a PR **adds or changes an exported `hsm_*` C ABI function, or appends a struct - field**, bump this version **in the same PR** — `MINOR` for additive, backward-compatible growth; - `MAJOR` for any breaking change (reorder/remove a field, change a function's semantics). Policy is - stated in the header and `docs/native-collector-c-abi.md`. -- **Keep `CMakeLists.txt` `project(HsmCollectorNative VERSION x.y.z)` in sync** with the header macros — - it feeds the `find_package(hsm_collector x.y)` compatibility check, so a drift silently lets an - incompatible consumer link. -- This is the C++/native code's own version. **If you touch the native/C-ABI code in a way that changes - what a consumer can call or observe, this number moves.** - -### 2. Product version `HSM_COLLECTOR_PRODUCT_VERSION` — pinned to the managed collector - -- This is the `.module/Collector version` sensor value — the shared **HSMDataCollector product** number. -- **Keep it byte-identical to the managed collector** (`src/collector/HSMDataCollector/HSMDataCollector.csproj` - ``) so the native port and the C# collector report the same product version. **Do NOT bump it - native-only** — that diverges two collectors meant to report one product version. -- It moves only at a **DataCollector product release**, in lockstep on BOTH sides. A native-only parity - change (native catching up to existing managed behavior) does not move it. - -**Precedent (#1221):** the built-in file logger added the C ABI function `hsm_collector_enable_file_logging` -but did **not** bump `HSM_COLLECTOR_VERSION` — an ABI-hygiene miss (a new function owes a `MINOR` bump). -It correctly left `HSM_COLLECTOR_PRODUCT_VERSION` at `3.4.12` (native parity with the managed collector, -which had no release). The fix bumped the ABI to `0.6.0` and resynced `CMakeLists.txt` (which had also -drifted to `0.4.0`). +## Versioning — the native collector's own version + +The native collector has **one** version: `HSM_COLLECTOR_VERSION_{MAJOR,MINOR,PATCH}` in +[`include/hsm_collector/hsm_collector.h`](include/hsm_collector/hsm_collector.h) (keep `CMakeLists.txt` +`project(HsmCollectorNative VERSION x.y.z)` in sync — it feeds the `find_package(hsm_collector x.y)` +compatibility check, so a drift silently lets an incompatible consumer link). It is **INDEPENDENT** of +the managed C# collector, the host application (e.g. the agent's `HsmAgent VERSION`), and the server — +each is a distinct product with its own version. It is also the value the native collector reports as +the `.module/Collector version` sensor (`HSM_COLLECTOR_VERSION_STRING`, the `MAJOR.MINOR.PATCH` form). + +**Bump it in the same PR as the change, per semver:** +- **MAJOR** — a breaking ABI change (reorder/remove a struct field, change a function's semantics). +- **MINOR** — additive, backward-compatible ABI growth (a new exported `hsm_*` function, an appended + struct field). +- **PATCH** — a backward-compatible behavior/logic change that does **not** touch the ABI (e.g. a + logging change). + +Do **not** pin it to the managed C# collector (`HSMDataCollector.csproj `) — they are two +separate products and are allowed to diverge. Conformance compares the two collectors' wire +byte-for-byte but does **not** compare the `.module/Collector version` *value*, so a diverging version +is safe. + +Full map of HSM's versions: +[`aicontext/features/core/versioning/feature.md`](../../../aicontext/features/core/versioning/feature.md). diff --git a/src/native/collector/CMakeLists.txt b/src/native/collector/CMakeLists.txt index a810273a4..d9362a9fb 100644 --- a/src/native/collector/CMakeLists.txt +++ b/src/native/collector/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.21) # VERSION tracks the C ABI semver (HSM_COLLECTOR_VERSION_* in include/hsm_collector/hsm_collector.h); # keep the two in sync. It feeds the find_package(hsm_collector x.y) version check (#1100). -project(HsmCollectorNative VERSION 0.6.0 LANGUAGES CXX) +project(HsmCollectorNative VERSION 0.6.1 LANGUAGES CXX) # --------------------------------------------------------------------------- # Target topology (epic #1093 / issue #1095 §1 — "core lib / C ABI lib / C++ diff --git a/src/native/collector/include/hsm_collector/hsm_collector.h b/src/native/collector/include/hsm_collector/hsm_collector.h index 7b643075b..18ff4bf91 100644 --- a/src/native/collector/include/hsm_collector/hsm_collector.h +++ b/src/native/collector/include/hsm_collector/hsm_collector.h @@ -9,22 +9,24 @@ extern "C" { #endif -/* ABI version. Bumped per the policy in docs/native-collector-c-abi.md: MINOR - for additive, backward-compatible growth (new functions, struct fields - appended); MAJOR for any breaking change (field reorder/removal, semantic - change). hsm_collector_version() returns the packed value at runtime. */ +/* The native collector's OWN version (semver) — INDEPENDENT of the managed C# collector, the host + application (e.g. the agent), and the server; each is a distinct product with its own version. + Bump per src/native/collector/AGENTS.md: MAJOR for a breaking ABI change; MINOR for additive ABI + growth (a new exported hsm_* function / appended struct field); PATCH for a backward-compatible + behavior/logic change that does not touch the ABI (e.g. a logging change). hsm_collector_version() + returns the packed value at runtime; HSM_COLLECTOR_VERSION_STRING is the "MAJOR.MINOR.PATCH" form + reported as the ".module/Collector version" sensor. */ #define HSM_COLLECTOR_VERSION_MAJOR 0 #define HSM_COLLECTOR_VERSION_MINOR 6 -#define HSM_COLLECTOR_VERSION_PATCH 0 +#define HSM_COLLECTOR_VERSION_PATCH 1 #define HSM_COLLECTOR_VERSION \ ((HSM_COLLECTOR_VERSION_MAJOR * 10000) + (HSM_COLLECTOR_VERSION_MINOR * 100) + HSM_COLLECTOR_VERSION_PATCH) -/* Collector PRODUCT version — the value reported as ".module/Collector version". This is the - HSMDataCollector product line and is DISTINCT from the C ABI version above (and from any host - application's own version). Keep it in sync with the managed collector's version - (src/collector/HSMDataCollector/HSMDataCollector.csproj ) so the native port and the - C# collector report the same product version. */ -#define HSM_COLLECTOR_PRODUCT_VERSION "3.4.12" +#define HSM_COLLECTOR_VERSION_STRINGIFY_(x) #x +#define HSM_COLLECTOR_VERSION_STRINGIFY(x) HSM_COLLECTOR_VERSION_STRINGIFY_(x) +#define HSM_COLLECTOR_VERSION_STRING \ + HSM_COLLECTOR_VERSION_STRINGIFY(HSM_COLLECTOR_VERSION_MAJOR) \ + "." HSM_COLLECTOR_VERSION_STRINGIFY(HSM_COLLECTOR_VERSION_MINOR) "." HSM_COLLECTOR_VERSION_STRINGIFY(HSM_COLLECTOR_VERSION_PATCH) typedef struct hsm_collector_t hsm_collector_t; typedef struct hsm_sensor_t hsm_sensor_t; diff --git a/src/native/collector/src/hsm_collector.cpp b/src/native/collector/src/hsm_collector.cpp index c568744bf..7baeac383 100644 --- a/src/native/collector/src/hsm_collector.cpp +++ b/src/native/collector/src/hsm_collector.cpp @@ -3314,9 +3314,9 @@ namespace } // Optional host override for the reported ".module/Collector version". Empty (default) -> - // HSM_COLLECTOR_PRODUCT_VERSION (the collector product line). A host must NOT set this to its - // own application version: collector and host (e.g. the agent) are distinct products with - // distinct version lines. Reserved for embedders that genuinely re-brand the collector build. + // HSM_COLLECTOR_VERSION_STRING (the native collector's own version). A host must NOT set this + // to its own application version: collector and host (e.g. the agent) are distinct products + // with distinct version lines. Reserved for embedders that genuinely re-brand the collector. void SetCollectorVersionOverride(std::string version) { collector_version_override_ = std::move(version); } const std::string& CollectorVersionOverride() const { return collector_version_override_; } @@ -7042,12 +7042,12 @@ hsm_result_t hsm_collector_add_collector_monitoring_sensors(hsm_collector_t* col std::shared_ptr collector_version; if (collector->impl->AddDefaultSensor(HSM_DEFAULT_COLLECTOR_VERSION, ¶ms, collector_version) == HSM_RESULT_OK) { - // Report the collector PRODUCT version (HSMDataCollector line), NOT the C ABI version - // and NOT the host application's version — collector and host (e.g. the agent) are - // distinct products. An explicit host override still wins if set. + // Report the native collector's OWN version (HSM_COLLECTOR_VERSION_STRING), independent of + // the managed C# collector, the host application (e.g. the agent), and the server — each is + // a distinct product with its own version. An explicit host override still wins if set. const std::string& override_ver = collector->impl->CollectorVersionOverride(); const std::string version = override_ver.empty() - ? std::string(HSM_COLLECTOR_PRODUCT_VERSION) + ? std::string(HSM_COLLECTOR_VERSION_STRING) : override_ver; EmitVersionStartValue(collector->impl.get(), collector_version, version.c_str()); } diff --git a/src/native/collector/tests/hsm_collector_tests.cpp b/src/native/collector/tests/hsm_collector_tests.cpp index a81b9a7ca..5c395180c 100644 --- a/src/native/collector/tests/hsm_collector_tests.cpp +++ b/src/native/collector/tests/hsm_collector_tests.cpp @@ -4093,9 +4093,9 @@ namespace saw_collector = true; Contains(payload, "\"Type\":8"); Contains(payload, "Start:"); - // Collector PRODUCT version (HSM_COLLECTOR_PRODUCT_VERSION) — NOT the C ABI version - // and NOT any host/agent version. Collector is a distinct product (#1189 follow-up). - Contains(payload, HSM_COLLECTOR_PRODUCT_VERSION); + // The native collector's own version (HSM_COLLECTOR_VERSION_STRING) — NOT the managed + // collector's, NOT any host/agent version. Collector is a distinct product. + Contains(payload, HSM_COLLECTOR_VERSION_STRING); } }