feat(agent-v2): surface downloadPercent + streamingFinished in Office doSummary

The office_install_completed doSummary paired aggregateFileSize next to
totalBytesDownloaded with no context, making the (expected) gap look like a
bug: the completed event fires at core-binary completion while background
streaming of the remaining declared content is still in flight, so the peak
DO sample shows downloaded < declared. aggregateFileSize is the sum of the
DO jobs' declared target sizes at the peak instant, not a stable payload total.

Mirror downloadPercent (from OfficeDoSample.DownloadPercent) and
streamingFinished into the summary so the gap is self-explanatory. XML-doc
now states why aggregate exceeds downloaded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Oliver Kieselbach
2026-06-15 15:59:03 +02:00
parent b956de1377
commit 8e35eb1b57
2 changed files with 14 additions and 2 deletions
@@ -292,6 +292,8 @@ namespace AutopilotMonitor.Agent.V2.Core.Tests.Monitoring.Office
Assert.Equal(0L, summary["bytesFromPeers"]);
Assert.Equal(80, summary["percentFromCacheServer"]);
Assert.Equal(20, summary["percentFromCdn"]);
Assert.Equal(83, summary["downloadPercent"]); // 1000 of 1200 declared
Assert.Equal(true, summary["streamingFinished"]);
}
[Fact]
@@ -544,6 +546,8 @@ namespace AutopilotMonitor.Agent.V2.Core.Tests.Monitoring.Office
Assert.Equal(1000L, summary["totalBytesDownloaded"]);
Assert.Equal(800L, summary["bytesFromCacheServer"]);
Assert.Equal(200L, summary["bytesFromCdn"]);
Assert.Equal(83, summary["downloadPercent"]);
Assert.Equal(true, summary["streamingFinished"]);
Assert.Equal(OfficeInstallStateData.StateCompleted, rig.Persistence!.Load()!.State);
}
@@ -411,7 +411,7 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Telemetry.Office
data["coreBinariesPresent"] = coreBinariesPresent;
// One-time Delivery-Optimization summary (how Office was delivered) — far more useful than
// a streaming download-% (which is noise under Connected-Cache + multi-job churn).
if (_peakDo != null) data["doSummary"] = BuildDoSummary(_peakDo);
if (_peakDo != null) data["doSummary"] = BuildDoSummary(_peakDo, snap.StreamingFinished);
}
var message = BuildMessage(eventType, snap);
@@ -467,8 +467,14 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Telemetry.Office
/// highest-bytes sample seen. Splits the bytes into Connected-Cache-Server / peer / pure-CDN: on
/// MCC-enabled networks <c>BytesFromHttp</c> includes the cache-server bytes, so pure CDN is
/// <c>BytesFromHttp - BytesFromCacheServer</c> (see project DO-telemetry notes).
///
/// <para><c>aggregateFileSize</c> is the sum of the DO jobs' declared target sizes at the peak
/// instant — NOT a stable "total Office payload". It commonly exceeds <c>totalBytesDownloaded</c>
/// because the completed event fires at core-binary completion while background streaming of the
/// remaining declared content is still in flight (<c>streamingFinished == false</c>). The mirrored
/// <c>downloadPercent</c> + <c>streamingFinished</c> make that gap self-explanatory.</para>
/// </summary>
private static Dictionary<string, object> BuildDoSummary(OfficeDoSample d)
private static Dictionary<string, object> BuildDoSummary(OfficeDoSample d, bool streamingFinished)
{
long total = d.TotalBytesDownloaded;
long cacheServer = d.BytesFromCacheServer;
@@ -480,6 +486,8 @@ namespace AutopilotMonitor.Agent.V2.Core.Monitoring.Telemetry.Office
{
{ "totalBytesDownloaded", total },
{ "aggregateFileSize", d.FileSize },
{ "downloadPercent", (object?)d.DownloadPercent ?? 0 },
{ "streamingFinished", streamingFinished },
{ "jobCount", d.JobCount },
{ "bytesFromCacheServer", cacheServer },
{ "bytesFromPeers", peers },