Skip to content

fix(windows): publish account usage in background - #559

Open
D-sudoasd wants to merge 1 commit into
xiufengsun:mainfrom
D-sudoasd:codex/fix-stale-usage-tracking
Open

fix(windows): publish account usage in background#559
D-sudoasd wants to merge 1 commit into
xiufengsun:mainfrom
D-sudoasd:codex/fix-stale-usage-tracking

Conversation

@D-sudoasd

@D-sudoasd D-sudoasd commented Sep 1, 2026

Copy link
Copy Markdown

Summary

Keep Windows account usage current while the dashboard is hidden by routing the five-minute native background sync through the authenticated local publication endpoint.

Scope

  • CLI (src/)
  • Dashboard (dashboard/)
  • macOS app (TokenTrackerBar/)
  • Windows app (TokenTrackerWin/)
  • Docs / CI / config

Why

On Windows v0.94.1, the raw session files, V2 parser cursor, local queue, and local usage API could all be current while the signed-in account view remained several days behind. The native host log showed the five-minute timer repeatedly exiting successfully with:

sync --auto --background

That path intentionally performs local parsing only. Account publication requires --publish-account plus an ephemeral device token, so a tray-only Windows session never advanced its cloud upload offset. Opening the dashboard could make one bounded upload attempt, but it was not a periodic publisher and a large backlog stayed stale.

This is independent of #551: that PR fixes the ingest anon-key value after publication starts; this PR fixes the missing Windows publication trigger itself.

What changed

  • Windows background refresh now uses loopback GET /api/local-auth followed by an authenticated POST /functions/tokentracker-local-sync.
  • The request asks for auto, background, allLocalSources, publishAccount, and nativeOnlyWsl as strict booleans.
  • The local API accepts nativeOnlyWsl only for a real background request and passes TOKENTRACKER_WSL_MODE=native-only to the child.
  • Manual Windows sync remains the existing direct exhaustive path, including its WSL behavior.
  • Background and manual sync share a single-flight gate; shutdown cancels the request and terminates the server process tree.
  • The local auth token is held only for the request and is never logged or persisted by the native client.
  • LocalSyncPublisher is covered by executable xUnit tests rather than source-text assertions alone.

Checklist

  • npm test passes
  • New user-facing strings go through dashboard/src/content/copy.csv (no new strings)
  • Commits follow conventional style (fix(windows): ...)
  • PR description explains why, not just what

Verification

  • node --test test/windows-background-sync-source.test.js test/windows-background-sync-args.test.js test/local-api-background.test.js test/local-api-security.test.js — 37 passed
  • npm run validate:copy — passed (existing unused-key warnings only)
  • npm run validate:locale — passed
  • npm run validate:ui-hardcode — passed
  • npm run validate:guardrails — passed
  • npm run validate:versions — passed
  • node --test test/architecture-guardrails.test.js — 4 passed
  • npm --prefix dashboard run build — passed
  • Full npm test was attempted locally on Windows/Node 25; unrelated host- and timing-dependent baseline tests fail in this environment. The changed-scope tests above are green.
  • Local .NET test/build could not run because this machine has the .NET runtime but no SDK; the Windows CI job is the authoritative compile/xUnit check.

Risk layer addendum

Risk layer triggers

  • Public exposure / share links / unauthenticated access
  • Auth / session / token handling
  • Cross-endpoint invariants or shared logic
  • External gateway / environment constraints

Rules / invariants

  • Local mutation still requires the per-process local-auth token.
  • Cloud publication remains gated by the server-side persisted cloud-sync preference.
  • Windows background scans remain native-only with respect to WSL; manual sync remains exhaustive.
  • A native client timeout must not release the single-flight slot while the server child is still running, so the local endpoint owns its configured request/child budgets and app shutdown provides cancellation.
  • No prompt, response, auth token, or response body is logged.

Boundary matrix

  • Signed in + cloud sync enabled: background scan mints/reuses a device token and publishes bounded batches.
  • Signed out or no refresh token: local background parsing continues; no account upload occurs.
  • Cloud sync disabled: the server suppresses publishAccount even though the native request asks for it.
  • Non-boolean or foreground nativeOnlyWsl: ignored; no environment override is injected.
  • Timer fires during manual/background sync: request is skipped by the shared single-flight gate.
  • App exits during publication: CTS cancellation and server process-tree termination prevent an orphaned native operation.
Codex review context
  • Delta since last Codex review: extracted and unit-tested LocalSyncPublisher; replaced a too-short client timeout with server-owned lifetime plus shutdown cancellation.
  • Intended behavior / invariants: periodic Windows account publication without changing local parsing, privacy, cloud opt-out, or manual WSL semantics.
  • Edge cases covered: exact request order/body/header, non-success auth response, missing token, cancellation, strict boolean WSL override, disabled cloud sync, no refresh token, and overlapping native sync calls.
  • Tests run: listed above.
  • Known gaps / out of scope: existing backlog drains in bounded batches across timer ticks; provider-parser risks and fix(sync): forward runtime anon key to account ingest #551's anon-key propagation are separate changes.

Most likely regression surface

Windows native sync lifecycle, loopback local-auth exchange, shutdown cancellation, and WSL background isolation.

Verification method

Focused Node contract tests, executable xUnit HTTP protocol tests in CI, Windows Release build in CI, and a privacy-preserving live data-flow reproduction.

Uncovered scope

Local .NET compilation is pending CI because no SDK is installed on the reproducing machine.

Summary by CodeRabbit

  • New Features

    • Background synchronization now uses an authenticated local connection and publishes comprehensive local-source updates.
    • Added native-only WSL handling for background synchronization.
    • Manual synchronization continues to use its existing direct execution behavior.
  • Bug Fixes

    • Improved cancellation and shutdown handling for background synchronization.
    • Prevented authentication response contents from being exposed in errors.
  • Tests

    • Added coverage for authentication, payloads, cancellation, error handling, and native-only WSL behavior.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 0119152c-e6a1-4e0a-aeb6-95e48f6b87d3

📥 Commits

Reviewing files that changed from the base of the PR and between 58db7aa and e6ab699.

📒 Files selected for processing (8)
  • TokenTrackerWin.Tests/LocalSyncPublisherTests.cs
  • TokenTrackerWin.Tests/TokenTrackerWin.Tests.csproj
  • TokenTrackerWin/LocalSyncPublisher.cs
  • TokenTrackerWin/ServerManager.cs
  • src/lib/local-api.js
  • test/local-api-background.test.js
  • test/windows-background-sync-args.test.js
  • test/windows-background-sync-source.test.js

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Changes

Background sync flow

Layer / File(s) Summary
Authenticated local publisher
TokenTrackerWin/LocalSyncPublisher.cs, TokenTrackerWin.Tests/LocalSyncPublisherTests.cs, TokenTrackerWin.Tests/TokenTrackerWin.Tests.csproj
Adds authenticated local API publishing, fixed background-sync payload handling, response validation, token protection, cancellation propagation, and focused tests.
Windows background-sync orchestration
TokenTrackerWin/ServerManager.cs, test/windows-background-sync-args.test.js, test/windows-background-sync-source.test.js
Routes background sync through LocalSyncPublisher, preserves direct manual sync, and adds lifecycle, cancellation, HTTP, endpoint, header, and payload assertions.
Native-only WSL propagation
src/lib/local-api.js, test/local-api-background.test.js
Passes TOKENTRACKER_WSL_MODE=native-only only when the required background-sync flags are strictly true, with combination coverage.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: 🔵 Low · up to e6ab6

This PR enables periodic Windows background publication of account usage through the local service. A bounded shutdown or timeout window could allow synchronization state to clear before the underlying operation fully exits, potentially delaying a retry or causing duplicate work; the change is otherwise mergeable with explicit owner awareness.

Sequence Diagram(s)

sequenceDiagram
  participant ServerManager
  participant LocalSyncPublisher
  participant LocalAPI
  participant TrackerSync
  ServerManager->>LocalSyncPublisher: RunBackgroundSyncAsync
  LocalSyncPublisher->>LocalAPI: GET /api/local-auth
  LocalAPI-->>LocalSyncPublisher: Return token
  LocalSyncPublisher->>LocalAPI: POST authenticated background payload
  LocalAPI->>TrackerSync: Spawn sync with native-only WSL environment
  TrackerSync-->>LocalAPI: Complete sync
  LocalAPI-->>LocalSyncPublisher: Return publish response
  LocalSyncPublisher-->>ServerManager: Complete background sync
Loading

Suggested reviewers: xiufengsun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 7 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: publishing account usage during Windows background synchronization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 7 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@xiufengsun xiufengsun left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The Windows loopback publisher and its tests look coherent on exact head e6ab6994b59c7fbbccb661dda1460d673fa53a80, but the account publication still cannot succeed reliably against current main.

drainQueueToCloud() currently sources the InsForge anonymous key only from TOKENTRACKER_INSFORGE_ANON_KEY. The native background request launches a child without that environment key; the configured runtime key available in the local server is not forwarded into the uploader. As a result, this PR schedules publication every five minutes but normally sends ingest without the required apikey header.

Please either incorporate a concurrency-safe runtime-key forwarding fix or rework this flow so the child receives the local server's current anonymous key. Do not copy #551 as-is: its current head can delete a newly written key during a concurrent device login. Add an end-to-end regression that starts from the native loopback request with no environment key and verifies the ingest request carries the runtime key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants