Merge remote-tracking branch 'origin/main' into maintainer-async/20260904T112618Z-core-runtime/pulse

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-09-04 12:55:04 +01:00
4 changed files with 113 additions and 36 deletions
+32 -32
View File
@@ -10167,38 +10167,6 @@
}
]
},
{
"id": "telemetry-test-binary-production-pings",
"summary": "Go test binaries reported themselves to the production telemetry receiver as live installations. pkg/server tests boot the real server through Run() with the version literal \"test-version\", which internal/updates normalizes to 0.0.0-test-version, and each test runs against its own t.TempDir(), so every run minted a fresh install ID. The startup ping waits two minutes and never fired in a short test, but the service-health failure reporter added on 2026-08-29 sends synchronously from a deferred handler as soon as Run() returns an error, so every test run that exercised a startup failure posted one ping. The receiver recorded 317 single-ping installs between 2026-08-29 and 2026-09-03, 311 from linux/amd64 hosts (dominated by the autonomous maintainer fleet running ad-hoc go test, not GitHub Actions, which ran twice in the final 24h) and 3 from a maintainer workstation. The canonical clean denominator excludes single-ping installs and was unaffected, but raw install counts and the operator-evidence Patrol blocked-cause read counted them as real installations. Resolved by refusing production-endpoint sends from a test binary in internal/telemetry, opting the server tests out of telemetry, and putting the operator-evidence read on the production-ping basis. Note the receiver cannot filter these on version_is_development: the emitter sets that flag only for git build metadata or a prerelease of exactly dev or dev.*, so 0.0.0-test-version arrives with it clear and only version_is_published_release excludes it.",
"owner": "project-owner",
"status": "triaged",
"recorded_at": "2026-09-03",
"lane_ids": [
"L14"
],
"subsystem_ids": [
"security-privacy"
],
"proposed_resolution": "lane-expansion",
"coverage_impact": 3,
"evidence": [
{
"repo": "pulse",
"path": "internal/telemetry/telemetry.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "pkg/server/server.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "pkg/server/server_test.go",
"kind": "file"
}
]
},
{
"id": "patrol-investigation-rate-metric-invalid",
"summary": "The Patrol investigation rate (pulse_intelligence_patrol_investigations_30d over pulse_intelligence_patrol_new_findings_30d), which TELEMETRY_SIGNALS.md instructs every reader to report, is not a rate and must not be trended. Four independent reasons, all verified in pkg/server/telemetry_pulse_intelligence.go: the denominator sums run.NewFindings over history.Runs, which SavePatrolRunHistory caps at MaxPatrolRunHistory (100), so it covers at most the last hundred runs rather than thirty days and silently under-reports for any install patrolling faster than that (355 of 449 Patrol-enabled installs in the 6.4 upgrade cohort on 2026-09-03); the numerator instead scans the current findings store and counts surviving finding records investigated in-window, including findings created before it, which is how the paid cohort read 128.57 percent in the week to 2026-08-25; the populations are disjoint because Finding.ShouldInvestigate returns false at monitor autonomy and effective autonomy is licence-gated, so free installs produced 4384 findings and 1 investigation (0.02 percent) in the week to 2026-09-03 while 67 paid installs produced 242; and only 29 clean installs reported any investigation at all, one of which swung the fleet total by 38. The three-week decline that prompted this (7.2 to 5.0 percent) is composition, not regression: the rate is flat in version-stable installs (3.48, 3.39, 3.78), fleet investigations rose once that single install is excluded (170, 213, 225), finding-detection code is identical between v6.3.2 and v6.4.1, and the patrol interval is unchanged at 360 minutes across 6.1 through 6.4. The reported run growth is likewise the 63c40ebe5e daily tally back-filling, not more patrolling. This also corrects the telemetry inference in patrol-findings-hygiene-attention-noise: findings are not mostly 'seen and ignored', they are raised on installs that are licence-gated out of investigating at all, which leaves that gap's independently evidenced UX work (discussions 1623 and 1699) standing on its own footing. Two defects follow: new_findings_30d saturates on the very history cap that 63c40ebe5e fixed for runs_30d in the same function, needing a per-day findings tally alongside DailyRuns; and the blessed doc tells every reader to compute the invalid ratio. The real signal the ratio was hiding is that paid Patrol installs fell from 76 to 67 while free Patrol grew from 888 to 962.",
@@ -10240,6 +10208,38 @@
"kind": "file"
}
]
},
{
"id": "telemetry-test-binary-production-pings",
"summary": "Go test binaries reported themselves to the production telemetry receiver as live installations. pkg/server tests boot the real server through Run() with the version literal \"test-version\", which internal/updates normalizes to 0.0.0-test-version, and each test runs against its own t.TempDir(), so every run minted a fresh install ID. The startup ping waits two minutes and never fired in a short test, but the service-health failure reporter added on 2026-08-29 sends synchronously from a deferred handler as soon as Run() returns an error, so every test run that exercised a startup failure posted one ping. The receiver recorded 317 single-ping installs between 2026-08-29 and 2026-09-03, 311 from linux/amd64 hosts (dominated by the autonomous maintainer fleet running ad-hoc go test, not GitHub Actions, which ran twice in the final 24h) and 3 from a maintainer workstation. The canonical clean denominator excludes single-ping installs and was unaffected, but raw install counts and the operator-evidence Patrol blocked-cause read counted them as real installations. Resolved by refusing production-endpoint sends from a test binary in internal/telemetry, opting the server tests out of telemetry, and putting the operator-evidence read on the production-ping basis. The emitter's development flag was wrong too and is now fixed: it was set only for git build metadata or a prerelease of exactly dev or dev.*, so 0.0.0-test-version and 0.0.0-dev-pro both arrived with version_is_development clear. The 0.0.0 sentinel now decides the channel, so builds reporting after 2026-09-04 carry version_is_development true. Rows already stored keep the values they were sent with and are not backfilled, so any read whose window reaches earlier must still filter on version_is_published_release.",
"owner": "project-owner",
"status": "triaged",
"recorded_at": "2026-09-03",
"lane_ids": [
"L14"
],
"subsystem_ids": [
"security-privacy"
],
"proposed_resolution": "lane-expansion",
"coverage_impact": 3,
"evidence": [
{
"repo": "pulse",
"path": "internal/telemetry/telemetry.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "pkg/server/server.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "pkg/server/server_test.go",
"kind": "file"
}
]
}
],
"candidate_lanes": [
@@ -3141,6 +3141,16 @@ strings into normalized release identity fields for browser preview payloads
and operator telemetry reporting, so unpublished `git describe` / manual / dev
builds cannot pollute published stable or RC adoption reads just because they
share a semver-looking prefix.
The development flag in that identity is defined by the `0.0.0` sentinel, not
by prerelease spelling. `normalizeVersionString` assigns `0.0.0-<sanitized>` to
every build string it cannot parse as a release version, so any version whose
major, minor, and patch are all zero must report `version_channel` `dev` and
`version_is_development` true, and must never simultaneously report as a
published release — including a sentinel that happens to spell a preview stage,
such as `0.0.0-rc.1`. Matching only the prerelease texts `dev` and `dev.*` left
`0.0.0-test-version`, `0.0.0-dev-pro`, and `0.0.0-qual-*` reporting as ordinary
prereleases with the development flag clear, so a receiver-side read that
filtered on that flag alone kept counting them as real installations.
That release-build metadata path is now explicit too: `scripts/release_ldflags.sh`
is the canonical owner for server and agent build ldflags, and release artifact
assembly must route through it instead of hand-writing overlapping `main.Version`,
+17 -1
View File
@@ -296,7 +296,10 @@ func DescribeUsageDataVersion(raw string) UsageDataVersionIdentity {
identity.Build = parsed.Build
identity.Channel = usageDataVersionChannel(parsed)
identity.IsDevelopment = identity.Channel == "dev"
identity.IsPublishedRelease = parsed.IsPublishedReleaseAssetVersion()
// A development build is never a published release. Without this the 0.0.0
// sentinel "0.0.0-rc.1" would satisfy IsPublishedReleaseAssetVersion and
// report both flags at once, which no real install can be.
identity.IsPublishedRelease = !identity.IsDevelopment && parsed.IsPublishedReleaseAssetVersion()
return identity
}
@@ -431,6 +434,17 @@ func detectChannelFromVersion(version string) string {
return "stable"
}
// developmentSentinelVersion reports whether a version carries the 0.0.0
// sentinel normalizeVersionString assigns to any build string it cannot parse
// as a release version: a branch name, an ad-hoc test or qualification label,
// or an empty VERSION file. Pulse never publishes a 0.0.0 release, so such a
// build is a development build whatever its prerelease text happens to spell,
// and the check has to precede the prerelease classification rather than fall
// through to it.
func developmentSentinelVersion(version *Version) bool {
return version != nil && version.Major == 0 && version.Minor == 0 && version.Patch == 0
}
func usageDataVersionChannel(version *Version) string {
if version == nil {
return "unknown"
@@ -438,6 +452,8 @@ func usageDataVersionChannel(version *Version) string {
switch {
case version.Build != "":
return "dev"
case developmentSentinelVersion(version):
return "dev"
case version.IsPreviewPrerelease():
return version.PreviewStage()
case version.Prerelease == "":
+54 -3
View File
@@ -324,12 +324,63 @@ func TestDescribeUsageDataVersion(t *testing.T) {
wantPublished: false,
},
{
name: "source branch falls back to prerelease dev identity",
name: "source branch is a development build",
input: "feature/new-usage-report",
wantVersion: "0.0.0-feature-new-usage-report",
wantRaw: "feature/new-usage-report",
wantChannel: "prerelease",
wantDevelopment: false,
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{
// The literal pkg/server tests passed to Run(). It reported
// version_is_development = 0 for 317 installs before the 0.0.0
// sentinel was classified as development.
name: "ad-hoc test label is a development build",
input: "test-version",
wantVersion: "0.0.0-test-version",
wantRaw: "test-version",
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{
// "dev-pro" is not "dev" and does not start with "dev.", so the
// prerelease-text rules alone never caught it.
name: "dev-pro label is a development build",
input: "dev-pro",
wantVersion: "0.0.0-dev-pro",
wantRaw: "dev-pro",
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{
name: "qualification label is a development build",
input: "qual-87699dfff-810aae8d2",
wantVersion: "0.0.0-qual-87699dfff-810aae8d2",
wantRaw: "qual-87699dfff-810aae8d2",
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{
// The sentinel outranks the preview-stage rule: a 0.0.0 build is
// never a published release asset, so it must not report as both.
name: "sentinel outranks a preview prerelease spelling",
input: "rc.1",
wantVersion: "0.0.0-rc.1",
wantRaw: "rc.1",
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{
name: "empty version is a development build",
input: "",
wantVersion: "0.0.0-dev",
wantChannel: "dev",
wantDevelopment: true,
wantPublished: false,
},
{