Skip to content

fix(telemetry): the CLI never looks where Windows installs spool (backend#2377) - #555

Merged
LukasWodka merged 1 commit into
developfrom
fix/2377-windows-installer-spool-drain
Aug 23, 2026
Merged

fix(telemetry): the CLI never looks where Windows installs spool (backend#2377)#555
LukasWodka merged 1 commit into
developfrom
fix/2377-windows-installer-spool-drain

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes tracebloc/backend#2377. Part of the backend#1872 telemetry epic.

installerSpoolFiles (internal/cli/telemetry_installer_spool.go) looked for the installer's pre-log fallback spool in $TMPDIR, $HOME and /tmp. The PowerShell installer writes it to $USERPROFILE, else $HOME, else [IO.Path]::GetTempPath() (i.e. TMP/TEMP) — client/scripts/lib/telemetry.ps1, Get-TelemetryFallbackSpool. Windows sets neither TMPDIR nor, usually, HOME, so the search reduced to /tmp, which does not exist there.

Result: Windows pre-log install failures were spooled and never delivered. That is precisely the class the fallback exists for — validate_config and early_data_dir_guard run before there is a log or a data dir, so the fallback file is their only record. The data-dir spool was unaffected: this function already resolves that one through os.UserHomeDir(), which is USERPROFILE on Windows. The glob was fine too — tracebloc-telemetry-* already matches the twin's .jsonl suffix.

Type

Bug fix.

Changes

  • installerFallbackDirVars — the candidate variables, named once and documented against both producers' fallback chains (telemetry.sh _telemetry_fallback_dir and telemetry.ps1 Get-TelemetryFallbackSpool), with the residual stated in the code: those producers live in tracebloc/client, so nothing in this repo's CI can prove the list still agrees with them. Review rule until the two repos share a fixture.
  • The loop reads that list instead of three inline literals.
  • filepath.Clean replaces strings.TrimRight(dir, "/") for dedup, so a trailing separator collapses on Windows too. Two spellings of one directory would forward the same install outcome twice in one batch.

Test plan

Three new tests in internal/cli/telemetry_installer_spool_test.go:

  1. TestInstallerSpoolFilesFindsTheFallbackOnEveryHomeVariable — a subtest per variable, each setting only that variable. The five names are written down independently of installerFallbackDirVars, deliberately: a test that feeds the production list back into itself is self-consistent and would plant a typo rather than catch one.
  2. TestInstallerFallbackDirVarsAreAllSearched — totality. Catches the opposite failure: a name added to the vocabulary and never wired into the loop.
  3. TestInstallerSpoolFilesDedupesATrailingSeparator — guards the filepath.Clean.

Mutation-proved, with the anchor asserted applied each time (the diff was printed per mutation, so an inert mutation could not pass for coverage):

mutation reddened
drop "USERPROFILE" from the list …OnEveryHomeVariable/USERPROFILE
revert the loop to the pre-fix {"TMPDIR","HOME"} /USERPROFILE, /TEMP, /TMP, totality, dedupe
iterate installerFallbackDirVars[:len-1] /TMP, totality
remove the seen[dir] check dedupe

Restored and green afterwards.

Ran locally (go1.26.6, darwin/amd64): gofmt -l clean, go vet ./... clean, go build ./..., go test ./... -count=1 → 18 packages ok, 0 FAIL.

Could not run locally: golangci-lint (not installed on this machine — CI's golangci.yml covers it), and the Windows path semantics themselves. filepath.Clean on darwin does not treat \ as a separator, so the Windows half of the dedup change is exercised by construction rather than by execution; the build.yml cross-platform matrix compiles it, and the behavioural fix (searching USERPROFILE/TEMP/TMP at all) is fully covered on any platform.

Checklist

  • Targets develop
  • Linter and the tests covering the change run, output above
  • Full diff read
  • No secrets, tokens or customer data
  • No CLAUDE.md / BUGBOT.md / runbook statement is made false by this change

🤖 Generated with Claude Code


Note

Low Risk
Narrow path-discovery fix for installer telemetry drain, with tests. No auth, ingest, or filtering-logic changes.

Overview
The CLI now finds the installer's pre-log fallback spool on Windows. installerSpoolFiles previously only searched $TMPDIR, $HOME, and /tmp, so Windows writes under $USERPROFILE / $TEMP / $TMP were never drained.

Candidate dirs now come from installerFallbackDirVars (TMPDIR, HOME, USERPROFILE, TEMP, TMP) plus bash's literal /tmp. Dedup uses filepath.Clean so a trailing separator does not send the same install outcome twice.

Tests pin each env var independently, assert every declared name is actually searched, and cover trailing-separator dedup.

Reviewed by Cursor Bugbot for commit dd34cba. Bugbot is set up for automated code reviews on this repo. Configure here.

…kend#2377)

`installerSpoolFiles` searched $TMPDIR, $HOME and /tmp for the installer's
pre-log fallback spool. Windows sets neither of the first two — USERPROFILE is
its home variable and [IO.Path]::GetTempPath() resolves TMP/TEMP — so the search
reduced to /tmp, a path that does not exist there.

`client/scripts/lib/telemetry.ps1` `Get-TelemetryFallbackSpool` writes to
$USERPROFILE, else $HOME, else GetTempPath(). Every Windows pre-log install
failure was therefore written and never collected: exactly the class the
fallback exists for, since validate_config and early_data_dir_guard run before
there is a log or a data dir.

The candidate list is now named and documented against both producers, and the
dedup uses filepath.Clean so a trailing separator collapses on either platform
rather than sending one install outcome twice.

Residual, stated rather than hidden: the producers live in tracebloc/client, so
nothing in this repo's CI can prove the list still agrees with them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka LukasWodka self-assigned this Aug 23, 2026

@saqlainsyed007 saqlainsyed007 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified against the code and the producers' chains — clean fix.

The spool search was TMPDIR → HOME → /tmp, but the PowerShell installer writes to USERPROFILE → HOME → TMP/TEMP, and Windows sets neither TMPDIR nor usually HOME — so it reduced to /tmp, which doesn't exist there, and every Windows pre-log install failure was spooled and never collected (exactly the class the fallback exists for: validate_config/early_data_dir_guard run before any log). Adding USERPROFILE/TEMP/TMP closes it, and filepath.Clean (not TrimRight("/")) correctly dedups a trailing separator on both platforms.

The test earns its keep: TestInstallerSpoolFilesFindsTheFallbackOnEveryHomeVariable writes the five var names independently of installerFallbackDirVars, so a typo in the production list can't be mirrored into the test and pass anyway (rule 9); one subtest per var with only that var set makes each assertion about that var, not the environment. The cross-repo residual (producers live in tracebloc/client, kept in step by review until a shared fixture) is stated, not hidden. CI green, no threads. LGTM.

@LukasWodka
LukasWodka merged commit f4f7cfb into develop Aug 23, 2026
29 checks passed
@LukasWodka
LukasWodka deleted the fix/2377-windows-installer-spool-drain branch August 23, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants