diff --git a/src/Agent/AutopilotMonitor.Agent.V2.Core/Monitoring/Runtime/SelfUpdater.cs b/src/Agent/AutopilotMonitor.Agent.V2.Core/Monitoring/Runtime/SelfUpdater.cs
index d9ce3c92..0b489591 100644
--- a/src/Agent/AutopilotMonitor.Agent.V2.Core/Monitoring/Runtime/SelfUpdater.cs
+++ b/src/Agent/AutopilotMonitor.Agent.V2.Core/Monitoring/Runtime/SelfUpdater.cs
@@ -13,11 +13,13 @@ using Newtonsoft.Json.Linq;
namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
{
///
- /// Fast self-update at agent startup: checks version.json in blob storage,
- /// downloads the ZIP if newer, swaps files (rename-trick for locked binaries),
+ /// Fast self-update at agent startup: checks version-v2.json in blob storage,
+ /// downloads the V2 ZIP if newer, swaps files (rename-trick for locked binaries),
/// and restarts via PowerShell Wait-Process.
///
/// Design priority: speed over update — better to run the old version than delay startup.
+ /// V2 uses its own manifest (version-v2.json) + ZIP (AutopilotMonitor-Agent-V2.zip) to
+ /// stay isolated from the legacy V1 release line.
///
static class SelfUpdater
{
@@ -82,7 +84,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
///
/// Optional: backend-provided SHA-256 hash of the latest agent ZIP.
/// Set from the last AgentConfigResponse before calling CheckAndApplyUpdateAsync.
- /// Takes priority over the hash in version.json (separate trust channel).
+ /// Takes priority over the hash in version-v2.json (separate trust channel).
///
public static string BackendExpectedSha256 { get; set; }
@@ -107,7 +109,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
///
/// When false (default), a latest version strictly lower than
/// is rejected even when is true — prevents the production
- /// version.json from silently overwriting a higher-versioned dev/pre-release agent via
+ /// version-v2.json from silently overwriting a higher-versioned dev/pre-release agent via
/// the runtime hash-mismatch path. Set to true only for controlled rollback scenarios.
///
public static async Task CheckAndApplyUpdateAsync(
@@ -134,7 +136,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
try
{
- // Step 1: Fetch version.json (1s timeout)
+ // Step 1: Fetch version-v2.json (2.5s timeout)
var versionSw = Stopwatch.StartNew();
string manifestSha256;
(latestVersion, manifestSha256) = await GetLatestVersionAsync(log);
@@ -144,7 +146,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
if (latestVersion == null)
{
if (isStartupTrigger)
- WriteSkipMarker("version_check_failed", currentVersion, null, "version.json fetch failed or timed out", log);
+ WriteSkipMarker("version_check_failed", currentVersion, null, "version-v2.json fetch failed or timed out", log);
return; // Could not determine latest version — continue with current
}
@@ -211,7 +213,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
}
try { zipSizeBytes = new FileInfo(zipPath).Length; } catch { /* best-effort */ }
- // Step 3b: Verify SHA-256 integrity (backend hash has priority over version.json hash)
+ // Step 3b: Verify SHA-256 integrity (backend hash has priority over version-v2.json hash)
string expectedSha256;
if (!string.IsNullOrEmpty(BackendExpectedSha256))
{
@@ -221,7 +223,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
else if (!string.IsNullOrEmpty(manifestSha256))
{
expectedSha256 = manifestSha256;
- log("Self-update: using version.json hash for integrity verification (blob storage)");
+ log("Self-update: using version-v2.json hash for integrity verification (blob storage)");
}
else
{
@@ -313,14 +315,14 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
}
///
- /// Fetches version.json from blob storage and returns the version string and optional SHA-256 hash.
+ /// Fetches version-v2.json from blob storage and returns the version string and optional SHA-256 hash.
/// Returns (null, null) if the check fails or times out.
///
private static async Task<(string version, string sha256)> GetLatestVersionAsync(Action log)
{
try
{
- var versionUrl = $"{Constants.AgentBlobBaseUrl}/{Constants.AgentVersionFileName}";
+ var versionUrl = $"{Constants.AgentBlobBaseUrl}/{Constants.AgentVersionFileNameV2}";
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler) { Timeout = TimeSpan.FromMilliseconds(VersionCheckTimeoutMs) })
@@ -331,13 +333,13 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
if (string.IsNullOrWhiteSpace(version))
{
- log("Self-update: version.json has no 'version' field");
+ log("Self-update: version-v2.json has no 'version' field");
return (null, null);
}
var sha256 = obj["sha256"]?.ToString();
if (!string.IsNullOrWhiteSpace(sha256))
- log($"Self-update: version.json has SHA-256 hash for integrity verification");
+ log($"Self-update: version-v2.json has SHA-256 hash for integrity verification");
return (version.Trim(), sha256?.Trim());
}
@@ -349,7 +351,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
}
catch (HttpRequestException ex) when (ex.Message.Contains("404"))
{
- log("Self-update: version.json not found (404) — skipping update");
+ log("Self-update: version-v2.json not found (404) — skipping update");
return (null, null);
}
catch (Exception ex)
@@ -447,7 +449,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
{
try
{
- var zipUrl = $"{Constants.AgentBlobBaseUrl}/{Constants.AgentZipFileName}";
+ var zipUrl = $"{Constants.AgentBlobBaseUrl}/{Constants.AgentZipFileNameV2}";
// Clean up any previous download
if (File.Exists(zipPath))
@@ -664,7 +666,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Runtime
///
/// Writes a small JSON marker so the next agent startup can emit an agent_version_check event
- /// with outcome=skipped (or check_failed if the version.json fetch itself failed). Only called
+ /// with outcome=skipped (or check_failed if the version-v2.json fetch itself failed). Only called
/// on the startup trigger path (runtime-triggered failures are logged normally because the full
/// logger is already up). Best-effort — never throws.
///
diff --git a/src/Agent/AutopilotMonitor.Agent.V2/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent.V2/buildcounter.txt
index e34885bb..bc6298e8 100644
--- a/src/Agent/AutopilotMonitor.Agent.V2/buildcounter.txt
+++ b/src/Agent/AutopilotMonitor.Agent.V2/buildcounter.txt
@@ -1 +1 @@
-107
+110
diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
index 69559761..6d0c1073 100644
--- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
+++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
@@ -1 +1 @@
-1075
+1077
diff --git a/src/Backend/AutopilotMonitor.Functions/Middleware/AuthenticationMiddleware.cs b/src/Backend/AutopilotMonitor.Functions/Middleware/AuthenticationMiddleware.cs
index c30e30a1..0a2fb914 100644
--- a/src/Backend/AutopilotMonitor.Functions/Middleware/AuthenticationMiddleware.cs
+++ b/src/Backend/AutopilotMonitor.Functions/Middleware/AuthenticationMiddleware.cs
@@ -44,6 +44,7 @@ public class AuthenticationMiddleware : IFunctionsWorkerMiddleware
"/api/stats/platform",
"/api/agent/register-session",
"/api/agent/ingest",
+ "/api/agent/telemetry",
"/api/agent/config",
"/api/agent/upload-url",
"/api/agent/error",
diff --git a/src/Shared/AutopilotMonitor.Shared/Constants.cs b/src/Shared/AutopilotMonitor.Shared/Constants.cs
index 83694baa..e1e09d77 100644
--- a/src/Shared/AutopilotMonitor.Shared/Constants.cs
+++ b/src/Shared/AutopilotMonitor.Shared/Constants.cs
@@ -82,15 +82,27 @@ namespace AutopilotMonitor.Shared
public const string AgentBlobBaseUrl = "https://autopilotmonitor.blob.core.windows.net/agent";
///
- /// Version manifest filename in blob storage (JSON: { "version": "1.0.350" })
+ /// Version manifest filename in blob storage (JSON: { "version": "1.0.350" }) — Legacy V1 agent only.
///
public const string AgentVersionFileName = "version.json";
///
- /// Agent ZIP filename in blob storage
+ /// Agent ZIP filename in blob storage — Legacy V1 agent only.
///
public const string AgentZipFileName = "AutopilotMonitor-Agent.zip";
+ ///
+ /// V2 version manifest filename — separate release line from V1 to prevent
+ /// the V2 agent from being downgrade-blocked against V1 versions.
+ /// Matches what the V2 bootstrapper downloads (Install-AutopilotMonitor-v2.ps1).
+ ///
+ public const string AgentVersionFileNameV2 = "version-v2.json";
+
+ ///
+ /// V2 agent ZIP filename — paired with .
+ ///
+ public const string AgentZipFileNameV2 = "AutopilotMonitor-Agent-V2.zip";
+
///
/// Staging directory for self-update extraction
///