Skip to content

Wire startPushDaemon() in API boot so commits actually propagate to the data remote #37

Description

@themightychris

The gap

The API boot path never calls repo.startPushDaemon(). The deploy plan (PR #35) shipped:

  • The deploy key mounting in Helm
  • GIT_SSH_COMMAND env wiring in the entrypoint
  • Documentation in docs/operations/secrets.md and deploy.md

…but no actual startPushDaemon() call in apps/api/src/store/boot.ts (or anywhere else). So commits made via store.transact land in the local working tree at CFP_DATA_REPO_PATH and are never pushed to CFP_DATA_REMOTE.

This fell between storage-foundation's closeout (which deferred "deploy key wiring" to deploy) and deploy's scope (which focused on container/Helm/CI artifacts).

What to wire

In apps/api/src/store/boot.ts (or a small plugin):

if (env.CFP_DATA_REMOTE) {
  const daemon = await repo.startPushDaemon({
    remote: 'origin',
    branch: env.CFP_DATA_BRANCH ?? 'main',
    backoff: 'exponential',
  });
  // Wire events
  daemon.on('push', ({ commit, durationMs }) => log.info({ commit, durationMs }, 'pushed'));
  daemon.on('retry', ({ attempt, nextDelayMs }) => log.info({ attempt, nextDelayMs }, 'push retry'));
  daemon.on('error', ({ err, attempt, reason }) => {
    if (reason === 'non-fast-forward') {
      log.error({ err: String(err), attempt }, 'push rejected non-fast-forward — manual reconciliation needed');
    } else {
      log.warn({ err: String(err), attempt }, 'push failed');
    }
  });
  // Graceful shutdown on SIGTERM/SIGINT (Fastify onClose hook)
}

NFF detection (gitsheets v1.0.5)

The error handler above already discriminates reason: 'non-fast-forward' from transient errors per PushFailureReason in gitsheets v1.0.5+. On NFF, the daemon won't retry (terminal), and the API should log loud + ideally page somebody (no automated reconciliation in v1).

Acceptance

  • Boot path starts the daemon when CFP_DATA_REMOTE is set
  • A commit produced via store.transact is observed pushed (test against a local bare remote)
  • Daemon stop on SIGTERM (Fastify shutdown hook)
  • NFF rejections are logged with the non-fast-forward reason, no retry spin
  • fastify.pushDaemon.status() exposed via a hidden admin route or just the logs

Out of scope

Activity

  1. added 2 commits that reference this issue on May 18, 2026
    5c98144
    7b79c74
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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions