Skip to content

Session shards are rewritten on every export because exportedAt uses Date.now() #3

Open

Description

@logser13

Summary

opencode-github-sync 3.0.1 rewrites every exported session shard on each push even when the OpenCode session itself has not changed.

The shard currently sets:

exportedAt: Date.now(),

Because that value changes on every export, the JSON payload changes, the .json.gz bytes change, and Git sees the shard as modified.

With autoPushOnIdle enabled this can generate repeated commits touching many or all session shards even when no session data changed.

Environment

  • opencode-github-sync: 3.0.1
  • OpenCode Desktop / CLI: 1.18.30
  • Node.js: 24.x
  • Windows 11

Reproduction

  1. Enable session sync.
  2. Ensure there is at least one eligible session.
  3. Run opencode-sync push.
  4. Make no changes to the session.
  5. Run opencode-sync push --dry-run or another normal push.

Observed: the session shard is reported as modified again.

In a test with 11 eligible sessions, an unchanged export could show all 11 .json.gz shards as modified purely because export metadata was regenerated.

Expected result

If the underlying session and related rows did not change, exporting the same session again should produce identical shard bytes and Git should stay clean.

Tested fix

Using the session's own stable update timestamp instead of wall-clock export time makes repeated exports deterministic:

exportedAt: Number(sessionRow.time_updated ?? 0),

After that change, running opencode-sync push --dry-run twice with no session changes reports Already up to date on the second run.

Suggested regression test

  1. Export a session to a shard.
  2. Export the same unchanged session again.
  3. Assert the shard bytes are identical.
  4. Assert the second sync has no Git diff.

Related: #2 is a separate session-import data-loss issue.

Activity

  1. aquelejota commented on Sep 20, 2026

    @aquelejota

    Confirming this on two Linux machines with ~912 shards. Every push and startup pull carried all 912 files. After deriving exportedAt from the session's own time_updated, a repeat export is byte-identical (914 shards exported twice: 914 identical, 0 different) and pushes carry only the sessions actually in use (0–2 files, ~13 s instead of ~65 s).

    One extra finding while verifying this: the regression test never ran under vitest — await import("node:sqlite") throws ("Failed to load url sqlite") in that runner, sqliteAvailable() reports false, and every session test returns early via if (!available) return, so it passed silently. A createRequire(import.meta.url)("node:sqlite") fallback makes the driver detectable and the tests actually execute (suite went from ~15 ms to ~95 ms).

    I sent both changes as a PR: #5

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

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