Skip to content

Local notify sync is skipped without deviceToken, leaving local-only dashboard stale #67

Description

@pitimon

Summary

In @ipv9/tokentracker-cli 0.39.38, a local-only installation can serve the dashboard without a device token, but the generated notify hook does not start a local sync unless a deviceToken exists. The dashboard therefore refreshes only once at service startup and then becomes stale, even though Codex notifications continue to fire.

This report concerns local-only operation. A fix must not require or introduce cloud data transmission.

Environment

  • Linux with a systemd user service
  • Node.js 22.17.1
  • @ipv9/tokentracker-cli 0.39.38
  • Dashboard bound to 127.0.0.1
  • No TokenTracker cloud login or device token, intentionally

Reproduction

  1. Initialize TokenTracker and run the local dashboard without signing in or configuring a device token.
  2. Configure Codex notify to use the generated ~/.tokentracker/bin/notify.cjs.
  3. Use Codex until the notify hook fires.
  4. Observe that notify.signal receives a new modification time.
  5. Observe that:
    • queue.jsonl does not receive the new local usage,
    • sync.throttle is not created,
    • status reports a recent last_notify, but last_notify_spawn remains null.
  6. Restart the dashboard service. Startup sync refreshes the queue once, after which it becomes stale again.

The local HTTP server itself remains healthy and fast; the failure is in the notify-to-ingest path.

Root cause

The generated notify hook gates the entire sync spawn on a cloud credential:

const canSync = Boolean(deviceToken && deviceToken.length > 0);

if (canSync && now - last > 20_000) {
  // spawn tracker sync --auto --from-notify
}

Without a device token, the hook writes notify.signal and exits without starting local parsing.

This conflates two separate decisions:

  1. Parse local AI-tool logs and update the local queue.
  2. Authenticate and upload data to the cloud.

The sync command already supports local parsing without a device token and reports cloud upload as skipped. The default dashboard startup also successfully performs an automatic local parse without a token.

Expected behavior

  • A notify event should update the local queue even when no device token is configured.
  • Cloud upload must remain disabled unless the user explicitly opts in and supplies cloud credentials.
  • Local-only mode should remain functional offline.
  • Reloading the local dashboard should show the newly parsed local data without requiring a cloud account.

Strict privacy requirement

Any fix must preserve a true local-only mode and must not send data to the cloud.

Specifically, local refresh without a device token must not:

  • create or obtain a device token,
  • sign the user in,
  • upload queue.jsonl or project usage,
  • transmit session, usage, model, repository, or project metadata,
  • send telemetry as a prerequisite for local refresh,
  • contact a cloud endpoint merely to enable local parsing.

Please keep cloud upload as a separately gated, explicit opt-in path. An automated test should verify that the no-token notify flow performs no outbound upload or cloud API request.

Current workaround

A systemd user path unit watches:

~/.tokentracker/tracker/notify.signal

When the signal changes, a oneshot service runs the installed local runtime:

node ~/.tokentracker/tracker/app/bin/tracker.js sync --auto

With no device token configured, this refreshes the local queue while cloud upload remains skipped. The workaround was validated twice: each notify event triggered a successful sync in about one second and updated the queue.

This workaround should not be necessary in the packaged installation.

Suggested fix

Either:

  1. Always allow the throttled notify hook to start local parsing, while keeping upload conditional on an explicit device token; or
  2. Add an explicit sync --local-only / --no-upload path with a guarantee of no cloud requests, and use it from the notify hook when no token is configured.

Suggested regression coverage:

  • no token + notify event -> local queue updates;
  • no token + notify event -> zero cloud upload/API calls;
  • token configured + notify event -> existing authenticated upload behavior remains intact;
  • local-only behavior works without network access.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions